Socket.IO -jak uzyskać listę podłączonych gniazd / klientów?

Próbuję uzyskać listę wszystkich gniazd / klientów, które są obecnie podłączone.

io.sockets niestety nie zwraca tablicy.

Wiem, że mógłbym zachować własną listę używając tablicy, ale nie sądzę, że jest to optymalne rozwiązanie z 2 powodów:

  1. Redundancja. Socket.IO przechowuje kopię tej listy.

  2. Socket.IO zapewnia metodę ustawiania dowolnych wartości pól dla klientów (tj.: socket.set('nickname', 'superman')), więc muszę nadążyć za tymi zmianami, jeśli miałem prowadzić własną listę.

Pomocy?
Author: franzlorenzon, 2011-07-03

27 answers

W Socket.IO 0.7 w przestrzeni nazw znajduje się Metoda clients, która zwraca tablicę wszystkich podłączonych gniazd.

API dla bez przestrzeni nazw:

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

Dla przestrzeni nazw

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

Nadzieję, że to pomoże komuś w przyszłości

Uwaga: To rozwiązanie tylko Działa z wersją wcześniejszą niż 1.0

 151
Author: 3rdEden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-24 07:09:18

Socket.io 1.4

Object.keys(io.sockets.sockets); daje wszystkie podłączone gniazda.

Socket.io 1.0 Od socket.io 1.0, rzeczywista zaakceptowana odpowiedź nie jest już ważna. Więc zrobiłem małą funkcję, której używam jako tymczasowej poprawki:

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 dla brak przestrzeni nazw staje się

// 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 dla przestrzeń nazw staje się:

// 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');

Zobacz także topodobne pytanie , w którym podaję funkcję, która zwraca gniazda dla miejsce.

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 dla brak przestrzeni nazw:

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

Dla przestrzeni nazw

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

Uwaga: ponieważ wydaje się, że socket.io API jest podatne na łamanie, a niektóre rozwiązania polegają na szczegółach implementacji, może to być kwestia śledzenia klientów samodzielnie: [11]}

var clients = [];

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

    client.on('disconnect', function() {
        clients.splice(clients.indexOf(client), 1);
    });
});
 89
Author: nha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:54

Po socket.io 1.0 nie możemy używać

io.sockets.clients(); 
or
io.sockets.clients('room'); 
/ Align = "left" / Zamiast tego możesz użyć następującego
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
}
 44
Author: salihcenap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-08 11:48:30

Za Pomocą Socket.IO 1.x:

Get array of the connected clients:

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

Uzyskaj liczbę podłączonych klientów:

io.engine.clientsCount // => 2
io.eio.clientsCount    // => 2
 31
Author: Joseph Dykstra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-10 21:53:28

Bardzo proste w socket.io 1.3:

io.sockets.sockets - jest tablicą zawierającą podłączone obiekty gniazd. Jeśli zapisałeś nazwę użytkownika w każdym gnieździe, możesz to zrobić:

io.sockets.sockets.map(function(e) {
    return e.username;
})
Boom. Masz nazwy wszystkich połączonych użytkowników.
 30
Author: or29544,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-01 11:58:24

Przeszłam dziś przez ten ból. Socket.io będzie znacznie lepiej, jeśli będą mogli zrobić odpowiednią dokumentację dla swojego API.

W każdym razie, próbowałem przyjrzeć się io.gniazda i znaleźliśmy kilka opcji, z których możemy skorzystać:
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

Należy również pamiętać, że przy użyciu socket.io w przestrzeni nazw, powyższe metody zostaną przerwane od io.sockets staje się tablicą zamiast obiektem. Aby rozwiązać problem, wystarczy wymienić io.gniazda przez io (tj. io.gniazda.połączony staje się io.połączone, io.gniazda.adapter.pokoje staje się io.adapter.pokoje ...)

Testowane na socket.io 1.3.5

 19
Author: Thanh Nguyen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-19 12:33:56

Myślę, że możemy uzyskać dostęp do obiektu socket z serwera, i można przypisać Nick, i wskazać jego id socket,

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

Na disconnect proszę usunąć nick z io.sockets.sockets.

 17
Author: sunil n jose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 11:33:57

Jest to najlepszy sposób, aby uzyskać do niego dostęp w socket.io 1.3

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

 9
Author: ksloan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-18 17:58:58

Dla każdego, kto chce tylko liczyć podłączonych klientów wierzę, że to wystarczy:

io.sockets.manager.server.connections

 4
Author: crickeys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-07 19:02:03

Socket.io 1.4.4

Przykładowy kod dla Ciebie.

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

Myślę, że pomoże komuś ten blok kodu.

 4
Author: Tiago Zamperini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-11 17:07:48

Wersja +2.0

W wersji +2.0 określasz przestrzeń nazw / pokój / węzeł, z którym pytasz.

Podobnie jak w przypadku nadawania, domyślnie są to wszyscy klienci z domyślnej przestrzeni nazw ('/'):

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

Pobiera listę identyfikatorów klientów podłączonych do określonej przestrzeni nazw (we wszystkich węzłach, jeśli dotyczy).

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

