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

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

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

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

  1. Резервирование. Socket.IO уже хранит копию этого списка.

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

Помощь?


person Andy Hin    schedule 03.07.2011    source источник
comment
Разве вы не можете просто преобразовать io.sockets в массив?   -  person mak    schedule 03.07.2011
comment
Нет, io.sockets на самом деле является сложным объектом и не просто хранит список объектов сокетов. На данный момент я собираюсь управлять своим собственным списком пользовательских объектов и избегать использования функции socket.set ().   -  person Andy Hin    schedule 03.07.2011
comment
В 0.7.6 io.sockets.sockets - это простой хэш-объект id = ›socket   -  person mak    schedule 03.07.2011
comment
Я заметил это, но он ведет себя странно (не похоже на стандартные объекты сокета). Например, я пробовал: pastebin.com/fxuzVckS, но он говорит, что объект сокета не содержит 'get' метод.   -  person Andy Hin    schedule 03.07.2011
comment
socket - это идентификатор, io.sockets.sockets[socket] - это сокет.   -  person mak    schedule 03.07.2011
comment
Верно. В этом есть смысл. Я пробовал следующее: pastebin.com/kJcHzpvV, и похоже, что псевдоним возвращает значение null. Что я делаю неправильно?   -  person Andy Hin    schedule 03.07.2011
comment
Первый аргумент - err, а если вы используете хранилище памяти, он всегда null. .get('nickname', function(err, nickname) { ... })   -  person mak    schedule 03.07.2011


