it-swarm.com.de

Socket.IO - Wie bekomme ich eine Liste der verbundenen Sockets/Clients?

Ich versuche, eine Liste aller derzeit verbundenen Sockets/Clients zu erhalten. 

io.sockets gibt leider kein Array zurück. 

Ich weiß, dass ich meine eigene Liste mit einem Array führen könnte, denke aber nicht, dass dies aus zwei Gründen eine optimale Lösung ist:

  1. Redundanz. Socket.IO behält bereits eine Kopie dieser Liste.

  2. Socket.IO bietet eine Methode zum Festlegen beliebiger Feldwerte für Clients (d. H .: socket.set('nickname', 'superman')). Wenn ich also meine eigene Liste pflegen möchte, muss ich mit diesen Änderungen Schritt halten.

Hilfe?

138
Andy Hin

In Socket.IO 0.7 haben Sie eine clients-Methode für die Namespaces. Diese gibt ein Array aller verbundenen Sockets zurück.

API für keinen Namespace:

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

Für einen Namespace

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

Hoffen wir, dass dies in der Zukunft jemandem hilft

HINWEIS: Diese LösungONLYfunktioniert mit einer Version vor 1.0

158
3rdEden

Socket.io 1.4

Object.keys(io.sockets.sockets); gibt Ihnen alle angeschlossenen Steckdosen.

Socket.io 1.0 Ab Socket.io 1.0 ist die tatsächlich akzeptierte Antwort nicht mehr gültig . Daher habe ich eine kleine Funktion erstellt, die ich als temporäre Lösung verwende:

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

Die API für Kein Namespace wird zu 

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

Die API für ein Namespace wird zu:

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

Siehe auch diese bezogene Frage , in der ich eine Funktion gebe, die die Steckdosen für einen bestimmten Raum zurückgibt.

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 für kein Namespace:

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

Für ein Namespace

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

Note: Da die socket.io-API anscheinend zu brechen neigt und einige Lösungen auf Implementierungsdetails angewiesen sind, könnte es eine Frage der Nachverfolgung der Clients selbst sein:

var clients = [];

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

    client.on('disconnect', function() {
        clients.splice(clients.indexOf(client), 1);
    });
});
91
nha

Nach socket.io 1.0 können wir nicht mehr verwenden 

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

nicht mehr. Stattdessen können Sie Folgendes verwenden 

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
}
45
salihcenap

Socket.IO 1.x verwenden:

Holen Sie sich ein Array der verbundenen Clients:

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

Rufen Sie die Anzahl der verbundenen Clients ab:

io.engine.clientsCount // => 2
io.eio.clientsCount    // => 2
32
Joseph Dykstra

Sehr einfach in socket.io 1.3:

io.sockets.sockets - ist ein Array, das die verbundenen Socketobjekte enthält. Wenn Sie den Benutzernamen in jedem Socket gespeichert haben, können Sie

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

Boom. Sie haben die Namen aller verbundenen Benutzer. 

30
or29544

Ich habe diesen Schmerz heute durchgemacht. Socket.io ist viel besser, wenn sie eine geeignete Dokumentation für ihre API erstellen könnten.

Wie auch immer, ich habe versucht, in io.sockets nachzuschauen und habe eine Reihe von Optionen gefunden, die wir verwenden können:

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

Beachten Sie außerdem, dass bei Verwendung von socket.io mit Namespace die oben genannten Methoden beschädigt werden, da io.sockets ein Array anstelle eines Objekts wird. Um das Problem zu beheben, ersetzen Sie einfach io.sockets durch io (d. H. Io.sockets.connected wird zu io.connected, io.sockets.adapter.rooms wird zu io.adapter.rooms ...).

Getestet auf socket.io 1.3.5

21
Thanh Nguyen

Ich denke, wir können vom Server aus auf das Socket-Objekt zugreifen, und Sie können den Kurznamen zuweisen und seine Socket-ID verweisen.

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

Entfernen Sie bei disconnect den Spitznamen aus io.sockets.sockets.

17
sunil n jose

Dies ist der beste Weg, um in socket.io 1.3 darauf zuzugreifen

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

9
ksloan

Version + 2.0

In Version +2.0 geben Sie den Namespace/Raum/Knoten an, gegen den Sie abfragen.

Wie beim Broadcasting werden standardmäßig alle Clients aus dem Standard-Namespace ('/') verwendet:

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

Ruft eine Liste von Client-IDs ab, die mit einem bestimmten Namespace verbunden sind (ggf. über alle Knoten hinweg).

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

Ein Beispiel, um alle Clients im Raum des Namespaces zu erhalten:

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

Dies ist aus der offiziellen Dokumentation: Socket.IO Server-API

7
John Galt

