【问题标题】:socket.io: assure socket joins only one room at a timesocket.io:确保套接字一次只加入一个房间
【发布时间】:2015-05-08 01:10:09
【问题描述】:

我正在使用 socket.io 1.3.5。客户可以通过发送join 消息加入房间。服务器端代码:

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

每当客户想要加入房间时,我都会调用leaveAllRooms,它会为socket.adapter.sids[socket.id] 中找到的所有房间调用socket.leave(),除了套接字自己的房间。

这个解决方案似乎运作良好,但我不确定它是否正确。在another post's comment 中提到可以使用io.sockets.manager.roomClients[socket.id](而不是我的socket.adapter.sids[socket.id])。我不知道哪个更好。某处是否有关于此的文档?我发现socket.io 的文档很少。

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

【问题讨论】:

    标签: node.js socket.io


    【解决方案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 中,因此您可以跨多个服务器强制执行策略。

    【讨论】:

      猜你喜欢
      • 2020-10-28
      • 1970-01-01
      • 2022-10-31
      • 2016-08-06
      • 1970-01-01
      • 2014-07-18
      • 2016-12-14
      • 2021-11-12
      • 2012-06-09
      相关资源
      最近更新 更多