現在接続されているすべてのソケット/クライアントのリストを取得しようとしています。
残念ながら、io.sockets
は配列を返しません。
私は配列を使用して自分のリストを保持できることを知っていますが、これが2つの理由で最適なソリューションだとは思わない:
冗長性。 Socket.IOはすでにこのリストのコピーを保持しています。
Socket.IOは、クライアントに任意のフィールド値を設定するメソッドを提供します(つまり、socket.set('nickname', 'superman')
)。したがって、自分のリストを維持する場合は、これらの変更に対応する必要があります。
助けて?
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より前のバージョンで動作します
Socket.io 1.4
Object.keys(io.sockets.sockets);
は、接続されたすべてのソケットを提供します。
Socket.io 1.0socket.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 forNo namespaceは
// 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 fora namespaceは次のようになります:
// 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`
a名前空間の場合
var clients = io.of('/chat').clients();
var clients = io.of('/chat').clients('room'); // all users from room `room`
注:socket.io APIは壊れやすい傾向があり、一部のソリューションは実装の詳細に依存しているため、クライアントを追跡する問題になる可能性がありますあなた自身:
var clients = [];
io.sockets.on('connect', function(client) {
clients.Push(client);
client.on('disconnect', function() {
clients.splice(clients.indexOf(client), 1);
});
});
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
}
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
Socket.io 1.3では非常に簡単です:
io.sockets.sockets
-接続されたソケットオブジェクトを含む配列です。ユーザー名を各ソケットに保存した場合、次のことができます。
io.sockets.sockets.map(function(e) {
return e.username;
})
ブーム。すべての接続ユーザーの名前があります。
今日、この痛みを経験しました。 APIの適切なドキュメントを作成できれば、Socket.ioの方がはるかに優れています。
とにかく、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でテスト済み
サーバーからソケットオブジェクトにアクセスでき、ニックネームを割り当ててそのソケットIDを指定できると思います。
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
からニックネームを削除してください。
バージョン+2.0では、クエリ対象のネームスペース/ルーム/ノードを指定します。
ブロードキャストと同様に、デフォルトはデフォルトのネームスペース( '/')からのすべてのクライアントです:
const io = require('socket.io')();
io.clients((error, clients) => {
if (error) throw error;
console.log(clients); // => [6em3d4TJP8Et9EMNAAAA, G5p55dHhGgUnLUctAAAB]
});
特定のネームスペースに接続されているクライアントIDのリストを取得します(該当する場合、すべてのノード間で)。
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
これは、socket.io 1.3でアクセスする最良の方法です。
Object.keys(socket.adapter.rooms[room_id])
接続されたクライアントのCOUNTだけが必要な場合は、これでうまくいくと思います。
io.sockets.manager.server.connections
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;
});
}
このコードブロックを誰かに役立つと思います。
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
Socket.io 1.5以降、減価償却され、valueOfに置き換えられたindexOfからの変更に注意してください。
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;
}
socket.io 1.3で2行でこれを達成しました
var usersSocketIds = Object.keys(chat.adapter.rooms['room name']);
var usersAttending = _.map(usersSocketIds, function(socketClientId){ return chat.connected[socketClientId] })
function getConnectedList() { let list = [] for(io.sockets.connectedのクライアントを許可) { list.Push(client) } return list } console.log (getConnectedList()) // [[yIfhb2tw7mxgrnF6AAAA '、' qABFaNDSYknCysbgAAAB '] を返します
Redis-adaptorを使用したクラスターモードの場合
io.in(<room>).clients(function(err, clients) {
});
各ソケット自体が部屋であるため、同じソケットを使用してソケットが存在するかどうかを確認できます。
これは、名前空間またはルームを使用していない場合、Socket.IO 1.0+で最も簡単な方法です。
io.nsps["/"].sockets.length
これは、デフォルトの名前空間を見て、Object.keys()
を使用せずにソケット配列の長さを決定します
バージョン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で常にこの感覚を持っているからです。
バージョン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...
}
});
何らかの理由で、ソケットIDを格納するために配列ではなくプレーンオブジェクトを使用しています。
ここには多くの良い答えがあり、非常に役に立つが私が必要とするものではないものがたくさんあります。関心のあるクライアントが特定のレコードの変更をリッスンできるpubsub機能にソケットを使用しています。
私の特定の問題は、同じソケットが同じ部屋に数回参加していることでした。これに対する解決策は、ソケットの部屋プロパティ内に既に部屋があるかどうかを確認することでした。
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");
}
これが誰かを助けることを願っています。
ソケットのmanagerプロパティからこれにアクセスできると思いますか?
var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;
プロジェクトにsocket.ioクラスターがある場合、これはsocket.io-redisアダプタが使用されています。
上記のような場合、すべての接続されたソケットIDプロセスの取得は、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 page をご覧ください。
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.
Object.Keysを使用して、接続されたソケットの配列を取得しました。次に、同じ配列内でmap関数を反復処理して、オブジェクトの新しい配列を作成します
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);
おそらく、この答えはソケットID /ユーザー名配列を取得するのに役立つでしょう。
これがまだ進行中かどうかはわかりません。しかし、このようなものは私が最終的に使用したものです(接続された各ソケットにsessionオブジェクトを保持し、これにはユーザー名と他の情報が含まれます:
var connectedUsers = Object.keys(io.sockets.connected).map(function(socketId) {
return io.sockets.connected[socketId].session.username;
});
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
})