0

I'm new to socketio-redis adapter. Originally I had a single socketio process, but now trying a socketio cluster.

When it was a single process, I'd maintain a Map of connected sockets, to find a socket by a userId. When user A emit to a room, if user B was connected but not yet in the room, B's socket was found and joined that room. Then A's socket emit to room.

My question is, how to go about this with socketio-redis?

Below is a simplified plan. Is it possible to add a userId to a socket on connect in one socketio process, then find that socket by userId in a different process?

chatio.on('connect', socket => {
  // add userId to socket obj
  socket.userId = userId
  . . .
  socket.on("message", async (data, ack) => {
    const userId  = data.otherUserId
    const roomId  = data.roomId
    const message = data.message
    const clients = await io.of('/').adapter.clients()

    // a message came in from user A
    // if user B socket is found, B joins same room
    const otherUserSocket = clients.find(socketId => {
      const s = io.of('/').adapter.connected[socketId]
      return (s.userId == userId)
    })

    if (otherUserSocket) {
      otherUserSocket.join(roomId)
      socket.to(roomId).emit("message", { message })
    }
  }
})

Anyone have experience implementing something like this?

1192805
  • 988
  • 2
  • 10
  • 26

1 Answers1

0

I think you can use customRequest/customHook to send a request to every nodes to find the socket with the wanted userId :

RedisAdapter#customRequest(data:Object, fn:Function)

Then make it joins the room.

Edit : May be this example can help you :

let ns = io.of('/');
ns.on('connection', socket => {
    // add userId to socket obj
    socket.userId = socket.handshake.query.userId
    console.log("New user connected: " + socket.userId);

    socket.on("message", data => {
      ns.adapter.customRequest(data, (err,results) =>{
        if(err){
            console.log('Error : ' + err.message)
        }else{
            console.log(results);
            socket.to(data.roomId).emit("message", data.message)
        }
      }); 
    })
})

ns.adapter.customHook = (data, cb) => {
    let otherUserId  = data.otherUserId
    let roomId  = data.roomId
    let clients = Object.keys(ns.sockets)

    clients.forEach(socketId => {
        if(ns.sockets[socketId].userId === otherUserId){
            ns.sockets[socketId].join(roomId)
            return cb(true)
        }
    });
    return cb(false)
}
LaurentP22
  • 586
  • 5
  • 15