Socket.IO-Comment puis-je obtenir une liste de sockets/clients connectés?

j'essaie d'obtenir une liste de tous les sockets/clients qui sont actuellement connectés.

io.sockets ne renvoie pas de tableau, malheureusement.

je sais que je pourrais garder ma propre liste en utilisant un tableau, mais ne pensez pas que c'est une solution optimale pour 2 raisons:

  1. redondance. Socket.IO conserve déjà une copie de cette liste.

  2. Socket.IO fournit méthode pour définir des valeurs de champ arbitraires pour les clients(I. e: socket.set('nickname', 'superman') ) donc j'aurais besoin de suivre ces changements si je devais maintenir ma propre liste.

de l'Aide?

135
demandé sur franzlorenzon 2011-07-03 19:58:05

27 réponses

Dans Socket.IO 0.7 vous avez une méthode clients sur les espaces de noms, cela renvoie un tableau de toutes les sockets connectés.

API pour no namespace:

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

pour un espace de noms

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

espère que cela aidera quelqu'un dans le futur

NOTE: Cette Solution SEULEMENT fonctionne avec une version antérieure à la version 1.0

151
répondu 3rdEden 2015-04-24 07:09:18

Socket.io 1.4

Object.keys(io.sockets.sockets); vous donne tous les sockets connectés.

Socket.io 1,0 As of socket.io 1.0, la réponse acceptée n'est plus valide. J'ai donc créé une petite fonction que j'utilise comme solution temporaire:

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 pour No namespace devient

// 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 pour a namespace devient:

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

Voir Aussi cette question connexe , dans laquelle je donne une fonction qui retourne les sockets pour une pièce Donnée.

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 pour no namespace :

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

Pour un espace de noms

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

Note: Puisqu'il semble la prise.IO API est enclin à la rupture, et certaines solutions reposent sur les détails de mise en œuvre, il pourrait s'agir de suivre les clients vous-même:

var clients = [];

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

    client.on('disconnect', function() {
        clients.splice(clients.indexOf(client), 1);
    });
});
89
répondu nha 2017-05-23 12:34:54

après douille.io 1.0 nous ne pouvons pas utiliser

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

plus. À la place, vous pouvez utiliser le

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
répondu salihcenap 2014-06-08 11:48:30

Utilisant Socket.IO 1.x:

Obtenir le tableau des clients connectés:

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

obtenir le nombre de clients connectés:

io.engine.clientsCount // => 2
io.eio.clientsCount    // => 2
31
répondu Joseph Dykstra 2015-12-10 21:53:28

très simple dans socket.io 1.3:

io.sockets.sockets - est un tableau contenant les objets de socket connectés. Si vous avez stocké le nom d'utilisateur dans chaque socket, vous pouvez faire:

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

Boom. Vous avez les noms de tous les utilisateurs connectés.

30
répondu or29544 2015-03-01 11:58:24

j'ai eu mal aujourd'hui. Socket.io sera beaucoup mieux s'ils peuvent faire une documentation appropriée pour leur API.

quoi qu'il en soit, j'ai essayé d'enquêter sur io.les sockets et trouvé un certain nombre d'options que vous pouvez utiliser:

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

Aussi, notez que lors de l'utilisation de socket.io avec l'espace de noms, les méthodes ci-dessus va casser depuis io.sockets devient un tableau au lieu d'un objet. Pour résoudre, il suffit de remplacer io.sockets by io (I. e io.socket.connecter devient io.connecté, io.socket.adaptateur.les chambres deviennent io.adaptateur.chambre. ..)

testé sur socket.151920920"

19
répondu Thanh Nguyen 2015-07-19 12:33:56

je pense que nous pouvons accéder à l'objet socket depuis le serveur, et vous pouvez assigner le surnom, et pointer son ID de 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");
    });    
});

sur disconnect veuillez supprimer le surnom de io.sockets.sockets .

17
répondu sunil n jose 2013-05-27 11:33:57

C'est la meilleure façon d'y accéder en socket.io 1.3

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

9
répondu ksloan 2015-11-18 17:58:58

pour quiconque veut juste un compte des clients connectés je crois que cela le fera:

io.sockets.manager.server.connections

4
répondu crickeys 2012-02-07 19:02:03

Socket.io 1.4.4

exemple de code pour vous.

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

je pense que ça va aider quelqu'un à bloquer ce code.

4
répondu Tiago Zamperini 2016-02-11 17:07:48

Version + 2.0

dans la version +2.0 vous spécifiez le namespace/room/node que vous cherchez.

comme pour la radiodiffusion, la valeur par défaut est tous les clients de l'espace de noms par défaut ('/'):

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

