Skip to content

Instantly share code, notes, and snippets.

@dmichael
Last active June 29, 2023 07:38
Show Gist options
  • Star 58 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save dmichael/9dc767fca93624df58b423d01e485402 to your computer and use it in GitHub Desktop.
Save dmichael/9dc767fca93624df58b423d01e485402 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
  }
}
@shauryaverma4296
Copy link

Please light me, where to dispatch action for "WEBSOCKET:SEND" in this whole architecture ?

@shauryaverma4296
Copy link

@dmichael Please light me, where to dispatch action for "WEBSOCKET:SEND" in this whole architecture ?

@shauryaverma4296
Copy link

@dmichael Please light me, where to dispatch action for "WEBSOCKET:SEND" in this whole architecture ?

@dmichael
Copy link
Author

@shauryaverma4296 its been a long time since Ive worked with this. The full library has been release and is maintained here: https://github.com/giantmachines/redux-websocket

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment