如何使用 socket.io 存储来自特定用户的套接字资源? [英] how do I store socket resources from specific users with socket.io?

查看:21
本文介绍了如何使用 socket.io 存储来自特定用户的套接字资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm designing a chat script which I test on my machine using different browsers. I'm tryng to send messages to specific users with socket.io, so here it is :

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 中的用户存储在用户对象中,如果我重新加载并重新连接再次存储它,但是当我询问浏览器 B 中用户对象的内容是什么时......信息已过时并且显示的结果与我询问 Broser A 中对象的内容时显示的结果不同,即使我正在尝试检查无效性以在用户为空时存储 vals --> if( ( users.hasOwnProperty(req.session.name) === false)).基本上,我需要的是一种将每个套接字资源存储在带有标识符 (req.session.name) 并使这样的容器可用于所有浏览器中的所有会话,因此当服务器收到从浏览器 A 到浏览器 B 的消息时,它可以识别它并向浏览器 B 发出响应.

Well, I'll talk about the structure of code related to the server. It is in charge of storing a user on a 'connection' event. The problem starts when I reload the page: it stores the user from browser A in the users object, if I reload and reconnect stores it again , but when I ask which are the contents of the users object in browser B ... the info is outdated and does not show the same result as when I ask which are the contents of the object in broser A, even though I'm trying to do some cheking of nullity to store vals if users is empty --> if( ( users.hasOwnProperty(req.session.name) === false)). Basically, what I need is a means of storing each socket resource in a container(in fact, doesn't necessarily needs to be an object) with an identifier(req.session.name) and to have such container available to all sessions in all browsers, so when server receives a message from browser A to browser B it could identify it and emit a response to browser 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' (users[incoming.phonenumber] = socket.id),而在 git generalhenry 中声明我们必须存储 'socket'(users[myName] = socket) 资源.后者是正确的,因为 socket.id 的值在两种浏览器中往往是相同的......并且该值会自动更改,我不知道为什么会出现......我想在早期版本的节点中它那样工作.

If you look carefully at the code... in chrissilich.com , the author states that we need to store the 'socket.id' (users[incoming.phonenumber] = socket.id), whereas in git generalhenry states we have to store the 'socket'(users[myName] = socket) resource. The latter is the correct one , because the values of socket.id tend to be the same in both browsers... and that value changes automatically , I don't know why is there... I suppose in earlier versions of node it worked that way.

推荐答案

问题是socket.id标识的是sockets,而不是用户,所以如果一个用户同时打开了多个tab,每个tab的socket.id都会不同,所以如果你只为一个用户存储了一个 socket.id,那么每次你分配它时,你都会覆盖之前的 socketid.

The problem is that socket.id identifies sockets, not users, so if an user has several tabs opened at same time, every tab would have different socket.id, so if you store only one socket.id for an user, every time you assign it, you overwrite previous socketid.

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

So, beside other possible problems, at least you need to do this or it won't work. I bet that you say about 1 socket for all browsers is that you overwrite the id every time (it happened to me when I started using Socket.IO)

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

As a general rule, remember that you manage CONNECTIONS and not USERS... an user can have more than one connection!.

连接时

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
}

这篇关于如何使用 socket.io 存储来自特定用户的套接字资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