Brian Yeh Brian Yeh - 5 months ago 102
Node.js Question

How to send data to specific client in a specific room with socket io

My question is what's the proper way of sending data to a specific client in a specific room. I'm using socket io and the code written below:

I use the command:

socket.to(socket.id).emit('change', {data})


but the client never gets this command. Anyone know why?

Below is a snippet of my code:

server code:

io.on('connection', function (socket) {
socket.on('channelJoin', function(channel){
socket.join(channel);

if(deltasByChannel[channel])
{
console.log("sending initial data to: "+socket.id);
socket.to(socket.id).emmit('change', deltasByChannel[channel]);
}

socket.on("change", function(delta){
console.log("channel: " + channel+" was edited!");
console.log(deltasByChannel[channel]);
deltasByChannel[channel] ? deltasByChannel[channel] = deltasByChannel[channel].concat(delta) : deltasByChannel[channel] = delta;
socket.broadcast.to(channel).emit('change', delta);
});
});
});


http.listen(3000, function () {
console.log('listening on *:3000');
});


client code:

var channel = window.location.pathname;
var socket = io.connect();

//Ace handlers
var sendUpdateData = function(e){
socket.emit("change", [e.data]);
};



socket.on('connect', function(){
socket.on("change", function(data){
console.log("change event received!");
editor.getSession().removeListener('change', sendUpdateData);
editor.getSession().getDocument().applyDeltas(data);
editor.getSession().on('change', sendUpdateData);
});
editor.getSession().on('change', sendUpdateData);

socket.emit('channelJoin', channel);
});


just to avoid confusion the editor object is listening for a change event as well. It's from an entirely different library (ace.js) that has nothing to do with my socket io issue.

below is another snippet of the server code for more clarity:

var http = require('http').Server(app);
var io = require('socket.io')(http);

http.listen(3000, function () {
console.log('listening on *:3000');
});

Answer

I think there's some confusion about sending data over sockets using socket.io. You can elect to emit events or data using rooms or private namesspaces, you can broadcast to all connected sockets, or you can emit data to a specific ID.

In your case you should just be selecting a socket.id, to emit an event to a particular connection. You can do this by:

io.sockets.connected[ socket.id ].emit('privateMsg', 'hello this is a private msg');

You can also use the to() method in conjunction with broadcast as well:

socket.broadcast.to( socket.id ).emit('privateMsg', 'hello this is a private msg');

This will reach the user which matches the socket.id you pass in as the argument.

To contact users within a "room" or private namespace, you can also use the to() method:

io.to('some room').emit('some event');

In this case some room would be the channel var you've defined, and it should match a predefined variable that has already been instantiated.

For more information about rooms/namespaces/and reaching specific socket connections: http://socket.io/docs/rooms-and-namespaces/#

Comments