WebSocket
The WebSocket task handler allows to create a WebSocket connection, send messages, and listen on incoming ones.
Configuration¶
Parameter | Type | Description |
---|---|---|
socketFactory | (connectionUrl: string) => WebSocketLike |
Optional. Function that will be used to create the socket, useful to provide compatibility layers (e.g. Primus, SockJS) or enhanced versions of WebSocket. Defaults to creating a standard WebSocket |
encode | (data: any) => any |
Optional. Function to encode data from a send task into a wire format. Defaults to JSON.stringify |
decode | (data: any) => any |
Optional. Function to decode data from the wire into a format useful for application code. Defaults to JSON.parse |
Example:
import ReconnectingWebSocket from 'reconnecting-websocket'
import { configureAgents, createSocketAgent } from 'redux-agent'
store.subscribe(configureAgents([
createSocketAgent({
// Provide enhanced/wrapped implementation
socketFactory: (url) => new ReconnectingWebSocket(url)
// skip JSON encoding
encode: (data) => data,
// skip JSON decoding
decode: (data) => data
})
], store))
Task: Listen¶
This task describes a connection intent, the actions that will to notify about connection status, and the action that will notify of incoming messages.
{
type: 'socket',
op: 'listen',
url: string, // socket endpoint URL, e.g. wss://example.com/
actions: {
connect: string, // action type to dispatch when the socket connects
disconnect: string, // action type to dispatch when the socket disconnects
error: string, // action type to dispatch when an error occurs
message: string, // action type to dispatch when a message is received
}
}
Tip
To disconnect a socket, simply remove the task (see how in the example).
Actions¶
Event Type | Meta | Payload |
---|---|---|
connect |
None | None |
disconnect |
None | None |
error |
None | None |
message |
None | Received message |
Task: Send¶
{
type: 'socket',
op: 'send',
data: any, // data to send, will be encoded to JSON
actions: {
sent: string // action type to dispatch when the message has been sent
}
}
Warning
The sent
action can be a dummy (it doesn’t need to be handled by any reducer) but needs to be dispatched, and thus specified, because it will signal to the task reducer that the send
task can be removed from the store. This requirement will be lifted in future versions.
Actions¶
Name | Meta | Payload |
---|---|---|
sent |
None | Note |
Example¶
import {
addTask, delTasks, reduceReducers, taskReducer
} from 'redux-agent'
const MAX_EVENTS = 4
const reducer = (state, action) => {
switch (action.type) {
case 'CONNECT_WEB_SOCKET':
return addTask(state, {
type: 'socket',
op: 'listen',
url: 'wss://ws-beta.kraken.com/',
actions: {
connect: 'SOCKET_CONNECTED',
disconnect: 'SOCKET_DISCONNECTED',
error: 'SOCKET_ERROR',
message: 'SOCKET_MESSAGE_RECEIVED'
}
})
case 'SUBSCRIBE_TO_CURRENCY_INFO':
return addTask(state, {
type: 'socket',
op: 'send',
data: {
event: 'subscribe',
pair: ['XBT/USD', 'XBT/EUR'],
subscription: { name: 'ticker' }
},
actions: {
sent: 'SOCKET_MESSAGE_SENT'
}
})
case 'DISCONNECT_WEB_SOCKET':
return delTasks(state,
(t) => t.type === 'socket')
case 'SOCKET_MESSAGE_RECEIVED':
const { events } = state.liveCurrencyUpdates
return {
...state,
liveCurrencyUpdates: {
...state.liveCurrencyUpdates,
events: events.length < MAX_EVENTS
? events.concat(action.payload)
: events.slice(0, -1).concat(action.payload)
}
}
default:
return state
}
}
export default reduceReducers(reducer, taskReducer)