Socket.IO - как получить список подключенных сокетов / клиентов? - PullRequest
139 голосов
/ 03 июля 2011

Я пытаюсь получить список всех сокетов / клиентов, которые в данный момент подключены.

io.sockets не возвращает массив, к сожалению.

Я знаю, что могу сохранить свой собственный список, используя массив, но не думаю, что это оптимальное решение по двум причинам:

  1. Избыточность. Socket.IO уже хранит копию этого списка.

  2. Socket.IO предоставляет метод для установки произвольных значений полей для клиентов (то есть: socket.set('nickname', 'superman')), поэтому мне нужно было бы не отставать от этих изменений, если бы я должен был поддерживать свой собственный список.

Помощь

Ответы [ 26 ]

160 голосов
/ 06 августа 2011

В Socket.IO 0.7 у вас есть метод clients для пространств имен, он возвращает массив всех подключенных сокетов.

API без пространства имен:

var clients = io.sockets.clients();
var clients = io.sockets.clients('room'); // all users from room `room`

Дляnamespace

var clients = io.of('/chat').clients();
var clients = io.of('/chat').clients('room'); // all users from room `room`

Надеется, что это поможет кому-то в будущем

ПРИМЕЧАНИЕ: Это решение ONLY работает с версией до 1.0

95 голосов
/ 10 июня 2014

Socket.io 1.4

Object.keys(io.sockets.sockets); дает вам все подключенные розетки.

Socket.io 1.0 Начиная с socket.io 1.0, фактически принятый ответ больше не действителен. Поэтому я сделал небольшую функцию, которую я использую как временное исправление:

function findClientsSocket(roomId, namespace) {
    var res = []
    // the default namespace is "/"
    , ns = io.of(namespace ||"/");

    if (ns) {
        for (var id in ns.connected) {
            if(roomId) {
                var index = ns.connected[id].rooms.indexOf(roomId);
                if(index !== -1) {
                    res.push(ns.connected[id]);
                }
            } else {
                res.push(ns.connected[id]);
            }
        }
    }
    return res;
}

API для Нет пространства имен становится

// var clients = io.sockets.clients();
// becomes : 
var clients = findClientsSocket();

// var clients = io.sockets.clients('room');
// all users from room `room`
// becomes
var clients = findClientsSocket('room');

API для пространства имен становится:

// var clients = io.of('/chat').clients();
// becomes
var clients = findClientsSocket(null, '/chat');

// var clients = io.of('/chat').clients('room');
// all users from room `room`
// becomes
var clients = findClientsSocket('room', '/chat');

Также см. Этот связанный вопрос , в котором я даю функцию, которая возвращает сокеты для данной комнаты.

function findClientsSocketByRoomId(roomId) {
var res = []
, room = io.sockets.adapter.rooms[roomId];
if (room) {
    for (var id in room) {
    res.push(io.sockets.adapter.nsp.connected[id]);
    }
}
return res;
}

Socket.io 0,7

API для без пространства имен :

var clients = io.sockets.clients();
var clients = io.sockets.clients('room'); // all users from room `room`

Для пространство имен

var clients = io.of('/chat').clients();
var clients = io.of('/chat').clients('room'); // all users from room `room`

Примечание: Поскольку кажется, что API socket.io склонен к взлому, а некоторые решения основываются на деталях реализации, это может быть вопросом отслеживания клиентов самостоятельно:

var clients = [];

io.sockets.on('connect', function(client) {
    clients.push(client); 

    client.on('disconnect', function() {
        clients.splice(clients.indexOf(client), 1);
    });
});
46 голосов
/ 08 июня 2014

После socket.io 1.0 мы больше не можем использовать

io.sockets.clients(); 
or
io.sockets.clients('room'); 

.Вместо этого вы можете использовать следующее

var clients_in_the_room = io.sockets.adapter.rooms[roomId]; 
for (var clientId in clients_in_the_room ) {
  console.log('client: %s', clientId); //Seeing is believing 
  var client_socket = io.sockets.connected[clientId];//Do whatever you want with this
}
35 голосов
/ 09 декабря 2014

Использование Socket.IO 1.x:

Получить массив подключенных клиентов:

