I've asked on IRC what the proper way is to get a socket by id from the normal namespace. Supposedly it would be io.sockets.client(id)
. Unfortunately, this method does not exist. I figured it'd be a typo, and it should be io.sockets.clients(id)
. However, the clients
method expects a room and then returns an array of all sockets in that room.
Thus, one could get a socket by id like so:
function getSocketById(id) {
var clients = io.sockets.clients(),
client = null;
clients.forEach(function(_client) {
if (_client.id === id) return (client = _client);
});
return client;
}
This is obviously rather excessive. A much more efficient way would be to access the socket by id through a library (an object where id is the key
).
From the source, another way to access a socket by id is io.sockets.socket(id);
. Unfortunately, there are 2 problems here:
Thus, this method cannot be used as passing an invalid or non-existant id would trigger the creation of a dead socket.
Is there no proper way to get a client from a namespace by id at the moment?
It was actually io.sockets.socket
see https://github.com/LearnBoost/socket.io/blob/master/lib/namespace.js#L202 I could have sworn it was .client().
And it will indeed generate a new client, but there isnt any other way of doing it.. except for looking in the interal client object, which isn't adviced
@3rd-Eden, please read my entire post ;) I did address io.sockets.socket
and it has its own issues. Thanks.
@tommedema I noticed that part as was already editing my reply :)
Closing this as proper scalable solutions are in the works!
@tommedema, can you share your proper scalable solution?
@pyrostrex, I'm afraid you misunderstood me. I do not have such solution yet. :)
@tommedema, owh XD. my bad.
If the solution is not there yet, the issue shouldn't be closed.
Can this be re-opened please? There is still no way to easily get a socket by ID without running the risk of creating new sockets.
Going to add in a request to re-open this as well! Would be a very useful addition
I think you can use the io.sockets.sockets property as a hash to get the socket by id like this:
var socket = io.sockets.sockets[socket_id];
Is there a scalable way to do this yet?
For socket.io version 1.0.6, I think you can use this:
var socket = io.sockets.connected[socket.id];
For socket.io version 1.0.6, I think you can use this:
var socket = io.sockets.connected[socket.id];
just as a data point, this doesn't work as of socket.io 1.2.x
io.sockets.sockets is an array of sockets, so you can
var socket = _.findWhere(io.sockets.sockets, {id: 'mySocketId'});
using underscore or
var socket;
for (var i = 0; i < io.sockets.sockets; i += 1) {
if (io.sockets.sockets[i].id === 'mySocketId') {
socket = io.sockets.sockets[i];
}
}
more general. Have in mind that io.sockets is the "/" namespace. For specific namespace: io.of('/ns').sockets.
@romelperez thanks man, that was super helpful, old app stopped working after upgrade because this doesn't work anymore: var socket = io.sockets.sockets[socket_id];
, saludos
io.sockets.sockets is an array of sockets, so you can
var socket = _.findWhere(io.sockets.sockets, {id: 'mySocketId'});
using underscore or
var socket; for (var i = 0; i < io.sockets.sockets; i += 1) { if (io.sockets.sockets[i].id === 'mySocketId') { socket = io.sockets.sockets[i]; } }
more general. Have in mind that io.sockets is the "/" namespace. For specific namespace: io.of('/ns').sockets.
@romelperez But whole this comments thread is based on a comment of @tommedema stating that using forEach
in your case some underscore.js function, is excessive. Not an array but a hash would be more efficient or convenient.
For socket.io version 1.0.6, I think you can use this:
var socket = io.sockets.connected[socket.id];just as a data point, this doesn't work as of socket.io 1.2.x
works fine for me as of socket.io 2.2.2, and it seems to be written in API doc.
See https://github.com/socketio/socket.io/blob/master/docs/API.md#namespaceconnected
Most helpful comment
@romelperez But whole this comments thread is based on a comment of @tommedema stating that using
forEach
in your case some underscore.js function, is excessive. Not an array but a hash would be more efficient or convenient.