我正在使用 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/