Handling Real-time Events with Event Channel
Create an event channel that listens to a WebSocket connection for real-time data, showing how Redux-Saga can handle external events and dispatch actions to the store based on those events.
import { eventChannel, END } from 'redux-saga';
import { call, take, put } from 'redux-saga/effects';
// Creating an event channel from the WebSocket
function createWebSocketChannel(sock) {
return eventChannel(emit => {
sock.onmessage = (event) => {
emit(event.data);
};
sock.onclose = () => {
emit(END);
};
const unsubscribe = () => {
sock.onmessage = null;
};
return unsubscribe;
});
}
This code snippet creates a Redux-Saga event channel that listens to incoming messages from a WebSocket connection. Each message received is emitted to subscribers of this channel, and when the WebSocket closes, it emits an END signal to close the channel.
function* listenForSocketMessages() {
const socket = new WebSocket('ws://example.com/data');
const socketChannel = yield call(createWebSocketChannel, socket);
try {
while (true) {
// Taking events from the channel
const payload = yield take(socketChannel);
// Dispatching an action with the payload received from the WebSocket
yield put({ type: 'SOCKET_MESSAGE_RECEIVED', payload });
}
} catch (err) {
console.error('socket error:', err);
} finally {
console.log('WebSocket disconnected');
}
}
This generator function demonstrates how to listen for messages from the created WebSocket channel. It waits for messages from the `take` effect, dispatches actions with received payloads to the Redux store, and handles errors or a disconnection in a structured way.