Przykład, aby uzyskać wszystkich klientów w pokoju przestrzeni nazw:

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

To z oficjalnej dokumentacji: Socket.IO Server-API

 4
Author: John Galt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-04 15:58:24

W Socket.IO 1.4

Aby uzyskać tablicę wszystkich podłączonych użytkowników:

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

Aby uzyskać liczbę wszystkich klientów:

var clientsCount = io.engine.clientsCount ; // This will return the count of connected clients
 3
Author: KIA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 08:53:44

Od socket.io 1.5, zwróć uwagę na zmianę z indexOf, która wydaje się zdeprecjonowana i zastąpiona przez 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;
}

Dla socket.io Wersja 2.0.3, działa następujący kod:

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;
}
 3
Author: MoleIsKing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-02 09:02:38

On socket.io 1.3 udało mi się to osiągnąć w 2 liniach

var usersSocketIds = Object.keys(chat.adapter.rooms['room name']);
var usersAttending = _.map(usersSocketIds, function(socketClientId){ return chat.connected[socketClientId] })
 2
Author: Coelhone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 22:15:04

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
Author: Alexandre Daubricourt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-25 13:35:19

Wydaje mi się, że ma Pan do tego dostęp z posesji zarządcy gniazda?

var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;
 1
Author: Dan Steele,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-20 14:50:59

Widzę tu wiele dobrych odpowiedzi i wiele przydatnych, ale nie do końca tego, czego potrzebowałem. Używam gniazd do funkcji pubsub, w której zainteresowany klient może odsłuchać wszelkie zmiany w danej płycie.

Mój szczególny problem polegał na tym, że to samo gniazdo łączyło się z tym samym pokojem kilka razy. Rozwiązaniem było sprawdzenie, czy gniazdo miało już pomieszczenie wewnątrz pomieszczeń.
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");
}
Mam nadzieję, że to komuś pomoże.
 1
Author: Gus Ortiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-25 18:24:01

Od wersji 1.5.1, jestem w stanie uzyskać dostęp do wszystkich gniazd w przestrzeni nazw za pomocą:

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

Z jakiegoś powodu używają zwykłego obiektu zamiast tablicy do przechowywania identyfikatorów gniazd.

 1
Author: rppc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-01 02:08:23

Dla wersji 2.3 to działa i to będzie Ci Gniazdo zbyt , wydaje mi się, że socketIo zmienia się zbyt szybko i do dużo Z do mało czytelnej dokumentacji po użyciu go na chwilę.

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

Nadal nie czuję się dobrze, ponieważ zawsze mam to uczucie z socket Io jakoś

 1
Author: Joris Ceelen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-08 07:04:47

Dla trybu klastra, przy użyciu redis-adaptera

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

});

Ponieważ każde gniazdo jest pokojem, więc można stwierdzić, czy gniazdo istnieje używając tego samego.

 1
Author: Anuj Nautiyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-05 15:09:23

Oto szybki sposób na konwersję hash podłączonych gniazd z przestrzeni nazw na tablicę przy użyciu generatorów ES6 (dotyczy 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
})
 0
Author: Morgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-27 19:08:05

Jest to najprostszy sposób w Socket.IO 1.0+, Jeśli nie używasz przestrzeni nazw lub pokoi.

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

Sprawdza domyślną przestrzeń nazw i określa długość tablicy gniazd, bez konieczności używania Object.keys()

 0
Author: suncannon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-12 18:34:23

Nie wiem, czy to nadal trwa. Ale coś takiego jest tym, czego użyłem (trzymam obiekt session na każdym podłączonym gnieździe, który z kolei zawiera nazwę użytkownika i inne informacje:

var connectedUsers = Object.keys(io.sockets.connected).map(function(socketId) {
    return io.sockets.connected[socketId].session.username;
});
 0
Author: diazd2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-06 22:28:43

Jeśli projekt ma socket.io Klaster oznacza to, że używany jest adapter socket.io-redis .

W przypadku takim jak powyżej, uzyskanie identyfikatora wszystkich podłączonych gniazd musi być zastosowane przez adapter socket.io-redis. Poniższe przykłady mogą być użyte w tym celu;

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);
});
Po więcej szczegółów odwiedź stronę socket.io-redis github .
 0
Author: efkan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-29 08:09:54
var Client = require("socket.io").listen(8888); //port listening

//This is the best way.

var connection = Client.engine.clientsCount
 0
Author: Dor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 14:12:42

[email protected]

Użyłem obiektu.Klucze do podłączenia tablicy gniazd. Następnie w tej samej tablicy iteruj z funkcją map, aby zbudować nową tablicę obiektów

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

Być może ta odpowiedź pomoże uzyskać tablicę socket id/username.

 0
Author: jvaldezb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-07 02:12:04

V. 10

var clients = io.nsps['/'].adapter.rooms['vse'];
var count = clients.length;  // count
var sockets = clients.map((item)=>{  // all sockets room 'vse'
       return io.sockets.sockets[item];
      });
sample >>>
var handshake  = sockets[i].handshake; 
handshake.address  .time .issued ... etc.
 0
Author: Ark Iv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 10:43:28