0

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

任何人都有实施这样的经验?

4

1 回答 1

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)
}
于 2019-10-01T17:05:01.547 回答