Blog>
Snippets

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.