Socket.io 0.7 – Sending messages to individual clients

Note that this is just for Socket.io version 0.7, and possibly higher if they don’t change the API again.

I’m writing an iPhone app right now using PhoneGap and jQuery Mobile on the phone, and node.js and socket.io on an Amazon EC2 server, and I hit a wall when I started using Socket.io. The problem is that the documentation is sparse, disorganized, and hard to find. In addition to that, there are dozens of blog posts and community members who’ll teach you how to do things in older versions of socket, but the API has changed, so you just end up with undefined errors.

My exact problem was with sending messages to individual clients.

First, you need the client’s socket ID, so have the user “check in” when they connect, and have the server store their socket ID with whatever identifier we’ll be using to refer to users (in my case, phone number).

// on the server
var users = {};
io.sockets.on('connection', function (socket) {
	socket.emit('who are you');
	socket.on('check in', function (incoming) {
		users[incoming.phonenumber] = socket.id;
	});
});
// on the client
socket.on('who are you', function (incoming) {
	socket.emit('check in', {phonenumber: savedphonenumber});
});

To recap: The server is listening for connections. When a client connects, the server emits the custom message “who are you”. The client hears it and responds with it’s identifier (I’m using their phone number, which I verify and store earlier in the process). The server then stores the client’s socket ID in a users object, with their identifier as the key, and the socket ID as the value.

From then on, it’s a simple case of grabbing the user’s socket ID from the user’s table when you need to send them a message, and sending it like this:

var socketid = users[clientphonenumber];
io.sockets.socket(socketid).emit('for your eyes only');

One thing to consider is what happens to that users object if you have thousands of users. It’ll get pretty bloated, pretty quickly. You need to figure out a strategy for removing users from the users object if they disconnect AND if you don’t hear from them in a while (in case the disconnect event doesn’t fire).

17 thoughts on “Socket.io 0.7 – Sending messages to individual clients”

  1. How did you get pass the same origin policy issue with socket.io? If you have a node.js server on another domain on port 80 then a phonegap client. How do they communicate. I have been unable to get it to work. It works great if your html files are on the same domain and port as your node.js server.

    1. I never ran into that problem. Fortunately, I was running the node/socket server on Amazon EC2, and the phonegap install was local to the phone, and it just worked. Perhaps the same origin policy was added to a newer version of socket that I used.

        1. Sorry, but no, I can’t share anything without revealing what I’m working on, and my client would not like that very much.

    2. Not sure how socket.io overcomes this limitation but I have the html file loading from an apache server on port 80 and the socket.io server listening on port 8000. Just make sure that the socket.io.js file is available in the path when it has to be loaded by the html file. It’s possibly using the Script Tag Hack, which is not constrained by the same origin policy.

  2. I agree with you, socket.io documentation on the API is not very good. Especially if you look at what node.js offers or QT etc. Although you aren’t really doing any better to help the cause. Socket.io is now almost getting to ver 0.9 and your post reflects an older version, soon it will be out-dated. Not blaming you, but I wish people who wanted to “help” people would be kind enough to take the time to edit their post when necessary. Oh and for people new to socket.io, it can be very easy to simply call socket.id inside an event to receive the id if you do not store it.

    P.S Font in comment’s section is small and hurts my eyes.

    1. 1) Yes, I am “doing better to help the cause” since I have documented one feature of socket.io that was previously undocumented. I stopped using socket.io shortly after this post, so I haven’t updated my own knowledge. Since this little blog (that was aimed at helping people who happen to have the same obscure problems I run into) isn’t my full-time job, and nor do I work on the node or socket teams, I haven’t gone back to learn new code simply to update this post. You’ll have to forgive me for not wanting to spend ALL my time trying to “help” people. And who puts quotes around “help”. According to other comments and some analytics, I have helped people, no quotes.
      2) Socket.io is at 0.8.7, not “almost at 0.9″. Double point releases in the small software world are usually just bug fixes, you can’t just subtract 0.8.7 from 0.9 and say that it’s only 0.0.3 away. Also, you were rude enough that I went back and updated my socket install, and my code still works with 0.8.7 (that’s 0.1.7 away from when I posted it, amazing!). The Github repo shows no indication that Guillermo has even started work on 0.9, and for all we know, any api changes will not break compatibility with the code snippets I’ve posted.
      3) Yes, you can call socket.id inside an event that is originated by the client you want to send a message to. The reason I suggested storing the socket id in whatever user list you’re keeping is for cases when you aren’t getting an event from the user you want to message. For example, if some bit of data comes from user A, to the server, and the server is meant to send it to user B, the server will have to have stored the latest socket id of user B in order to know which client to send the new message to.
      P.s.) Comment font size too small? Zoom in.

  3. Nice article, you helped me a lot.
    The only problem i found (in my case), is when a user opens two or more tabs in the same browser.
    His member_id will be the same on all tabs, but his socket.id is different.
    Since the code above overrides users[member_id], the private message will be posted in his last opened tab.

    Thank you for your help.

  4. I’m using socket.io version 0.9.2, and still found this post very helpful. This seems like a common use case that should be documented.

    Thanks!

  5. Thanks for the post – it was helpful. You’re helping to fix the woeful lack of documentation on socket.io

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>