Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save jrartiga/20f057f649eef92ad080f7491d3d77f0 to your computer and use it in GitHub Desktop.

Select an option

Save jrartiga/20f057f649eef92ad080f7491d3d77f0 to your computer and use it in GitHub Desktop.

Redux WebSocket Middleware: Example

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.

Middleware

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);
};

Store setup example

import { createStore, applyMiddleware } from 'redux';
import reducer from './reducer';
import websocket from './websocket';

const createStore = (initialState) => (
  createStore(reducer, initialState, applyMiddleware(websocket))
)

Action

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());

Reducer

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
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment