socket.io:保证套接字一次只加入一个房间

时间:2015-05-08 01:10:09

标签: node.js socket.io

我正在使用socket.io 1.3.5。客户可以通过发送join消息加入会议室。 Serverside代码:

socket.on('join', function(room) {
  socket.join(room);
});

现在我想确保一个客户一次只能在一个房间里。我希望客户端在加入新房间时自动离开当前房间。这是我的方法:

function leaveAllRooms(socket) {
    var rooms = socket.adapter.sids[socket.id];
    Object.keys(rooms).forEach(function(room) {
        if (room != socket.id) {
          socket.leave(room);
        }
    });
}

socket.on('join', function(room) {
  leaveAllRooms(socket);
  socket.join(room);
});

每当客户想要加入某个会议室时,我都会致电leaveAllRoomssocket.leave()会为socket.adapter.sids[socket.id]中找到的所有会议室拨打io.sockets.manager.roomClients[socket.id],但插座自己的房间除外。

此解决方案似乎运行良好,但我不确定它是否正确。在another post's comment中提到可以使用socket.adapter.sids[socket.id](而不是我的df$new[df$date=='a' & !is.na(df$date)] <- df$va[df$date=='a' & !is.na(df$date)] df$new[df$date=='b' & !is.na(df$date)] <- df$vb[df$date=='b' & !is.na(df$date)] df$new[df$date=='c' & !is.na(df$date)] <- df$vc[df$date=='c' & !is.na(df$date)] )。我不知道哪一个更好。在某处有关于此的文档吗?我发现socket.io的文档相当稀疏。

此外,我想知道这个解决方案是否适用于命名空间甚至是通过Redis连接的多个socket.io实例。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

如果您真的只是从加入消息中管理到一个房间,那么您可以这样做:

socket.on('join', function(room) {
    if (socket.lastRoom) {
        socket.leave(socket.lastRoom);
        socket.lastRoom = null;
    }
    socket.join(room);
    socket.lastRoom = room;
});

它只是将最后一个房间存放在套接字上作为属性。

这会将给定套接字限制为一次仅由join消息处理的一个房间。如果客户端打开多个套接字,则它打开的每个套接字都可以在自己的房间中,因为您无法通过经过身份验证的用户ID(仅通过套接字)来跟踪它。我不了解您的多个实例/ redis问题,因为您的要求是一个给定的套接字一次只在一个房间中实现(给定的套接字只存在于一个地方)。

如果您想要更改要求并且一次将一个用户限制为一个房间并且您使用多个服务器并且用户可以打开多个客户端,那么您必须通过存储来实现更复杂最后一个房间和服务器实例集中在redis中,因此您可以跨多个服务器实施策略。