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

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

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

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

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

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

Помощь

Ответы [ 26 ]

5 голосов
/ 07 февраля 2012

Для тех, кто просто хочет подсчет подключенных клиентов, я верю, что это сделает это:

io.sockets.manager.server.connections

4 голосов
/ 08 августа 2016

In Socket.IO 1.4

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

var allConnectedClients = Object.keys(io.sockets.connected);// This will return the array of SockeId of all the connected clients

Чтобы получить количество всех клиентов:

var clientsCount = io.engine.clientsCount ; // This will return the count of connected clients
4 голосов
/ 22 февраля 2016

Начиная с socket.io 1.5, обратите внимание на изменение от indexOf, которое, по-видимому, обесценилось и заменено значением valueOf

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

    if (ns) {
        for (var id in ns.connected) {
            if (roomId) {
                //var index = ns.connected[id].rooms.indexOf(roomId) ;
                var index = ns.connected[id].rooms.valueOf(roomId) ; //Problem was here

                if(index !== -1) {
                    res.push(ns.connected[id]);
                }
            } else {
                res.push(ns.connected[id]);
            }
        }
    }
    return res.length;
}

Для socket.io версии 2.0.3 работает следующий код:

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

    if (ns) {
        for (var id in ns.connected) {
            if(roomId) {
                // ns.connected[id].rooms is an object!
                var rooms = Object.values(ns.connected[id].rooms);  
                var index = rooms.indexOf(roomId);
                if(index !== -1) {
                    res.push(ns.connected[id]);
                }
            }
            else {
                res.push(ns.connected[id]);
            }
        }
    }
    return res;
}
2 голосов
/ 25 марта 2017

Socket.io 1.7.3 (+):

function getConnectedList ()
{
    let list = []

    for ( let client in io.sockets.connected )
    {
        list.push(client)
    }

    return list
}

console.log( getConnectedList() )

// returns [ 'yIfhb2tw7mxgrnF6AAAA', 'qABFaNDSYknCysbgAAAB' ]

2 голосов
/ 13 июня 2015

на socket.io 1.3 я выполнил это в 2 строки

var usersSocketIds = Object.keys(chat.adapter.rooms['room name']);
var usersAttending = _.map(usersSocketIds, function(socketClientId){ return chat.connected[socketClientId] })
1 голос
/ 25 марта 2015

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

Моя конкретная проблема заключалась в том, что одна и та же розетка соединялась с одной и той же комнатой несколько раз. Решение этой проблемы состояло в том, чтобы проверить, была ли в сокете комната уже внутри своего помещения.

var room = myObj.id.toString();
if (socket.rooms.indexOf(room) === -1) {
    socket.join(room);
    socket.emit('subscribed', {to : room});
} else {
    console.log("Already in room");
}

Надеюсь, это кому-нибудь поможет.

1 голос
/ 01 ноября 2016

Начиная с версии 1.5.1, я могу получить доступ ко всем сокетам в пространстве имен с помощью:

var socket_ids = Object.keys(io.of('/namespace').sockets);
socket_ids.forEach(function(socket_id) {
    var socket = io.of('/namespace').sockets[socket_id];
    if (socket.connected) {
        // Do something...
    }
});

По какой-то причине они используют простой объект вместо массива для хранения идентификаторов сокетов.

1 голос
/ 20 декабря 2011

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

var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;
1 голос
/ 12 января 2016

Это самый простой способ в Socket.IO 1.0+, если вы не используете пространства имен или комнаты.

io.nsps["/"].sockets.length

Это смотрит на пространство имен по умолчанию и определяет длину массива сокетов, без необходимостииспользовать Object.keys()

1 голос
/ 05 сентября 2017

Для кластерного режима используется redis-адаптер

io.in(<room>).clients(function(err, clients) {

});

Поскольку каждый сокет является комнатой, можно определить, существует ли сокет с использованием того же самого.

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