code

소켓에 연결된 소켓/클라이언트 목록을 가져오려면 어떻게 해야 합니까?IO?

starcafe 2023. 7. 27. 22:10
반응형

소켓에 연결된 소켓/클라이언트 목록을 가져오려면 어떻게 해야 합니까?IO?

현재 연결된 모든 소켓/클라이언트 목록을 가져오려고 합니다.

io.sockets안타깝게도 배열을 반환하지 않습니다.

어레이를 사용하여 자신의 목록을 유지할 수 있다는 것은 알고 있지만, 다음 두 가지 이유로 인해 최적의 솔루션이 아니라고 생각합니다.

  1. 이중화.소켓.IO에서 이미 이 목록의 복사본을 보관하고 있습니다.

  2. Socket는 클라이언트 Socket)에 합니다.IO는 클라이언트에 대한 임의 필드 값을 설정하는 메서드를 제공합니다(예:socket.set('nickname', 'superman')), 내가 나는 가 있을 입니다.), 그서만약제제목유을다면한지, 저이변을따할야다것니입라.

어떻게 해야 하나?

소켓에 있습니다. 0 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 이전 버전에서만 작동합니다.

1.x 이상부터는 socket.io 의 채팅방에 몇 명이 있는지 확인하시기 바랍니다.

소켓.IO 1.4

Object.keys(io.sockets.sockets);연결된 소켓을 모두 제공합니다.

소켓.IO 1.0

소켓 기준.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는 다음과 같습니다.

// 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는 다음과 같습니다.

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

소켓.IO 0.7

