最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to send data to specific client in a specific room with socket io - Stack Overflow

programmeradmin4浏览0评论

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 mand:

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

but the client never gets this mand. 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');
});

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 mand:

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

but the client never gets this mand. 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');
});
Share Improve this question edited Sep 28, 2014 at 2:30 Brian Yeh asked Sep 28, 2014 at 1:47 Brian YehBrian Yeh 3,2773 gold badges30 silver badges46 bronze badges 6
  • Can you show the code where you instantiate the http object, and connect the io object to the server, probably using the listen method? – bencripps Commented Sep 28, 2014 at 2:14
  • ok, I put another snippet of that part in. – Brian Yeh Commented Sep 28, 2014 at 2:17
  • I assume emmit is a typo, and you're really using emit? – bencripps Commented Sep 28, 2014 at 2:22
  • I think you should be using io.to(socket.id).emit('change', {data}) but can you also verify that socket.id in this context is equal to channel? – bencripps Commented Sep 28, 2014 at 2:37
  • They are not equal. Channel is just an arbitrary string, a sort of chatroom that several users can be in. I use socket.to(channel).broadcast to send messages to all users in a "chat room". Socket.id is is the individual connection. It's some randomly generated string. I've seen people use socket.id in other places to send data to an individual, but what about a specific individual in a specific room? – Brian Yeh Commented Sep 28, 2014 at 2:44
 |  Show 1 more ment

1 Answer 1

Reset to default 4

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/#

发布评论

评论列表(0)

  1. 暂无评论