Javascript Socket IO房间:获取特定房间中的客户端列表
我正在尝试显示特定房间中的客户列表。我只想显示他们的用户名,而不是他们的套接字id 这就是我所处的位置:Javascript Socket IO房间:获取特定房间中的客户端列表,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,我正在尝试显示特定房间中的客户列表。我只想显示他们的用户名,而不是他们的套接字id 这就是我所处的位置: socket.set('nickname', "Earl"); socket.join('chatroom1'); console.log('User joined chat room 1); var roster = io.sockets.clients('chatroom1'); for ( i in roster ) { console.log('Username: ' +
socket.set('nickname', "Earl");
socket.join('chatroom1');
console.log('User joined chat room 1);
var roster = io.sockets.clients('chatroom1');
for ( i in roster )
{
console.log('Username: ' + roster[i]);
}
没有任何运气让它列出套接字ID或任何东西。但是,希望它返回昵称。只是一些事情
socket
时,您可以设置如下属性:socket.nickname='Earl'代码>稍后使用save属性,例如在控制台日志中:
console.log(socket.昵称)代码>
console.log('用户加入聊天室1)代码>
socket.nickname = 'Earl';
socket.join('chatroom1');
console.log('User joined chat room 1');
var roster = io.sockets.clients('chatroom1');
roster.forEach(function(client) {
console.log('Username: ' + client.nickname);
});
为了更好地帮助您,我需要查看您的所有代码,因为这不提供上下文。您可以创建用户集合的数组对象,如下所示:
var users = {};
然后在服务器端,您可以在连接时将其添加为新用户
socket.on('new-user', function (username) {
users[username] = username;
});
显示用户时,可以循环“users”对象
在客户端
var socket = io.connect();
socket.on('connect', function () {
socket.emit('new-user', 'username');
});
在socket.IO 3.x中 房间上的套接字是一组ES6客户端ID
//this is an ES6 Set of all client ids in the room
const clients = io.sockets.adapter.rooms.get('Room Name');
//to get the number of clients in this room
const numClients = clients ? clients.size : 0;
//to just emit the same event to all members of a room
io.to('Room Name').emit('new event', 'Updates');
for (const clientId of clients ) {
//this is the socket of each client in the room.
const clientSocket = io.sockets.sockets.get(clientId);
//you can do whatever you need with this
clientSocket.leave('Other Room')
}
在socket.IO 1.x到2.x之间
请参考以下答案:
. 复制了以下内容,并进行了一些修改:
const clients = io.sockets.adapter.rooms['Room Name'].sockets;
//to get the number of clients in this room
const numClients = clients ? Object.keys(clients).length : 0;
//to just emit the same event to all members of a room
io.to('Room Name').emit('new event', 'Updates');
for (const clientId in clients ) {
//this is the socket of each client in the room.
const clientSocket = io.sockets.connected[clientId];
//you can do whatever you need with this
clientSocket.leave('Other Room')
}
如果使用2.0,以上所有答案以及此处或此处的答案都不正确或不完整
io.sockets.manager
和io.sockets.clients
不再存在socket.adapter.rooms代码>
io.sockets.adapter.rooms代码>
io.sockets.adapter.sids;//socket.id数组
io.sockets.adapter.rooms
将给出一个非常混乱的结果,并且socket.adapter.rooms
给出的结果是正确的:到目前为止,我只试过内存适配器,还没有试过redis适配器。不要深入到
套接字/io
对象中,您可以使用简单而标准的方法:
io.in(room_name).clients((err , clients) => {
// clients will be array of socket ids , currently available in given room
});
有关Socket.io大于v1.0和node v6.0+的更多详细信息,请使用以下代码:
function getSockets(room) { // will return all sockets with room name
return Object.entries(io.sockets.adapter.rooms[room] === undefined ?
{} : io.sockets.adapter.rooms[room].sockets )
.filter(([id, status]) => status) // get only status = true sockets
.map(([id]) => io.sockets.connected[id])
}
如果要向它们发射某些东西,请使用以下命令:
getSockets('room name').forEach(socket => socket.emit('event name', data))
我刚刚把一个房间里的所有插座都记录到控制台上,你可以用它们做任何你喜欢的事情
const socketsInRoom = io.adapter.rooms[room_name];
/*Collect all participants in room*/
for(let participant in socketsInRoom){
for(let socketId in socketsInRoom[participant]){
console.log(socketId)
}
}
socket.io^2.2.0
const socket=io(url)
socket.on('connection',client=>{
socket.of(“/”).in(“某些房间名称”).clients((错误,clients)=>{
console.log(clients)//套接字ID数组
})
})
socket.io^2.0
function getRoomClients(room) {
return new Promise((resolve, reject) => {
io.of('/').in(room).clients((error, clients) => {
resolve(clients);
});
});
}
...
const clients = await getRoomClients('hello-world');
console.log(clients);
输出
[ '9L47TWua75nkL_0qAAAA',
'tVDBzLjhPRNdgkZdAAAB',
'fHjm2kxKWjh0wUAKAAAC' ]
对于
socket.IO v3
这里有一个突破性的变化:
Namespace.clients()重命名为Namespace.allSockets(),现在返回一个承诺
之前:
// all sockets in the "chat" namespace and in the "general" room
io.of("/chat").in("general").clients((error, clients) => {
console.log(clients); // => [Anw2LatarvGVVXEIAAAD]
});
现在(v3):
如果您对socket.IO不太熟悉,最好知道,您可以编写
IO
来使用默认名称空间,而不是(“/chat”)的IO.of(“/chat”)
。从socket.IO v3,rooms
现在是Adapter
的受保护属性,因此您将无法通过io.sockets.Adapter.rooms
访问它
而是使用:
const clientsInRoom = await io.in(roomName).allSockets()
还是多个房间
const clientsInRooms = await io.sockets.adapter.sockets(new Set([roomName, roomName2]))
您可以在io对象上使用适配器方法,如
io.sockets.adapter.rooms.get("chatroom1")
这将返回特定房间中已连接客户端的列表。
io.sockets.adapter.rooms这是连接到房间的所有客户端的映射,房间名称作为键,连接的客户端是房间键的值。地图功能适用。此解决方案适用于
- socket.io:“3.0.4”
- socket.io-redis:“6.0.1”
const redis=require('socket.io redis');
适配器(redis({host:'localhost',端口:6379}))代码>由于我对如何在特定名称空间中获取文件室几乎没有发现什么,所以这里有一个例子,以防有人想知道:
io.of(namespaceName).adapter.rooms代码>io.sockets.clients('chatroom1')在nodejs v1.0及以上版本中有效吗?您好,我在io.sockets.clients('roomname')中遇到一个错误,mysocket版本是2.2.0虽然这是公认的答案,但它不适用于大于socket.io 1.0的版本。此方法不存在任何其他方法给出错误:客户端不是函数,你要从客户端发送用户名而不是检查cookies之类的东西?这不是很容易伪造吗?我建议使用socket.handshake.query和中间件进行身份验证,然后将该令牌/用户名存储为socket属性,从服务器端引用,这样它就可以正常工作。我需要大于1.0的东西,但您明确指出这在上面的1.0上不起作用,没有理由否决。有一个+1来平衡它:p.@TheZ你能用这些修改来编辑上面的答案吗?我希望看到这些更改反映在答案中。更新了答案,使其也包含socket.IO 3.x的信息。我如何使用async和Wait进行此操作?请注意,此解决方案不适用于socket.IO v3或更高版本。我如何使用async和Wait进行此操作?一个简单的答案是将整个内容包装在一个异步函数中,并等待响应回调。这可能会有所帮助:这也适用于Socket.iov4。准确地说,上面的示例代码返回一组套接字ID,而不是实际的套接字对象io.of(“/”).sockets
可用于获取连接到命名空间的套接字实例的映射,以便io.of(“/”).sockets.get(socketId)
获取与id匹配的套接字实例。
const clientsInRooms = await io.sockets.adapter.sockets(new Set([roomName, roomName2]))
io.sockets.adapter.rooms.get("chatroom1")