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

Node.js 如何使用socket.io存储来自特定用户的套接字资源?,node.js,socket.io,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("isOp

我正在设计一个聊天脚本,在我的机器上使用不同的浏览器进行测试。我正在尝试使用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中的users对象的内容时。。。该信息已过时,并且显示的结果与我询问broser A中哪些是对象的内容时的结果不一样,即使我试图在用户为空-->if((users.hasOwnProperty(req.session.name)==false)时进行空值检查以存储VAL。基本上,我需要的是将每个套接字资源存储在一个带有标识符(req.session.name)的容器中(事实上,不一定是一个对象),并使该容器可用于所有浏览器中的所有会话,所以,当服务器接收到从浏览器a到浏览器B的消息时,它可以识别该消息并向浏览器B发出响应

我对我想要的东西有了一个想法


如果你仔细看代码。。。在chrissilich.com中,作者声明我们需要存储“socket.id”(用户[incoming.phonenumber]=socket.id),而在git generalhenry中,我们必须存储“socket”(用户[myName]=socket)资源。后者是正确的,因为socket.id的值在两种浏览器中趋于相同。。。这个值会自动改变,我不知道为什么会有。。。我想在node的早期版本中,它就是这样工作的

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

所以,除了其他可能的问题外,至少你需要这样做,否则它将无法工作。我敢打赌,你说所有浏览器都有一个socket,那就是你每次都会覆盖id(我刚开始使用socket.IO时就是这样)

一般来说,请记住,您管理的是连接,而不是用户。。。一个用户可以有多个连接

关于连接

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
}
断线

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
}

可能尝试将套接字的登录名存储在一个对象中,比如clients[login]=socket.id?所以你总是可以发送一些东西到一个特定的套接字,比如io.sockets.socket(clients[login])。emit(…)[link]我已经在这样做了,问题是socket.id在所有浏览器中都是相同的,而不是socket。上面的链接演示了您所说的内容。这个链接似乎可以工作,但我不知道如何存储所有用户并在所有浏览器中查看他们…为什么“socket.id在所有浏览器中都是相同的”对您来说是个问题?socket.id是在服务器上生成的,因此它不能依赖于浏览器,因为据我所知,socket.id用于跟踪用户。我使用不同的帐户和浏览器登录到服务器,因此在发送消息时会发送一个事件“msgToServer”。在服务器上,我打印所有用户及其各自的资源:“socket”。如果我改为使用socket.id,当我执行相同的操作时,我所看到的输出是相同的资源,即使我从不同的浏览器发送了消息,正如您所期望的那样。。。如果我试图从该资源(例如io.sockets.socket(clients[login])发送一个事件(msg),这在所有浏览器中都是相同的,那么这样的事件(msg)会发送给每个人,你是对的。我刚才解决了。基本上,问题是“用户”存储了很多套接字,因为我使用socket.id作为密钥,但是当我重新加载站点时。。。socket.id再次被同一用户更改并存储,因此解决方案是将密钥更改为其他内容(例如电话号码)。代码并没有包括所有的问题,tho(以防有人遇到我的情况)。谢谢你的回答。