Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Properly getting a socket by ID #503

Closed
tommedema opened this issue Sep 2, 2011 · 18 comments
Closed

Properly getting a socket by ID #503

tommedema opened this issue Sep 2, 2011 · 18 comments

Comments

@tommedema
Copy link

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:

  • the method is flagged private
  • the method creates a new socket when the given id does not exist

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?

@3rd-Eden
Copy link
Contributor

3rd-Eden commented Sep 2, 2011

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

@tommedema
Copy link
Author

@3rd-Eden, please read my entire post ;) I did address io.sockets.socket and it has its own issues. Thanks.

@3rd-Eden
Copy link
Contributor

3rd-Eden commented Sep 2, 2011

@tommedema I noticed that part as was already editing my reply :)

@tommedema
Copy link
Author

Closing this as proper scalable solutions are in the works!

@pyrostrex
Copy link

@tommedema, can you share your proper scalable solution?

@tommedema
Copy link
Author

@pyrostrex, I'm afraid you misunderstood me. I do not have such solution yet. :)

@pyrostrex
Copy link

@tommedema, owh XD. my bad.

@diegovar
Copy link

If the solution is not there yet, the issue shouldn't be closed.

@sandermarechal
Copy link

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.

@bijanv
Copy link

bijanv commented Dec 28, 2012

Going to add in a request to re-open this as well! Would be a very useful addition

@Max-Might
Copy link

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

@yocontra
Copy link

Is there a scalable way to do this yet?

@quangtho2910
Copy link

For socket.io version 1.0.6, I think you can use this:
var socket = io.sockets.connected[socket.id];

@mikermcneil
Copy link

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

@romelperez
Copy link

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.

@gigo6000
Copy link

@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

@fselcukcan
Copy link

fselcukcan commented Oct 9, 2018

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.

@prism4time
Copy link

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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

15 participants