Using socket.io with redux

2019-06-15 22:23发布

问题:

This is the first time I am going to use socket.io in production. I am using React + Redux. I have recently integrated socket.io with redux and its working fine but I am not sure if it would be the best way to do how I have done. Because I haven't found any sort of proper implementations of socket.io with redux, I need some help/suggestions on ways if I can improve it.

So, for starters I have setup a service for managing sockets all over the app:

Socket.js

import isEmpty from 'lodash/isEmpty';
import io from 'socket.io-client';
import storage from '../storage';

/* eslint-disable no-use-before-define */

const Socket = {
  connect,
  emit,
  on,
  removeListener,
  socket: null
};

/* eslint-enable no-use-before-define */

function connect() {
  const hasAuthenticated = !isEmpty(storage.get('user'));
  if (hasAuthenticated) {
    // Setup a server for testing.
    Socket.socket = io.connect('http://localhost:3000', { reconnect: true });
  }
}

connect();

function on(eventName, callback) {
  if (Socket.socket) {
    Socket.socket.on(eventName, data => {
      callback(data);
    });
  }
}

function emit(eventName, data) {
  if (Socket.socket) {
    Socket.socket.emit(eventName, data);
  }
}

function removeListener(eventName) {
  if (Socket.socket) {
    Socket.socket.removeListener(eventName);
  }
}

export default Socket;

I have only used it with a single page, but ofcourse there will be more pages. My redux compositon for that page is:

Dashboard.jsx

componentWillMount() {
    this.props.alertViolations(); // Action
  }

  componentWillUnmount() {
    this.props.unsubscribeViolations(); // Action
  }

Actions.js

export function alertViolations() {
  return dispatch => {
    Socket.on('violations', violation => {
      dispatch(actions.updateViolations(violation));
    });
  };
}

export function unsubscribeViolations() {
  Socket.removeListener('violations');
  return dispatch => {
    dispatch(actions.removeViolationsListener());
  };
}

Its working fine. On unmounting it stops listening to the emit function that I have on server. I would really appreciate if I could get some suggestions regarding:

  • Do I need to setup a middleware to managing sockets in a more better and abstract way?
  • Is there a better way to manage sockets with redux?
  • How can I make use of the built in connect and disconnect functions?
  • The way I have handled to only build the connection if user has authentication, is that fine? Or could there be a better way to handle this as well?
  • Oh and also, if I want to remove the connection on logout? Would I just have to removeListeners from all methods or can I use the disconnect function on logout actions?

Thanks a lot. Please let me know if I have missed anything in explaining.

回答1:

Middleware is the most common place for a persistent connection like a websocket in a Redux app. There's a good number of existing Redux+websocket integration libraries already - see my list at https://github.com/markerikson/redux-ecosystem-links/blob/master/middleware.md#sockets-and-adapters . You may be able to use some of them as-is, or use them as examples for your own implementation.