네임스페이스가 없는 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`

참고: 소켓으로 보이기 때문입니다.IO API는 손상되기 쉬우며 일부 솔루션은 구현 세부 정보에 의존하기 때문에 클라이언트를 직접 추적해야 할 수 있습니다.

var clients = [];

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

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

소켓 이후.IO 1.0, 사용할 수 없습니다.

io.sockets.clients();

또는

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
}

소켓 사용.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

소켓에서는 매우 간단합니다.IO 1.3:

io.sockets.sockets는 연결된 소켓 개체를 포함하는 배열입니다.

각 소켓에 사용자 이름을 저장한 경우 다음 작업을 수행할 수 있습니다.

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

쾅. 연결된 모든 사용자의 이름이 있습니다.

저는 오늘 이 고통을 겪었습니다.소켓.그들이 API에 대한 적절한 문서를 만들 수 있다면 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.message가 개체가 아닌 배열이 되므로 위의 메서드는 중단됩니다.확인하려면 io.socketsio바꾸기만 하면 됩니다(즉, io.sockets.connected는 io.connected되고, io.sockets.adapter.rooms는 io.adapter.rooms가 됩니다...).

소켓에서 테스트했습니다.IO 1.3.5.

버전 2.x

버전 2.x에서는 쿼리할 네임스페이스/룸/노드를 지정합니다.

브로드캐스팅과 마찬가지로 기본값은 기본 네임스페이스('/')의 모든 클라이언트입니다.

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

다음은 공식 문서의 내용입니다.소켓.IO 서버-API

소켓을 업데이트합니다.IO v4.0+(2022년 11월 6일 마지막 확인)

다른 답들은 다 시도해봤어요다음을 제외하고는 아무 것도 작동하지 않았습니다.

연결된 모든 소켓을 연결하는 가장 쉬운 방법은 다음과 같습니다.

await io.fetchSockets()

연결된 모든 소켓의 배열을 반환합니다.

문서화

// Return all Socket instances
const sockets = await io.fetchSockets();

// Return all Socket instances in the "room1" room of the main namespace
const sockets = await io.in("room1").fetchSockets();

// Return all Socket instances in the "room1" room of the "admin" namespace
const sockets = await io.of("/admin").in("room1").fetchSockets();

// This also works with a single socket ID
const sockets = await io.in(theSocketId).fetchSockets();

사용 예

// With an async function

 const sockets = await io.fetchSockets()
 sockets.forEach(socket => {
    // Do something
 });
// Without an async function

io.fetchSockets()
.then((sockets) => {
  sockets.forEach((socket) => {
    // Do something
  })
})
.catch(console.log)

서버에서 소켓 객체에 접근할 수 있고 닉네임을 지정하고 소켓 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.

이것이 소켓에서 액세스하는 가장 좋은 방법입니다.IO 1.3:

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

버전 4.0 이상(2021)

어떤 대답도 제게는 통하지 않았습니다.제가 당신의 고통을 덜어드리겠습니다.그들의 API와 설명서는 1.0 이후 크게 변화했습니다.

서버 API: 사용 가능한 모든 옵션

하지만 당신은 여기서 더 깊이 파고들 필요가 있습니다.

// Return all Socket instances
var clients = io.sockets;

clients.sockets.forEach(function(data, counter) {

    //console.log(data); // Maps

    var socketid = data.id; // Log ids
    var isConnected = data.connected // true, false;

});

2023년 업데이트 - 연결된 모든 사용자 가져오기

프로젝트(즉, 개인 메시징)에서 사용하기 위해 사용자 ID를 소켓 ID에 연결하여 지속성을 생성하는 방법을 보여줌으로써 이 답변에 추가하고 싶습니다.

client.js(클라이언트 측)

/***
*
*
* getConnectedUsers
*
*
*
*/
function getConnectedUsers(){
/**
*
*
* STEP 1
* GET
*
*
*/
//
var userID = localStorage.getItem('userid');//this typically would be the unique id from your database. Set this variable at login()
//set-username
socket.auth = { userID };
//console.log(socket.auth);
//
//get-connected-socket-users
socket.emit('get-connected-socket-users',{
userid:userID
});
}
/**
*
*
* STEP 2
* SET
* use this for instant communication
*
*/
socket.on('connected-socket-users',function(data){

//console.log(data);
var connectedUsers = JSON.stringify(data);

localStorage.setItem('connectedUsers',connectedUsers);
//console.log(localStorage.getItem('connectedUsers'));


});

server.js(서버 측)

/**
* 
* 
* GET ALL CONNECTED USERS
* 
* 
*/
socket.on('get-connected-socket-users',function(data){
//
//variables
var userid = data.userid;
socket.username = userid;
//console.log(io.sockets);
//console.log(userid);
/**
* 
* GET ALL CONNECTED USERS
* 
*/
const users = [];
var clients = io.sockets;
clients.sockets.forEach(function(data,counter){

users.push({
userSocketID: data.id,
username: data.username,
});

});


//console.log(users);
//var handle = 
setInterval(function(){

socket.emit("connected-socket-users", users);

}, 3000);


// When you want to cancel it:
//clearInterval(handle);
//handle = 0; // I just do this so I know I've cleared the interval


});

연결된 클라이언트의 수를 원하는 사용자라면 다음과 같이 할 수 있을 것입니다.

io.sockets.manager.server.connections

소켓에 있습니다.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

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

소켓 기준.IO 1.5, indexOf에서 더 이상 사용되지 않는 것으로 표시되고 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;
}

소켓용.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;
}

소켓.IO 3.0

io.in('room1').sockets.sockets.forEach((socket, key) => {
    console.log(socket);
})

1의 모든 소켓 인스턴스를 가져옵니다.

이오.오소켓.키 소켓

도움이 됩니다.

소켓에 있습니다.IO 1.3에서는 두 가지 방법으로 이를 수행했습니다.

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' ]

버전 2.3의 경우기능이 작동하며 소켓도 제공합니다.내가 보기에 그 소켓은한동안 사용한 후에 Io는 너무 빠르게 변하고 있고, 읽을 수 있는 문서가 거의 없습니다.

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 어떻게든.

클러스터 모드의 경우 Redis 어댑터 사용:

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

});

각각의 소켓은 그 자체가 방이기 때문에, 그것을 사용하여 소켓이 존재하는지 여부를 알 수 있습니다.

네임스페이스입니다.모든 소켓()

약속을 반환합니다.<SocketId>설정합니다.

io.allSockets()기본 네임스페이스에 연결된 모든 소켓 ID

io.in('room').allSockets()'룸'에 있는 모든 연결된 ID

io.of('/namespace').allSockets()'/namespace'에 있는 연결된 모든 ID(이 ID를 룸과 결합할 수도 있음)

소켓 ID 목록을 가져오려면 다음을 수행합니다.

[...io.sockets.sockets].map(s => s[0]);

소켓 개체를 가져오려면 다음을 수행합니다.

[...io.sockets.sockets].map(s => s[1]);

버전 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를 저장하기 위해 배열 대신 일반 객체를 사용합니다.

소켓의 관리자 속성에서 액세스할 수 있습니다.

var handshaken = io.manager.handshaken;
var connected = io.manager.connected;
var open = io.manager.open;
var closed = io.manager.closed;

저는 여기서 많은 좋은 답변들을 보았고 많은 것들이 꽤 유용했지만, 제가 필요로 하는 것은 아니었습니다.저는 관심 있는 고객이 주어진 레코드의 변경 사항을 들을 수 있는 펍 서브 기능에 소켓을 사용하고 있습니다.

저의 구체적인 문제는 동일한 소켓이 같은 방에 여러 번 연결되어 있다는 것이었습니다.이에 대한 해결책은 소켓이 이미 객실 속성 내부에 객실이 있는지 확인하는 것이었습니다.

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

이것이 소켓에서 가장 간단한 방법입니다.네임스페이스 또는 룸을 사용하지 않는 경우 IO 1.0 이상.

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

이것은 기본 네임스페이스를 살펴보고 소켓 배열의 길이를 결정합니다.Object.keys().

프로젝트에 socket.io 클러스터가 있으면 socket.io -redis 어댑터가 사용되고 있음을 의미합니다.

위와 같은 경우에는 socket.io -redis 어댑터를 통해 연결된 모든 소켓 ID 프로세스를 적용해야 합니다.이를 위해 아래의 예를 사용할 수 있습니다.

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 -registerhub 페이지를 참조하십시오.

소켓.IO 4.x

const socketsOnDefaultNamespace = io.of('/').sockets.size;
console.log("Number of clients connected: ", socketsOnDefaultNamespace);

const socketsInARoomInSomeNamespace = io
  .of('/someNamespace')
  .in('/someRoomname')
  .fetchSockets()
  .then((room) => {
      console.log("clients in this room: ", room.length);
    });

자세한 내용은 설명서를 참조하십시오.

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.

언급URL : https://stackoverflow.com/questions/6563885/how-do-i-get-a-list-of-connected-sockets-clients-with-socket-io

반응형