如何在由socketio-redis管理的socketio进程集群中查找用户套接字

时间:2019-09-19 17:40:00

标签: node.js redis socket.io socket.io-redis

我是socketio-redis适配器的新手。最初我只有一个socketio进程,但现在尝试使用socketio集群。

当它是单个进程时,我将维护一个已连接套接字的映射,以通过userId查找套接字。当用户A发射到某个房间时,如果用户B已连接但尚未在房间中,则找到B的插座并加入该房间。然后A的插座放到房间里。

我的问题是,如何使用socketio-redis进行此操作?

下面是一个简化的计划。是否可以在一个socketio进程中的连接套接字上添加一个userId,然后在另一个进程中通过userId查找该套接字?

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 })
    }
  }
})

任何人都具有实施类似内容的经验吗?

1 个答案:

答案 0 :(得分:0)

我认为您可以使用customRequest / customHook向每个节点发送请求,以查找具有所需userId的套接字:

  

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

然后让它加入房间。

编辑:也许这个例子可以帮助您:

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)
}