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:
-
redondance. Socket.IO conserve déjà une copie de cette liste.
-
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?
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
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);
});
});
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
}
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
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.
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"
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
.
C'est la meilleure façon d'y accéder en socket.io 1.3
Object.keys(socket.adapter.rooms[room_id])
pour quiconque veut juste un compte des clients connectés je crois que cela le fera:
io.sockets.manager.server.connections
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.
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
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
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;
}
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] })
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' ]
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;
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.
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.
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
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.
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
})
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()
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;
});
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.
var Client = require("socket.io").listen(8888); //port listening
//This is the best way.
var connection = Client.engine.clientsCount
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.
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.