我用Node.js和socket.io玩多人纸牌游戏,还有游戏室,玩家可以加入。
在加入一个房间时,我简单地使用:
io.sockets.on('connection', function (socket) {
socket.on('joinRoom', function (gid) {
//gid is game ID - create room name based on this and join the room
var room = 'game'+gid;
socket.join(room);
});
});我的问题是,检查插座是否连接到某个房间的最快方法是什么?我知道我可以在数组中获取这个房间中的所有套接字,然后检查目标套接字是否在数组中,但我猜应该有一个更基本的语法。我要找的(伪代码)应该是
if(socket with ID "z8b7dbf98i" is in room "game10")
//do something发布于 2014-04-13 17:37:56
对于文档,socket.io似乎没有任何简单的方法来做到这一点。您确实需要检查客户机是在房间数组中,还是相反:房间是否在客户端数组中。
这可以通过使用indexOf的oneliner来完成
if(socket.rooms.indexOf(room) >= 0)或者相反的搜索:
if(io.sockets.manager.rooms['/' + room].indexOf(socket.id) >= 0)发布于 2017-05-16 10:02:37
你可以这样检查
io.sockets.adapter.rooms['roomId']
这将返回一个带有sId的对象。
{"1sEAEIZeuMgdhF35AAAA":true}
特定于版本的更新: 3.0+:
io.sockets.adapter.get('roomId')1.4:
io.sockets.adapter.rooms['roomId']1.3.x:
io.sockets.adapter.rooms['roomId']; 1.0.x至1.2.x:
io.adapter.rooms['roomId'];**最新情况:**
但是,可以检查套接字Id是否在给定的房间中,就像上面提到的那样,只有当服务器体系结构有单个节点服务器/单个节点进程时,才能检查套接字Id是否在给定的房间中。
如果您使用的是多节点服务器,即单独的节点进程和负载平衡。
这里要注意的是,套接字只在它们首先连接的进程上注册。因此,您需要使用socket.io-redis将所有节点连接到一起以同步事件,而在多节点之间维护套接字is列表的方法是在客户端每次连接/断开连接时广播一个事件,以便每个节点更新&维护所有客户端/套接字is的实时列表。
Background/Details:
redis适配器扩展了基座适配器,但它只扩展了重写/添加以下属性:
客户端广播添加del delAll
使用以下代码:
io.sockets.adapter.rooms["roomId"]; //Any of the above examples specific to versions mentioned above您是在socket.io-redis适配器上查询房间属性。这没有被redis适配器覆盖,所以您实际上是在查询基本适配器,它只知道当前进程中的房间/客户端。
为什么redis适配器没有覆盖房间的属性?可能是因为它必须查询redis数据库实例来构造一个对象,该对象包含此属性的每次访问上的所有房间和连接。不是个好主意?
因此,在撰写本文的答案时,您必须使用如下方法将该功能添加到适配器本身:
/**
* One-Line code/property to check if the socket id is in given room.
*
* @param {String} room id
* @param {Function} callback (optional)
* @api public
*/
Redis.prototype.isSidExistsInRoom = function(room, fn){ ... }您将在其中访问redis数据库实例。
这应该是所有其他适配器实现的基本适配器接口的一部分。这是每个人总有一天会面临的一个常见问题,当他们扩展服务器时;)
另一种方法就是在socket.io-redis 3.1.0中使用customRequest/customHook方法。
**使用Ver5.2.0更新:(相关多节点服务器)**
现在,redis适配器从5.2.0开始为您提供跨进程/节点的空间。
源:RedisAdapter#clients(房间:数组,fn:Function) >返回连接到所有节点的房间的客户ID列表。参见Namespace#clients(fn:Function)
io.of('/').adapter.clients((err, clients) => {
console.log(clients); // an array containing all connected socket ids
});
io.of('/').adapter.clients(['room1', 'room2'], (err, clients) => {
console.log(clients); // an array containing socket ids in 'room1' and/or 'room2'
});
// you can also use
io.in('room3').clients((err, clients) => {
console.log(clients); // an array containing socket ids in 'room3'
});编码愉快!
发布于 2021-06-08 20:21:28
2021回应:
这让我很头疼,但目前在版本4.0.2版的Socket IO中,socket.rooms是Javascript Set,所以您可以使用.has()检查给定的套接字是否在房间里。
if (socket.rooms.has('abc')) {
// Do something if socket is in room 'abc'
} else {
// Do something if socket is NOT in room 'abc'
}如果您需要检查用户是否不在房间,只需使用!即可。
if (!socket.rooms.has('abc')) {
// Do something if socket is NOT in room 'abc'
}https://stackoverflow.com/questions/23045245
复制相似问题