This Gist provides some code examples of how to implement WebSocket stream handling using a Redux middleware. Please be aware that this is only provided as an example and that critical things like exception handling have not been implemented.
A more complete version has been packaged, tested, and is available on GitHub as redux-websocket. This library has also been published to npm at @giantmachines/redux-websocket
.
This module represents the foundation of the middleware and implements the ideas presented above. The exported function is used during the creation of the Redux store (see the following snippet).
const websocket;
/**
* An example middleware to handle WebSocket connections.
* NB: There is no exception handling!
*/
const middleware = store => next => action => {
switch (action.type) {
// User request to connect
case 'WEBSOCKET:CONNECT':
// Configure the object
websocket = new WebSocket(action.payload.url);
// Attach the callbacks
websocket.onopen = () => dispatch({ type: 'WEBSOCKET:OPEN' });
websocket.onclose = (event) => dispatch({ type: 'WEBSOCKET:CLOSE', payload: event });
websocket.onmessage = (event) => dispatch({ type: 'WEBSOCKET:MESSAGE', payload: event });
break;
// User request to send a message
case 'WEBSOCKET:SEND':
websocket.send(JSON.stringify(action.payload));
break;
// User request to disconnect
case 'WEBSOCKET:DISCONNECT':
websocket.close();
break;
default: // We don't really need the default but ...
break;
};
return next(action);
};
import { createStore, applyMiddleware } from 'redux';
import reducer from './reducer';
import websocket from './websocket';
const createStore = (initialState) => (
createStore(reducer, initialState, applyMiddleware(websocket))
)
The following snippet of code shows an action creator that when dispatched, will open a WebSocket connection. Notice that the format of the action follows the Flux Standard Action recommendation.
/**
* An example action creator to request a WebSocket connection.
*/
const action = (url = 'wss://localhost:6666') => {
type: 'WEBSOCKET:CONNECT',
payload: { url }
}
// Use it something like this wherever you wire up your actions
// (react-redux, other middlewares, etc)
store.dispatch(action());
Finally, this snippet shows how a reducer might handle an action that is dispatched from the WebSocket middleware.
/**
* An example reducer to handle WebSocket messages.
* NB: There is no error handling!
*/
const reducer = (state = {}, action) => {
switch (action.type) {
case 'WEBSOCKET:MESSAGE':
// Assuming that your data is a DOMString in JSON format
const data = JSON.parse(action.payload.data);
return { ...state, ...data}
default:
return state
}
}
This example was very nice to find; thank you for it.
In case you're interested, I don't see where
dispatch
was exposed from the store in order to call it in themiddleware
function.or