Für jeden, der nur einen COUNT der verbundenen Clients möchte, glaube ich, dass dies der Fall ist:

io.sockets.manager.server.connections

5
crickeys

Socket.io 1.4.4

Beispielcode für Sie.

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

Ich denke, jemandem wird dieser Codeblock helfen.

4
Tiago Zamperini

In Socket.IO 1.4 

So rufen Sie das Array aller verbundenen Benutzer ab:

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

Um die Anzahl aller Kunden zu ermitteln:

var clientsCount = io.engine.clientsCount ; // This will return the count of connected clients
4
KIA

Beachten Sie ab Socket.io 1.5 die Änderung von indexOf, die abgeschrieben erscheint und durch valueOf ersetzt wird

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

Für Socket.io Version 2.0.3 funktioniert der folgende Code:

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
MoleIsKing

auf socket.io 1.3 habe ich dies in zwei zeilen erreicht

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

Socket.io 1.7.3 (+):

 Funktion getConnectedList () 
 {
 let list = [] 

 for (lassen Sie den Client in io.sockets.connected) 
 {
 list.Push (Client) 
 } 

 return list 
} 

 console.log (getConnectedList ()) 

 // gibt ['yIfhb2tw7mxgrnF6AAAA', 'qABFaNDSYknCysbgAAAB'] .______ zurück.

Verwenden Sie für den Cluster-Modus den Redis-Adapter 

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

});

Da jede Steckdose selbst ein Raum ist, kann man feststellen, ob eine Steckdose existiert.

1
Anuj Nautiyal

Dies ist der einfachste Weg in Socket.IO 1.0+, wenn Sie keine Namespaces oder Räume verwenden.

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

Dies betrachtet den Standard-Namespace und bestimmt die Länge des Sockets-Arrays, ohne Object.keys() verwenden zu müssen

1
suncannon

Für Version 2.3 funktioniert das und es wird dir auch die Socket bringen , es scheint mir, dass sich socketIo zu schnell und zu wenig mit zu wenig lesbarer Dokumentation ändert, nachdem es eine Weile verwendet wurde. 

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

trotzdem fühlt sich das nicht richtig an, da ich irgendwie immer dieses Gefühl mit Steckdose habe

1
Joris Ceelen

Seit Version 1.5.1 kann ich auf alle Sockets in einem Namespace zugreifen mit:

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

Aus irgendeinem Grund verwenden sie ein einfaches Objekt anstelle eines Arrays, um die Socket-IDs zu speichern.

1
rppc

Ich sehe hier viele gute Antworten und viele waren sehr nützlich, aber nicht ganz das, was ich brauchte. Ich verwende Sockets für eine Pubsub-Funktion, bei der ein interessierter Kunde alle Änderungen in einem bestimmten Datensatz abhören kann.

Mein spezielles Problem war, dass dieselbe Steckdose mehrmals in denselben Raum trat. Die Lösung für dieses Problem bestand darin, zu überprüfen, ob die Steckdose das Zimmer bereits in ihrem Zimmer hatte.

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

Hoffe das hilft jemandem.

1
Gus Ortiz

Ich glaube, dass Sie über die Manager-Eigenschaft des Sockets darauf zugreifen können?

var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;
1
Dan Steele

Wenn das Projekt über einen socket.io -Cluster verfügt, wird der Adapter socket.io-redis verwendet.

In diesem Fall muss das Abrufen aller ID-Prozesse für alle verbundenen Sockets über den Adapter socket.io-redis erfolgen. Die folgenden Beispiele können hierfür verwendet werden.

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

Bitte besuchen Sie die socket.io-redis Github-Seite für weitere Details.

0
efkan

v.10

var clients = io.nsps['/'].adapter.rooms['vse'];
/* 
'clients' will return something like:
Room {
sockets: { '3kiMNO8xwKMOtj3zAAAC': true, FUgvilj2VoJWB196AAAD: true },
length: 2 }
*/
var count = clients.length;  // 2
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
Ark Iv

[email protected]

Ich habe Object.Keys verwendet, um das Array von Socket anzuschließen. Dann im gleichen Array mit Map-Funktion iterieren, um ein neues Array von Objekten zu erstellen 

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

Vielleicht kann diese Antwort helfen, ein Socket-ID/Benutzername-Array zu erhalten.

0
jvaldezb

Ich weiß nicht, ob das noch läuft. Aber so etwas habe ich am Ende verwendet (ich halte ein sessionobject auf jedem verbundenen Socket, der wiederum den Benutzernamen und andere Informationen enthält:

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

Hier ist eine schnelle Methode zum Konvertieren des Hashes verbundener Sockets aus einem Namespace in ein Array mit ES6-Generatoren (gilt für 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
Morgan