node.js - socket.io:确保套接字一次仅加入一个房间

标签 node.js socket.io

我正在使用 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.leave()适用于 socket.adapter.sids[socket.id] 中找到的所有房间,除了 socket 自己的房间。

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

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

最佳答案

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

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

关于node.js - socket.io:确保套接字一次仅加入一个房间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114210/

相关文章:

javascript - socket io - 它如何知道数据库中的数据是否已更改?

javascript - Socket.io - Access-Control-Allow-Origin 不允许来源

node.js - 如何创建一个正在运行的API端点?

node.js - 使用 mongodb 创建数据库 node.js

javascript - Socket.io 需要很长时间才能触发断开连接事件

javascript - 为什么我一直收到 "Cannot find module ' socket.io'”?

javascript - 套接字.io 1.0.5 : How to save session variables?

javascript - JavaScript 中的 Node js/MongoDB 副本集数组

node.js - 在快速路由 api 中添加命名参数

node.js - 在nodejs中从firebase获取具有最大属性的数据