如何使用socket.io存储特定用户的套接字资源?

时间:2012-12-27 03:02:13

标签: node.js socket.io

我正在设计一个聊天脚本,我使用不同的浏览器在我的机器上测试。我正在尝试使用socket.io向特定用户发送消息,所以这里是:

client:

socket.on('msgFromServer', function (data) {
     message = data['message'],
     from = data['from'],
     to = data['to'];               

    if($('#chatbox.'+from).dialog("isOpen") === true){
        $('#chatbox.'+from+' #messageOutput textarea.readOnly').text(message);      
    }   
    else if(($('#chatbox.'+from).dialog("isOpen") !== true)){
        createChatbox(from,to,message);
    }
});




server:

var users = {};
io.sockets.on('connection', function (socket) {
    if( ( users.hasOwnProperty(req.session.name) === false))
            users[req.session.name] = socket;

    socket.on('msgToServer', function (data) {
         for (var u in users){
              console.log("%s | %s",u,users[u]);
         }      

     });
}); 

好吧,我将讨论与服务器相关的代码结构。它负责将用户存储在“连接”事件上。当我重新加载页面时问题开始:它将用户从浏览器A存储在users对象中,如果我重新加载并重新连接再次存储它,但当我询问浏览器B中的用户对象的内容时... ...已经过时,并且没有显示与我在询问哪些是broser A中对象的内容时相同的结果,即使我正在尝试做一些无效的检验以存储val,如果用户为空 - &gt; if((users.hasOwnProperty(req.session.name)=== false))。基本上,我需要的是一种将每个套接字资源存储在容器(实际上,不一定是一个对象)的方法,其中包含一个标识符( req.session.name < / strong>)并且让所有浏览器中的所有会话都可以使用这样的容器,因此当服务器收到从浏览器A到浏览器B的消息时,它可以识别它并向浏览器B发出响应。

我从https://github.com/generalhenry/specificUser/blob/master/app.jshttp://chrissilich.com/blog/socket-io-0-7-sending-messages-to-individual-clients/

了解了我的想法

如果仔细查看代码...在chrissilich.com中,作者声明我们需要存储'socket.id'(用户[incoming.phonenumber] = socket.id),而在git generalhenry状态我们必须存储'socket'(users [myName] = socket)资源。后者是正确的,因为socket.id的值在两个浏览器中往往是相同的......并且该值会自动更改,我不知道为什么会有...我想在早期版本的节点中它这样工作。

1 个答案:

答案 0 :(得分:12)

问题是socket.id标识套接字而不是用户,因此如果用户同时打开了多个选项卡,则每个选项卡都会有不同的socket.id,因此如果只为用户存储一个socket.id,每次分配时,都会覆盖以前的socketid。

因此,除了其他可能的问题之外,至少你需要这样做,否则它将无法工作。我打赌你说所有浏览器的1个套接字是你每次都覆盖id(当我开始使用Socket.IO时发生在我身上)

作为一般规则,请记住您管理CONNECTIONS而非USERS ......用户可以拥有多个连接!

连接时

function onConnection( socket ) {
    var arr = users[incoming.phonenumber] || null;
    if( !arr ) 
        users[incoming.phonenumber] = arr = [];
    if( arr.indexOf( socket.id ) === -1 )
        arr.push( socket.id ); // Assigns socket id to user
}

断开连接

function onDisconnect( socket ) {
    var arr = users[incoming.phonenumber] || null;
    if( !arr ) return; // Should not happen since an user must connect before being disconnected
    var index = arr.indexOf( socket.id );
    if( index !== -1 )
        arr.splice( index, 1 ); // Removes socket id from user
}