保持与同一用户打开的每个新选项卡的套接字连接

时间:2015-01-30 10:58:47

标签: node.js websocket socket.io

我正在为我们的网站制作一个应用程序,用户可以相互发送聊天消息。我已成功使用nodejs和socketio成功完成了这项工作。我有一个带有某种通知图标的标题,就像facebook一样,可以在所有页面中看到。现在,如果用户打开多个标签并且他收到一条消息,那么所有打开的标签应该会看到图标亮起。我通过跟踪用户通过2D插槽阵列打开的套接字连接来实现这一点:

var container = {};
io.sockets.on( 'connection', function(client) {

    client.on('set account online', function(username) {
        if (!(username in container)) {
            console.log(username + " is now Online" );
            container[username] = [];
        }
        client.username = username;
        container[username].push(client);
    });

    client.on('set account offline', function(username) {
        if (username in container) {
            delete container[username];
            console.log(username + " is now Offline" );
        }
    });

然后当发送消息时,我遍历相应的数组元素

   client.on('send message', function(data) {
        if (data.recipient in container) {
            var clients = container[data.recipient];
            for(var i = 0; i < clients.length;i++){
                clients[i].emit('send message', {recipient: data.recipient, message: data.message });
            }
        }
    });

它运作良好而且全部(不知道它的编码有多好)。问题是如果用户关闭选项卡,该选项卡的套接字仍然存在于container变量中,并且如果收到该特定用户的消息,节点仍将尝试向该套接字发出。此外,取消跟踪任何断开连接的插座也感觉更干净。

我一直在考虑这个问题,我认为我必须将套接字断开连接事件与客户端onbeforeunload事件联系起来,我们都知道它在不同浏览器中的表现如何。有关从container数组中拆分断开的套接字的正确方法的建议吗?

1 个答案:

答案 0 :(得分:3)

根据我的评论:

  

你应该真正实现房间。在每个连接上每个用户   应该加入自己的房间,从同一个额外的连接   用户应该加入这个房间。然后,您可以将数据发送到房间   其中的每个客户都将收到数据。

您的代码可以更改为:

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

    client.on('set account online', function(username) {
        client.join(username);
    });

    client.on('set account offline', function(username) {
        client.leave(username);
    });

    client.on('send message', function(data) {
        io.to(data.recipient).emit('send message', {
            recipient: data.recipient,
            message: data.message
        });
    });
});