io.engine === io.eio // => true
Object.keys(io.engine.clients) // => [ 'US8AxrUrrDF_G7ZUAAAA', 'Ov2Ca24Olkhf2NHbAAAB' ]
Object.keys(io.eio.clients)    // => [ 'US8AxrUrrDF_G7ZUAAAA', 'Ov2Ca24Olkhf2NHbAAAB' ]

Получить количество подключенных клиентов:

io.engine.clientsCount // => 2
io.eio.clientsCount    // => 2
31 голосов
/ 01 марта 2015

Очень просто в socket.io 1.3:

io.sockets.sockets - это массив, содержащий подключенные объекты сокетов. Если вы сохранили имя пользователя в каждом сокете, вы можете сделать:

io.sockets.sockets.map(function(e) {
    return e.username;
})

Boom. У вас есть имена всех подключенных пользователей.

21 голосов
/ 09 июля 2015

Я прошел через эту боль сегодня. Socket.io будет намного лучше, если они смогут составить надлежащую документацию для своего API.

Во всяком случае, я попытался заглянуть в io.sockets и нашел несколько вариантов, которые мы можем использовать:

io.sockets.connected //Return {socket_1_id: {}, socket_2_id: {}} . This is the most convenient one, since you can just refer to io.sockets.connected[id] then do common things like emit()
io.sockets.sockets //Returns [{socket_1}, {socket_2}, ....]. Can refer to socket_i.id to distinguish
io.sockets.adapter.sids //Return {socket_1_id: {}, socket_2_id: {}} . Looks similar to the first one but the object is not actually the socket, just the information.

// Not directly helps but still relevant
io.sockets.adapter.rooms //Returns {room_1_id: {}, room_2_id: {}}
io.sockets.server.eio.clients //Return client sockets
io.sockets.server.eio.clientsCount //Return number of connected clients

Также обратите внимание, что при использовании socket.io с пространством имен вышеприведенные методы не работают, поскольку io.sockets становится массивом, а не объектом. Чтобы решить, просто замените io.sockets на io (т.е. io.sockets.connected становится io.connected, io.sockets.adapter.rooms становится io.adapter.rooms ...)

Проверено на socket.io 1.3.5

17 голосов
/ 08 ноября 2012

Я думаю, что мы можем получить доступ к объекту сокета с сервера, и вы можете назначить псевдоним и указать его идентификатор сокета,

io.sockets.on('connection',function(socket){ 
    io.sockets.sockets['nickname'] = socket.id;
    client.on("chat", function(data) {      
        var sock_id = io.sockets.sockets['nickname']
        io.sockets.sockets[sock_id].emit("private", "message");
    });    
});

Вкл. disconnect. Удалите псевдоним из io.sockets.sockets.

12 голосов
/ 04 августа 2017

версия + 2.0

В версии +2.0 вы указываете пространство имен / комнату / узел, к которому вы обращаетесь.

Как и в случае широковещания, по умолчанию используются все клиенты из пространства имен по умолчанию ('/'):

const io = require('socket.io')();  
io.clients((error, clients) => {
      if (error) throw error;
      console.log(clients); // => [6em3d4TJP8Et9EMNAAAA, G5p55dHhGgUnLUctAAAB]
});

Получает список идентификаторов клиентов, подключенных к определенному пространству имен (по всем узлам, если применимо).

const io = require('socket.io')();
io.of('/chat').clients((error, clients) => {
     if (error) throw error;
     console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD]
});

Пример получения всех клиентов в комнате пространства имен:

const io = require('socket.io')();
io.of('/chat').in('general').clients((error, clients) => {
      if (error) throw error;
      console.log(clients); // => [Anw2LatarvGVVXEIAAAD] 
});

Это из официальной документации: Socket.IO Server-API

9 голосов
/ 16 февраля 2015

Это лучший способ получить к нему доступ в socket.io 1.3

.

Object.keys(socket.adapter.rooms[room_id])

5 голосов
/ 11 февраля 2016

Socket.io 1.4.4

Пример кода для вас.

function get_clients_by_room(roomId, namespace) {
        io.of(namespace || "/").in(roomId).clients(function (error, clients) {
            if (error) { throw error; }
            console.log(clients[0]); // => [Anw2LatarvGVVXEIAAAD]
            console.log(io.sockets.sockets[clients[0]]); //socket detail
            return clients;
        });
    }

Думаю, кому-то этот блок кода поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...