Ответы (31)


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

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`

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

ПРИМЕЧАНИЕ. Это решение ТОЛЬКО работает с версией до 1.0.


ОБНОВЛЕНО 6 марта 2020 г.

Начиная с версии 1.x и выше, перейдите по этой ссылке: узнать, сколько человек участвует в чате в socket.io

person 3rdEden    schedule 06.08.2011
comment
Я думаю, что они отказались от метода клиентов в 1.0 ... сейчас просто проверяю это ... - person marksyzm; 07.04.2014
comment
В 1.0 они сбросили почти все, так как это полная переработка. Но поскольку 1.0 не выпускалась годами. В 1.0 вы должны использовать объект connected пространства имен. - person 3rdEden; 08.04.2014
comment
@ 3rdEden, каков синтаксис для использования подключенного объекта пространства имен? var clients = io.sockets.connected(); явно не работает. Спасибо - person Kaya Toast; 05.07.2014
comment
Начиная с версии 1.x и выше: stackoverflow.com/questions/9352549/ - person Musa Haidari; 07.06.2016
comment
TypeError: fn.bind не является функцией - person Iman Marashi; 25.04.2020
comment
Обратите внимание, что вы идентифицируете отдельные устройства сокетов с помощью свойства socket.id, я обычно сохраняю все идентификаторы в массиве при подключении новых устройств, длина этого массива дает количество клиентов. Преимущество этого в том, что позже вы можете определить, существует ли новое подключенное устройство в этом массиве или нет. Точно так же вы можете удалить устройства из массива при вызове события «разъединение». - person krupesh Anadkat; 01.06.2020

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);
    });
});
person nha    schedule 10.06.2014
comment
@TylerScott Я тоже, особенно учитывая, что это не описано в их руководстве по миграции (если я чего-то не упускаю). socket.io/docs/migrating-from-0-9 - person nha; 19.06.2014
comment
@nha, это не работает для меня, но возвращает массив целых чисел, например 0, 1 и 2 и т. д., вместо массива сокетов. Любые идеи? - person ThePixelPony; 20.09.2014
comment
как насчет нескольких узлов? потому что я использую несколько узлов с хранилищем Redis - person John Nguyen; 31.03.2015
comment
@nha вы отвечаете точно, но он не работает для нескольких узлов с сервером хранилища Redis. из процесса 1 узла, вы не можете проверить, подключен ли сокет, используя ns.connected [id] - person John Nguyen; 01.04.2015

После 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
}
person salihcenap    schedule 08.06.2014
comment
я меняю на var clients_in_the_room = io.sockets.adapter.rooms[roomId].sockets - person Fábio Zangirolami; 03.08.2016

Использование 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
person Joseph Dykstra    schedule 09.12.2014

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

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

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

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

person or29544    schedule 01.03.2015
comment
Спасибо! +1 для простоты. Вы знаете, есть ли разница между этим методом и, скажем, ответом Джозефа Дикстры? (Object.keys(io.engine.clients) - person cyclingLinguist; 16.10.2015
comment
Это не работает в версии 1.4.5. Все еще работаю над решением - person Nuno Furtado; 09.02.2016
comment
TypeError: io.sockets.sockets.map не является функцией - person Király István; 18.05.2017

Сегодня я пережил эту боль. 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

person Thanh Nguyen    schedule 09.07.2015
comment
@ Зелёный Это сработает, если вы не используете пространство имен. Если вы используете пространство имен, измените его на io.server.eio.clientsCount - person Thanh Nguyen; 10.12.2015

Версия +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

person John Galt    schedule 04.08.2017
comment
есть ли способ просмотреть все объекты сокета? например, если я добавляю свойство socket.username к каждому сокету при подключении, есть ли способ просмотреть все эти объекты сокета (включая настраиваемые свойства, которые я добавляю к каждому сокету)? (для справки, в настоящее время я использую глобальную объектную переменную для хранения дополнительной информации о сокете при подключении клиента - поэтому не спрашивая, как это настроить - просто интересно узнать, есть ли способ просмотреть все объекты сокета по умолчанию) . - person user1063287; 07.06.2019
comment
хмм, согласно этому ответу, я думаю, вы можете видеть все подключенные сокеты с помощью console.log(io.sockets.connected) - похоже, это объект, где каждое значение свойства объект сокета, который содержит эти свойства nsp, server, adaptor, id (строка), client, conn, rooms, acks, connected, disconnected, handshake, fns, flags, _rooms, _events, _eventsCount и, наконец, username, которое является настраиваемым свойством добавляю в каждый сокет при подключении. - person user1063287; 07.06.2019

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

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.

person sunil n jose    schedule 08.11.2012
comment
какова цель client.on? Можете ли вы использовать свой код таким образом (прием данных только из 1 сокета) ?: io.sockets.sockets [sock_id] .on ('newmessage', function (data) {console.log (data)}); - person The Hawk; 28.11.2012

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

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

person ksloan    schedule 15.02.2015
comment
пожалуйста, позвольте мне поделиться этим примером, var room = io.sockets.adapter.rooms[room_id]; var connections = _.map(Object.keys(room), function(socketId){ return (io.sockets.connected[socketId].connected == true) }); - person Hany Alsamman; 17.11.2015

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

io.sockets.manager.server.connections

person crickeys    schedule 07.02.2012
comment
Разве количество подключенных клиентов не проверено. (немного больше) - person mrzmyr; 16.03.2012
comment
для точного подсчета используйте io.sockets.clients().length - person Ivo; 07.04.2013
comment
В настоящее время и io.sockets.manager.server.connections, и io.sockets.clients().length не работают. У меня это сработало - только для подсчета - io.engine.clientsCount и для списка клиентов - io.engine.clientsCount. С тех пор, как он оставался таким более 3 лет. Похоже на надежный способ получить информацию о подключении. (На основе ответа Джозефа Дикстры) - person Aswin Ramakrishnan; 13.06.2017

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

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

person Tiago Zamperini    schedule 11.02.2016

В 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
person KIA    schedule 08.08.2016
comment
Я подтверждаю, что это работает в версии 1.5.1 socket.io - person Sébastien; 18.11.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;
}
person MoleIsKing    schedule 22.02.2016
comment
но версия socket.io еще не 1.5! Сейчас 1.4.8 - person leszek.hanusz; 18.08.2016

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

var usersSocketIds = Object.keys(chat.adapter.rooms['room name']);
var usersAttending = _.map(usersSocketIds, function(socketClientId){ return chat.connected[socketClientId] })
person Coelhone    schedule 12.06.2015

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

person Alexandre Daubricourt    schedule 25.03.2017

Для версии 2.3 это работает, и вам также будет предоставлен сокет, мне кажется, что socketIo меняется слишком быстро и слишком много с плохо читаемой документацией после его использования в течение некоторого времени.

ioSite.of('/').in(roomId).clients((error, clients) => {
    if (error) throw error;
    for (var i=0;i<clients.length;i++) {
        clientId=clients[i];
        console.log(clientId);

        // load the socket of your namespace
        var socket=ioSite.of('/').in(roomId).connected[clientId]
        console.log(socket.constructor.name);
        console.log(socket.id);
    }
});

все же это кажется неправильным, так как у меня всегда такое чувство с сокетом Io как-то

person Joris Ceelen    schedule 08.08.2017

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

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

});

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

person Anuj Nautiyal    schedule 05.09.2017

[email protected]

 io.in('room1').sockets.sockets.forEach((socket,key)=>{
        console.log(socket);
    })

все экземпляры сокетов в room1

person Atila Pehlivan    schedule 21.12.2020

namespace.allSockets ()

Обещание возврата ‹Set›

io.allSockets() все идентификаторы подключенных сокетов в основном пространстве имен

io.in('room').allSockets() // все подключенные идентификаторы в 'комнате'

io.of('/namespace').allSockets() // все подключенные идентификаторы в '/ namespace' (вы также можете объединить это с комнатами)

person M. Emre Yalçın    schedule 25.03.2021
comment
Это работает как в Socket.IO v3.x, так и в v4.x. Если вы хотите получить фактические объекты Socket из набора идентификаторов, полученных от allSockets(), вы можете использовать io.of('/namespace').sockets для получения карты всех экземпляров Socket, подключенных к пространству имен, чтобы io.of('/namespace').sockets.get(socketId) получил экземпляр Socket, соответствующий идентификатору. - person Samuli Asmala; 26.03.2021

2021 Update V4.0+

Ни один из ответов не помог мне. Я избавлю тебя от боли. Их API и документация сильно изменились с 1.0.

Server Api все доступные параметры

Но вам нужно копать здесь

// return all Socket instances
var clients = io.sockets;

clients.sockets.forEach(function(data,counter){

//console.log(data);//maps

var socketid =  data.id;//log ids
var isConnected = data.connected//true,false;

});
person Grogu    schedule 13.07.2021

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

var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;
person Dan Steele    schedule 20.12.2011
comment
Ответ 3rdEden не сработал для меня, поскольку есть проблемы с массивом, возвращающим отключенных клиентов, что сбрасывает счет. Object.keys (io.manager.open) .length оказался самым надежным подсчетом по моему опыту. io.of ('/ namespace'). manager.open, если вы используете пространства имен. - person Wes Johnson; 16.04.2012

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

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

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

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

person Gus Ortiz    schedule 25.03.2015
comment
Я думаю, что можно избежать этого оператора if, если вы заставите клиента присоединиться к комнате после подключения к сокету. - person Chayemor; 25.11.2015
comment
Откуда myObj? Как вы пришли к такому значению? - person Michael Draper; 10.12.2015
comment
@MikeDraper myObject - это запись в базе данных, которая действует как канал. Это решает случай, когда вы хотите, чтобы все ваши клиенты обновлялись всякий раз, когда происходит изменение в базе данных, например, пользователь обновляет свое имя, и все подключенные клиенты получают обновление. Поэтому я создаю комнату для этого идентификатора экземпляра, учитывая, что он уникален (BSON). Это очень конкретное значение для моего варианта использования, поэтому извините, если я вызвал какую-то путаницу. Дайте мне знать, если вам понадобится помощь :) - person Gus Ortiz; 17.12.2015
comment
@JMR из-за характера моего приложения случилось так, что сокет подписывался более одного раза, поэтому мне пришлось добавить эту проверку. - person Gus Ortiz; 11.02.2016

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

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

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

person suncannon    schedule 12.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...
    }
});

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

person rppc    schedule 01.11.2016
comment
Этот работает. Пустая строка в io.of ('') работает без пространств имен. - person Király István; 18.05.2017
comment
@ KirályIstván Я давно не разбирался в этом, но думаю, что в этом случае вы можете полностью удалить of() связанный вызов. - person rppc; 18.05.2017

Если в проекте есть кластер socket.io, это означает, что используется адаптер socket.io-redis.

В случае, подобном описанному выше, процесс получения идентификатора всех подключенных сокетов должен быть применен через адаптер socket.io-redis. Для этого можно использовать приведенные ниже примеры;

io.of('/').adapter.clients(function (err, clients) {
  console.log("clients: ", clients); // an array containing all connected socket ids
});


io.of('/').adapter.allRooms(function (err, rooms) {
  console.log("all rooms: ", rooms);
});

Посетите страницу socket.io-redis на github для получения дополнительных сведений.

person efkan    schedule 29.03.2017

Вот быстрый способ преобразовать хэш подключенных сокетов из пространства имен в массив с помощью генераторов ES6 (применяется к socket.io> = v1.0.0):

io.on('connection', function(socket) {
  var hash = io.of('/').connected
  var list = null

  hash[Symbol.iterator] = function*() {
    // for..of loop to invoke Object.keys() default iterator
    // to get the array values instead of the keys
    for(var id of Object.keys(hash)) yield hash[id]
  }

  list = [...hash]
  console.log(Array.isArray(list)) // true
})
person Morgan    schedule 27.09.2015

Я не знаю, продолжается ли это до сих пор. Но что-то вроде этого я в итоге использовал (я сохраняю объект session на каждом подключенном сокете, который, в свою очередь, содержит имя пользователя и другую информацию:

var connectedUsers = Object.keys(io.sockets.connected).map(function(socketId) {
    return io.sockets.connected[socketId].session.username;
});
person diazd2    schedule 06.06.2016

[email protected]

Я использовал Object.Keys, чтобы подключить массив сокетов. Затем в том же массиве выполните итерацию с функцией карты, чтобы построить новый массив объектов.

var connectedUsers = Object.keys(io.sockets.connected).map(function(socketId) {
    return { socket_id : socketId, socket_username: io.sockets.connected[socketId].username };
});

// test
console.log(connectedUsers);

Возможно, этот ответ поможет получить массив идентификаторов сокетов / имен пользователей.

person jvaldezb    schedule 07.09.2018
comment
Привет, не могли бы вы объяснить на английском, как это решает проблему? Таким образом, это будет не просто ответ, состоящий только из кода. Спасибо! - person Max von Hippel; 07.09.2018

io.sockets.sockets.keys ()

Это мне помогает.

person g721    schedule 27.06.2021

для socket.io версии 4.0.0

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

function listSocketsProperty(myProperty){
  let sck = io.sockets.sockets
  const mapIter = sck.entries()
  while(1){
    let en = mapIter.next().value?.[0]
    if(en) console.log( sck.get(en)[myProperty] )
    else break
  }
}

Объяснение:

sck = io.sockets.sockets - это объект Map.

Метод Entries () возвращает новый объект Iterator, содержащий пары [ключ, значение] для каждого элемента в объекте Map.

ru = mapIter.next (). value?. [0] получает ключ - первый элемент пары.

Если повторять больше не нужно, en становится неопределенным, и это прерывает цикл while.

Пример:

У моих сокетов есть свойство playerName, и я хочу перечислить имена всех активных игроков во всех комнатах. Для этого я просто вызываю функцию:

listSocketsProperty('playerName')

и войдите в консоль примерно так:

John
Peter
Zoran
etc.
person Zoran    schedule 17.07.2021

person    schedule
comment
Было бы хорошо, если бы вы могли добавить контекст, почему «Это лучший способ» и как ваш ответ что-то добавляет ко всем многочисленным ответам, приведенным выше. Код - это что-то, но ответ тоже должен иметь какое-то объяснение. Как видите, на этот вопрос есть много других ответов. Ваш ответ должен привносить нечто большее в тему, иначе он будет лишним. - person Nathan Ripert; 02.10.2018
comment
С socket.io 2.1.1 я получаю TypeError: clients.map is not a function, и хотя это выглядит многообещающим, я не совсем уверен, чего будет достигать приведенный выше пример - я надеялся, что он автоматически создаст массив клиентских объектов с включенными именами пользователей :). - person user1063287; 22.11.2018