obtient une liste des identifiants de clients connectés à un espace de noms spécifique (à travers tous les noeuds le cas échéant).

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

un exemple pour obtenez tous les clients dans la chambre de namespace:

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

C'est de la documentation officielle: Socket.IO Server-API

4
répondu John Galt 2017-08-04 15:58:24

Dans Socket.IO 1.4

pour obtenir le tableau de tous les utilisateurs connectés:

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

pour obtenir le compte de tous les clients:

var clientsCount = io.engine.clientsCount ; // This will return the count of connected clients
3
répondu KIA 2016-08-08 08:53:44

comme prise.io 1.5, note dont la variation par rapport à l'indice paraît dépréciée, et remplacée par la valeur de 151930920"

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

pour douille.io version 2.0.3, le code suivant fonctionne:

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
répondu MoleIsKing 2017-11-02 09:02:38

sur la socket.io 1.3, j'ai accompli cela en 2 lignes

var usersSocketIds = Object.keys(chat.adapter.rooms['room name']);
var usersAttending = _.map(usersSocketIds, function(socketClientId){ return chat.connected[socketClientId] })
2
répondu Coelhone 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
répondu Alexandre Daubricourt 2017-03-25 13:35:19

je crois que vous pouvez accéder à cela à partir de la propriété gestionnaire de la socket?

var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;
1
répondu Dan Steele 2011-12-20 14:50:59

je vois beaucoup de bonnes réponses ici et beaucoup d'où, très utile, mais pas tout à fait ce dont j'avais besoin. J'utilise des sockets pour une fonction pubsub dans laquelle un client intéressé peut écouter toute modification d'un enregistrement donné.

mon problème spécifique était que la même prise rejoignait la même pièce Plusieurs fois. La solution à cela était de vérifier si la prise avait déjà la pièce à l'intérieur de sa propriété Chambres.

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

J'espère que ça aidera quelqu'un.

1
répondu Gus Ortiz 2015-03-25 18:24:01

depuis la version 1.5.1, je peux accéder à toutes les sockets dans un espace de noms avec:

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

pour une raison inconnue, ils utilisent un objet simple au lieu d'un tableau pour stocker les ID de socket.

1
répondu rppc 2016-11-01 02:08:23

pour la version 2.3 cela fonctionne et vous obtiendrez le socket trop , il me semble que socketIo change trop vite et à beaucoup avec peu de documentation lisible après l'avoir utilisé pendant un certain temps.

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

cela ne me semble pas juste, comme j'ai toujours ce sentiment avec socket Io d'une certaine façon

1
répondu Joris Ceelen 2017-08-08 07:04:47

pour le mode cluster, en utilisant l'adaptateur redis

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

});

comme chaque socket est lui-même une pièce, donc on peut trouver si une socket existe en utilisant le même.

1
répondu Anuj Nautiyal 2017-09-05 15:09:23

voici un moyen rapide de convertir le hachage des sockets connectés à partir d'un espace de nom en un tableau en utilisant des générateurs ES6 (s'applique à la 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
répondu Morgan 2015-09-27 19:08:05

C'est le moyen le plus simple dans Socket.IO 1.0+, si vous n'utilisez pas d'espaces de noms ou de chambres.

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

cela regarde l'espace de noms par défaut et détermine la longueur du réseau de sockets, sans avoir besoin d'utiliser Object.keys()

0
répondu suncannon 2016-01-12 18:34:23

Je ne sais pas si ça continue. Mais quelque chose comme ça c'est ce que j'ai fini par utiliser (je garde un objet session sur chaque socket connecté, qui à son tour contient le nom d'utilisateur et d'autres informations:

var connectedUsers = Object.keys(io.sockets.connected).map(function(socketId) {
    return io.sockets.connected[socketId].session.username;
});
0
répondu diazd2 2016-06-06 22:28:43

si le projet a une prise .io cluster this means socket.l'adaptateur io-redis est utilisé.

si le cas comme ci-dessus, obtenir le processus d'identification de toutes les sockets connectés doit être appliqué via socket.io-redis adaptateur. Les exemples ci-dessous peuvent être utilisés à cet effet;

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

s'il vous Plaît visitez socket.io-redis github page pour plus de détails.

0
répondu efkan 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
répondu Dor 2018-02-22 14:12:42

socket.io@1.7.3

j'ai utilisé L'objet.Touches pour connecter le tableau de socket. Puis dans le même tableau itèrent avec la fonction de carte pour construire un nouveau tableau d'objets

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

peut-être que cette réponse peut aider à obtenir le tableau socket id/username.

0
répondu jvaldezb 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
répondu Ark Iv 2018-10-02 10:43:28