简体   繁体   中英

Redux + socket.io in the server - Does business logic belong in event listeners or action creators?

I'm implementing an online multiplayer game which will receive connections from clients through socket.io.

I'm not sure where to handle events in the server - either in the socket event listeners themselves, or if they should defer this logic to the action creators.

Take into account that in many of the cases, receiving an event from a client socket will trigger an .emit or .broadcast from the server side, so I need to have access to socket and io inside whatever function handles this.

My solution so far:

Store creator:

export default io => createStore(
    combineReducers({
        users,
        tables,
        games
    }),
    applyMiddleware(
        thunk.withExtraArgument(io),
        logger
    )
);

Create store with io as an extra thunk argument, so that action creators can io.emit events, bind socket event handlers to store and io so that they can dispatch , getState and io.emit :

let store = createStore(io),
    //socket event handlers
    boundHandlers = [
        tables,
        games,
        messages
    ].map(handler => handler(store, io));

io.on('connect', users(store, io, boundHandlers));

My users higher order function that returns the event handler for incoming connections and registers the boundHandlers declared previously:

let connections = {};

export default ({dispatch, getState}, io, handlers) => async socket => {
    //close sockets with same session id
    let sessionId = socket.handshake.session.id;

    if(connections[sessionId])
        connections[sessionId].disconnect();

    connections[sessionId] = socket;

    let userId = /** some authentication logic here **/

    //bind event handlers to socket
    handlers.forEach(handler => handler(socket, userId));

    socket
    //send initial user state
    .emit('init', userId, getUserState(getState(), userId))

    /** other stuff **/
}

This last piece of code is the one I'm not sure should be in the event listener or in an action creator.

In idiomatic redux action creators should be pure (no side effects) which means keeping them free of asynchronous logic.

I wrote middleware to configure the connection and dispatch actions accordingly.

I'd recommend checking out one of the number of libraries that are out there for this. Either to use as is or for ideas on how to implement your own. Like socket.io-redux .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM