套接字IO客户:获取特定房间的客户列表

时间:2013-08-07 02:27:04

标签: 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: ' + roster[i]);   
}

没有任何运气可以让它列出套接字ID或任何东西。希望它能够返回昵称。

15 个答案:

答案 0 :(得分:36)

对于使用socket.IO 1.0或更高版本的用户,上述答案可能无效。请参阅以下答案。 Get list of all clients in specific room

更新房间中所有客户端的套接字对象的代码

var clients = io.sockets.adapter.rooms['Room Name'].sockets;   

//to get the number of clients
var numClients = (typeof clients !== 'undefined') ? Object.keys(clients).length : 0;

for (var clientId in clients ) {

     //this is the socket of each client in the room.
     var clientSocket = io.sockets.connected[clientId];

     //you can do whatever you need with this
     clientSocket.emit('new event', "Updates");

}

答案 1 :(得分:17)

只是一些事情。

  1. 当您拥有socket时,您可以稍后设置以下属性:socket.nickname = 'Earl';以在控制台日志中使用save属性: console.log(socket.nickname);

  2. 你在哪里错过了结束语('):

    console.log('User joined chat room 1);

  3. 我不完全确定你的循环。

  4. 下面是修改后的代码应该对你有所帮助,同时也要注意我在下面使用的循环是异步的,这可能会影响你处理数据传输的方式。

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

    为了帮助你,我需要查看你的所有代码,因为这不会给我上下文。

答案 2 :(得分:10)

您可以使用简单且标准的方式,而不是深入socket/io对象:

io.in(room_name).clients((err , clients) => {
    // clients will be array of socket ids , currently available in given room
});

更多详情 DO READ

答案 3 :(得分:2)

如果使用2.0,上面的所有答案以及socket.io get rooms which socket is currently inSocket.IO - how do I get a list of connected sockets/clients?的答案都不正确或不完整。

  1. 在2.0中,io.sockets.manager或io.sockets.clients不再存在。
  2. 不使用命名空间,以下3个参数都可以在特定房间中获得套接字。

    socket.adapter.rooms;

    io.sockets.adapter.rooms;

    io.sockets.adapter.sids; // socket.id数组

  3. 使用命名空间(我在这里使用“cs”),io.sockets.adapter.rooms会给出一个非常令人困惑的结果,而socket.adapter.rooms给出的结果是正确的:

    / * socket.adapter.rooms给出:* /

    {“/ cs #v561bgPlss6ELZIZAAAB”:{“套接字”:{“/ cs #v561bgPlss6ELZIZAAAB”:true},“length”:1},“a room xxx”:{“套接字”:{“/ cs# v561bgPlss6ELZIZAAAB “:真},” 长度“:1}}

    / * io.sockets.adapter.rooms给出:没有命名空间的sid * /

    { “v561bgPlss6ELZIZAAAB”:{ “套接字”:{ “v561bgPlss6ELZIZAAAB”:真}, “长度”:1}}

  4. 注意:默认房间为:“Each Socket in Socket.IO is identified by a random, unguessable, unique identifier Socket#id. For your convenience, each socket automatically joins a room identified by this id。”

    到目前为止我只尝试了内存适配器,还没试过redis-adapter。

答案 4 :(得分:1)

对于大于v1.0的Socket.io和节点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))

答案 5 :(得分:1)

socket.io ^ 2.0

.concat()

输出

const a = [1,2,3,2,1,3,3,2,1];
const b = ['b','b','b','c','c','c','d','d','d'];

const sortedGroups = [].concat(...Array.from(a.reduce((map, val, i) => 
  map.set(b[i], (map.get(b[i]) || []).concat(val)),
  new Map
).values(), grouped => grouped.sort((a, b) => b-a)));

console.log(sortedGroups);

答案 6 :(得分:0)

我刚刚将一个房间中的所有套接字记录到控制台,您可以使用它们执行任何操作...

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

答案 7 :(得分:0)

socket.io ^ 2.2.0


const socket = io(url)

socket.on('connection', client => {
  socket.of('/').in("some_room_name").clients((err, clients) => {
    console.log(clients) // an array of socket ids
  })
})




答案 8 :(得分:0)

对于socket.IO v3,这里有一个重大变化:

Namespace.clients()重命名为Namespace.allSockets(),现在返回一个Promise。

之前:

// all sockets in the "chat" namespace and in the "general" room
io.of("/chat").in("general").clients((error, clients) => {
  console.log(clients); // => [Anw2LatarvGVVXEIAAAD]
});

现在(v3):

// all sockets in the "chat" namespace and in the "general" room
const ids = await io.of("/chat").in("general").allSockets();

Source

如果您不太熟悉socket.IO,最好知道可以写io.of("/chat")而不是io来使用默认名称空间。

答案 9 :(得分:0)

Socket.io v3 开始,rooms现在是Adapter的受保护属性,因此您将无法通过io.sockets.adapter.rooms访问它。 / p>

代替使用:

const clientsInRoom = await io.in(roomName).allSockets()

或多个房间

const clientsInRooms = await io.sockets.adapter.sockets(new Set([roomName, roomName2]))

答案 10 :(得分:0)

你可以在 io 对象上使用适配器方法

io.sockets.adapter.rooms.get("chatroom1")

这将返回特定房间中已连接客户端的列表。 io.sockets.adapter.rooms 这是连接到房间的所有客户端的映射,房间名称作为键,连接的客户端是房间键的值。地图功能适用。

答案 11 :(得分:0)

此解决方案适用于

  • socket.io : "3.0.4"
  • socket.io-redis : "6.0.1"

先导入这些

const redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));

socket.on('create or join', function(room) {
    log('Received request to create or join room ' + room);

    //var clientsInRoom = io.sockets.adapter.rooms[room];
    
    mapObject = io.sockets.adapter.rooms // return Map Js Object
    clientsInRoom = new Set(mapObject.get(room))
  
    var numClients = clientsInRoom ? clientsInRoom.size : 0;
    log('Room ' + room + ' now has ' + numClients + ' client(s)');

https://socket.io/docs/v3/using-multiple-nodes/#The-Redis-adapter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get

答案 12 :(得分:0)

由于我对如何将房间置于特定命名空间中的方法知之甚少,因此以防万一有人想知道:

io.of(namespaceName).adapter.rooms;

答案 13 :(得分:0)

对于 v4 我使用了这个方法 fetchSockets()

示例:

let roomUsers=await io.in(`room-id`).fetchSockets()

请参阅此处的文档: https://socket.io/docs/v3/migrating-from-3-x-to-4-0/#Additional-utility-methods

答案 14 :(得分:-3)

您可以将用户集合的数组对象创建为

var users = {};

然后在服务器端,您可以在连接时将其添加为新用户

socket.on('new-user', function (username) {
    users[username] = username;
});

在显示用户时,您可以循环“用户”对象

在客户端

var socket = io.connect();

socket.on('connect', function () {
    socket.emit('new-user', 'username');
});