如何使用socket io将数据发送到特定房间中的特定客户端

时间:2014-09-28 01:47:57

标签: javascript node.js websocket socket.io

我的问题是将数据发送到特定房间中的特定客户端的正确方法是什么。我正在使用socket io和下面编写的代码:

我使用命令:

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

但客户端永远不会得到此命令。谁知道为什么?

以下是我的代码片段:

服务器代码:

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');
});

客户代码:

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);
});

为了避免混淆,编辑器对象也在监听变更事件。它来自一个完全不同的库(ace.js),与我的socket io问题无关。

下面的

是服务器代码的另一个片段,以便更清晰:

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

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

1 个答案:

答案 0 :(得分:4)

我认为使用socket.io通过套接字发送数据存在一些困惑。您可以选择使用rooms或专用名称空间发出事件或数据,您可以向所有连接的套接字广播,或者您可以将数据发送到特定ID。

在您的情况下,您应该只选择socket.id,以向特定连接发出事件。您可以通过以下方式执行此操作:

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

您也可以将to()方法与broadcast结合使用:

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

这将转到与您传入的socket.id匹配的用户作为参数。

联系"房间内的用户"或私有命名空间,您也可以使用to()方法:

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

在这种情况下,some room将是您定义的channel var,它应该与已经实例化的预定义变量匹配。

有关房间/命名空间/以及到达特定套接字连接的更多信息:http://socket.io/docs/rooms-and-namespaces/#