Socket IO Rooms:获取特定房间的客户端列表

问题描述 投票:0回答:18

我没有注册这个蹩脚网站,这样我的数据就可以被出售并用于人工智能训练。

javascript node.js socket.io
18个回答
77
投票

在socket.IO 3.x中

3.x 版本的新功能是,connected 被重命名为套接字,现在是命名空间上的 ES6 映射。 房间套接字上是一组 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')
}

23
投票

您可以使用简单且标准的方式,而不是深入

socket/io
对象:

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

了解更多详情请阅读


19
投票

只是一些事情。

  1. 当您拥有

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

  2. 您的:

    中缺少结束引号(')

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

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

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

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

为了帮助您更多,我需要查看您的所有代码,因为这没有给我上下文。


17
投票

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

示例:

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

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


5
投票

上面的所有答案和这里的答案socket.io获取套接字当前所在的房间或这里Socket.IO - 我如何获取已连接的套接字/客户端的列表?如果您使用2.0,则要么不正确或不完整.

  1. 在2.0中,
    io.sockets.manager
    io.sockets.clients
    不再存在。
  2. 在不使用namespace的情况下,以下3个参数都可以获取特定房间的socket。

    socket.adapter.rooms;

    io.sockets.adapter.rooms;

    io.sockets.adapter.sids; // the socket.id array

  3. 使用命名空间(我在这里使用“cs”),

    io.sockets.adapter.rooms
    会给出一个相当混乱的结果,而
    socket.adapter.rooms
    给出的结果是正确的:

/* socket.adapter.rooms give: */

{
  "/cs#v561bgPlss6ELZIZAAAB": {
    "sockets": {
      "/cs#v561bgPlss6ELZIZAAAB": true
    },
    "length": 1
  },
  "a room xxx": {"sockets": {
    "/cs#v561bgPlss6ELZIZAAAB": true
  },
  "length": 1
  }
}

/* io.sockets.adapter.rooms give: a sid without namespace*/

{
  "v561bgPlss6ELZIZAAAB": {
    "sockets": {
      "v561bgPlss6ELZIZAAAB": true
    }, "length": 1
  }
}

注意:默认的房间是这样的:“Socket.IO 中的每个 Socket 都由一个随机的、不可猜测的、唯一的标识符 Socket#id 标识。为了您的方便,每个 Socket 都会自动加入由这个 id 标识的房间。”

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


5
投票

对于 Socket v.4,正确的语法是:

const sockets = await io.in("room1").fetchSockets();

https://socket.io/docs/v4/server-api/#namespacefetchsockets


3
投票

对于

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

来源

如果您对 socket.IO 不太熟悉,最好知道您可以编写

io.of("/chat")
来使用默认命名空间,而不是
io


3
投票

在socket.IO 4.x中

const getConnectedUserIdList = async () => {
  let connectedUsers = [];
  let roomUsers = await io.in(`members`).fetchSockets();
  roomUsers.forEach((obj) => {
    connectedUsers.push(obj.request.user.id);
  });
  return connectedUsers;
};

2
投票

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' ]

2
投票

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

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

1
投票

此解决方案适用于

  • 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


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

0
投票

您可以在 io 对象上使用适配器方法,例如

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

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


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

0
投票

由于我对如何获取特定名称空间内的房间知之甚少,所以这里是为了以防万一有人想知道:

io.of(namespaceName).adapter.rooms;


0
投票
let sockets = await io
              .of("/namespace")
              .in(ROOM_NAME)
              .allSockets();

您可以通过

获取已连接客户端的长度
console.log(receiver.size);

-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');
});
© www.soinside.com 2019 - 2024. All rights reserved.