Skip to content

Instantly share code, notes, and snippets.

@korolr
Forked from dmichael/redux-websocket-example.md
Created September 7, 2018 20:04
Show Gist options
  • Save korolr/6f7a36179aaefb9b97a1ad32e435e999 to your computer and use it in GitHub Desktop.
Save korolr/6f7a36179aaefb9b97a1ad32e435e999 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