redux-websocket
⚠️⚠️⚠️ NOTE: This project will be entering maintenance mode for the forseeable future so that we can focus on other internal initiatives. We thank you for using our library and hope that it has been useful to you! Please feel free to fork a version of redux-websocket if you would like to expand on it or run into any significant issues or bugs that require a major change. The last stable version will be v1.5.1
.
redux-websocket
is a Redux middleware for managing data over a WebSocket connection.
This middleware uses actions to interact with a WebSocket connection including connecting, disconnecting, sending messages, and receiving messages. All actions follow the Flux Standard Action model.
Features
- Written in TypeScript.
- Interact with a WebSocket connection by dispatching actions.
- Connect to multiple WebSocket streams by creating multiple middleware instances.
- Handle WebSocket events with Redux middleware, integrate with Saga, and use reducers to persist state.
- Automatically handle reconnection.
Installation
$ npm i @giantmachines/redux-websocket
Configuration
Configure your Redux store to use the middleware with applyMiddleware
. This package exports a function to create an instance of a middleware, which allows for configuration options, detailed below. Furthermore, you can create multiple instances of this middleware in order to connect to multiple WebSocket streams.
import { applyMiddleware, compose, createStore } from 'redux';
import reduxWebsocket from '@giantmachines/redux-websocket';
import reducer from './store/reducer';
const reduxWebsocketMiddleware = reduxWebsocket();
const store = createStore(reducer, applyMiddleware(reduxWebsocketMiddleware));
You may also pass options to the reduxWebsocket
function.
Available options
interface Options {
prefix?: string;
reconnectInterval?: number;
reconnectOnClose?: boolean;
reconnectOnError?: boolean;
onOpen?: (socket: WebSocket) => void;
serializer?: (payload: any) => string | ArrayBuffer | ArrayBufferView | Blob;
deserializer?: (message: any) => any;
dateSerializer?: (date: Date) => string | number;
}
Usage
redux-websocket
will dispatch some actions automatically, based on what the internal WebSocket connection. Some actions will need to be dispatched by you.
By default redux-websocket
actions get dispatched with a timestamp as a Date
object. This has caused some users to experience non serializable action warnings when using redux toolkit. If you encounter this problem you can either add a dateSerializer
function to redux-websocket
options or setup redux toolkit to ignore the actions.
User dispatched actions
These actions must be dispatched by you, however we do export action creator functions that can be used.
⚠️ If you have created your middleware with a prefix
option, make sure you pass that prefix as the second argument to all of these action creators.
➡️ REDUX_WEBSOCKET::WEBSOCKET_CONNECT
Example:
import { connect } from '@giantmachines/redux-websocket';
store.dispatch(connect('wss://my-server.com'));
store.dispatch(connect('wss://my-server.com', ['v1.stream.example.com']));
store.dispatch(
connect('wss://my-server.com', ['v1.stream.example.com'], 'MY_PREFIX')
);
store.dispatch(connect('wss://my-server.com', 'MY_PREFIX'));
Arguments:
url
(string
): WebSocket URL to connect to.- [
protocols
] (string[]
): Optional sub-protocols. - [
prefix
] (string
): Optional action type prefix.
➡️ REDUX_WEBSOCKET::WEBSOCKET_DISCONNECT
Example:
import { disconnect } from '@giantmachines/redux-websocket';
store.dispatch(disconnect());
Arguments:
- [
prefix
] (string
): Optional action type prefix.
➡️ REDUX_WEBSOCKET::WEBSOCKET_SEND
Example:
import { send } from '@giantmachines/redux-websocket';
store.dispatch(send({ my: 'message' }));
Arguments:
message
(any
): Any JSON serializable value. This will be stringified and sent over the connection. If the value passed is not serializable, JSON.stringify
will throw an error.- [
prefix
] (string
): Optional action type prefix.
Library dispatched actions
These actions are dispatched automatically by the middlware.
⬅️ REDUX_WEBSOCKET::OPEN
Dispatched when the WebSocket connection successfully opens, including after automatic reconnect.
Structure
{
type: 'REDUX_WEBSOCKET::OPEN',
meta: {
timestamp: Date,
},
}
⬅️ REDUX_WEBSOCKET::CLOSED
Dispatched when the WebSocket connection successfully closes, both when you ask the middleware to close the connection, and when the connection drops.
Structure
{
type: 'REDUX_WEBSOCKET::CLOSED',
meta: {
timestamp: Date,
},
}
⬅️ REDUX_WEBSOCKET::MESSAGE
Dispatched when the WebSocket connection receives a message. The payload includes a message
key, which is JSON, and an origin
key, which is the address of the connection from which the message was recieved.
Structure
{
type: 'REDUX_WEBSOCKET::MESSAGE',
meta: {
timestamp: Date,
},
payload: {
message: string,
origin: string,
},
}
⬅️ REDUX_WEBSOCKET::BROKEN
Dispatched when the WebSocket connection is dropped. This action will always be dispatched after the CLOSED
action.
Structure
{
type: 'REDUX_WEBSOCKET::BROKEN',
meta: {
timestamp: Date,
},
}
⬅️ REDUX_WEBSOCKET::BEGIN_RECONNECT
Dispatched when the middleware is starting the reconnection process.
Structure
{
type: 'REDUX_WEBSOCKET::BEGIN_RECONNECT',
meta: {
timestamp: Date,
},
}
⬅️ REDUX_WEBSOCKET::RECONNECT_ATTEMPT
Dispatched every time the middleware attempts a reconnection. Includes a count
as part of the payload.
Structure
{
type: 'REDUX_WEBSOCKET::RECONNECT_ATTEMPT',
meta: {
timestamp: Date,
},
payload: {
count: number,
},
}
⬅️ REDUX_WEBSOCKET::RECONNECTED
Dispatched when the middleware reconnects. This action is dispached right before an OPEN
action.
Structure
{
type: 'REDUX_WEBSOCKET::RECONNECTED',
meta: {
timestamp: Date,
},
}
⬅️ REDUX_WEBSOCKET::ERROR
General purpose error action.
Structure
{
type: 'REDUX_WEBSOCKET::ERROR',
error: true,
meta: {
timestamp: Date,
message: string,
name: string,
originalAction: Action | null,
},
payload: Error,
}