4

I'm having trouble getting basic client to client (or really client->server->client) working with socket.io. Heres the code I have right now:

io.sockets.on('connection', function (socket) {

users.push(socket.sessionId);

for(userID in users)    {
    console.log(userID);
    io.sockets.socket(userID).emit('message', { msg: 'New User Connected succesfully' });
}
socket.emit('message', { msg: 'Connected succesfully' });


socket.on('my other event', function (data) {
    console.log(data);
  });
});

From my understanding, that should send the new user message to every connected user (individually, since i want to do actual individual messages later). Instead, I only get the 'connected successfully' message at the end. I don't get any errors or other negative indicators from my server or client.

Any ideas of why io.sockets.socket(userID).emit() doesn't work or what to use in its place?

MrGlass
  • 9,094
  • 17
  • 64
  • 89
  • Not too familiar with Socket.IO, but you might want to check out [now.js](https://github.com/Flotype/now) and see if it's more appropriate for your needs. – Andrew Mao Mar 06 '13 at 19:26

3 Answers3

5

Socket.io has the concept of rooms where, once a socket has joined a room, it will receive all message sent to a room, so you don't need to track who's in the room, deal with disconnections, etc...

On connection, you'd use:

socket.join('room')

And to send a message to everyone in that room:

io.sockets.in('room').emit('event_name', data)

More info on the socket.io wiki: https://github.com/LearnBoost/socket.io/wiki/Rooms

Pascal Belloncle
  • 11,184
  • 3
  • 56
  • 56
  • I want to do 2 person communications (think gchat). So, I need a way to message user B that user A wants him to join a specific room – MrGlass Mar 06 '13 at 20:37
  • 1
    you can create a room per user (based on sessionId, email, etc), so it is easy for you to find how to talk to a given user. Furthermore, if the same user is connected multiple times, sending a message to the user room will get dispatched to all his active browsers. – Pascal Belloncle Mar 06 '13 at 20:49
2

Try

users.push(socket); // without .sessionId

for (var u in users)    {
   // users[u] is now the socket
   console.log(users[u].id);
   users[u].emit('message', { msg: 'New User Connected succesfully' });
}
mak
  • 13,267
  • 5
  • 41
  • 47
  • That works, but I feel like the users array is gonna get huge holding all those sockets. Is there a way to just persist an id and then pull the socket on the fly? – MrGlass Mar 06 '13 at 20:41
  • This is going to leak the sockets if browser disconnects, you'd need to catch the disconnection events and clean up. Socket.io keeps the connected sockets anyway, so you are not using more memory. – Pascal Belloncle Mar 06 '13 at 20:45
  • @PascalBelloncle I'm not a javascript expert, would that array have references to the sockets instead of copies? I figured it would take 2x the normal memory – MrGlass Mar 06 '13 at 20:47
  • 1
    a javascript array keeps only a reference to its objects, so this is not duplicating the socket by just putting it in an array. But if the browser disconnects, and you keep a reference in your array, it will leak, even if socket.io itself has closed it. It will get garbage collected only once nothing has a reference to it. – Pascal Belloncle Mar 06 '13 at 20:51
  • Remove reference on disconnect `socket.on('disconnect', function() { delete users[users.indexOf(socket)]; });` – mak Mar 06 '13 at 20:55
1

You can now also use ...

io.to('room').emit('event_name', data);

as an alternative to io.sockets.in

Master James
  • 1,691
  • 15
  • 19