【问题标题】:double sockets in room房间内双插座
【发布时间】:2017-01-04 07:50:16
【问题描述】:

当我反复按 F5 而不停止相同的 socket.username 进入房间时,生成重复名称列表。通过花费时间,这个sockets复制了徒劳的自动断开。

我在断开连接后尝试了这些线路,但不起作用!

delete io.sockets.adapter.sids[socket.id]; delete io.sockets.adapter.rooms[socket.id];

我怎样才能避免这种情况?谢了。

// SERVER.JS

io.set('authorization', function (handshakeData, accept) {
  if (handshakeData.headers.cookie) {
    handshakeData.cookie = cookie.parse(handshakeData.headers.cookie);
    handshakeData.sessionID = cookieParser.signedCookie(handshakeData.cookie['sec_session_id'], 'secret');
    if (handshakeData.cookie['sec_session_id'] != handshakeData.sessionID) return accept('Cookie is invalid.', false);
  } else return accept('No cookie transmitted.', false); 
  accept(null, true);
});




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

    socket.on('adduser', function(name, room, picuser, codeuser, operation) {

        var handshakeData = socket.request;  
        var cookies = cookie.parse(handshakeData.headers.cookie);       
        if(name.length > 0)
        {
            if (!io.sockets.adapter.sids[socket.id][room]) {

                var newCookie = changeCookie(cookies.sec_session_id);
                cookiesSockets[cookies.sec_session_id] = newCookie;
                cookiesSockets2[newCookie] = socket.id;             
                socket.color = getRandomColor();
                socket.username = name;
                socket.room = room;
                socket.newid = newCookie;
                socket.picuser = picuser;
                socket.codeuser = codeuser;             
                // add the client's username to the global list
                usernames[name] = name;
                // send client to room
                socket.join(room);              
                // echo to client they've connected
                socket.emit('updatechat', socket.picuser, socket.codeuser, socket.color, getClock(), 'You', 'join in '+room+'.', room, 0, 0, getClock2(), operation);
                // echo to room 1 that a person has connected to their room
                socket.broadcast.to(room).emit('updatechat', socket.picuser, socket.codeuser, socket.color, getClock(), name,'join in room.', room, 0, 0, getClock2(), 3);

                //update id's private chats on socket disconnecting and connecting...
                if (SocketsUsernames[name])
                {
                    if (SocketsUsernames[name]!=cookies.sec_session_id)
                    {
                        var cookieReal = SocketsUsernames[name];
                        var cookieChanged = cookiesSockets[cookieReal];
                        delete cookiesSockets[cookieReal];
                        delete cookiesSockets2[cookieChanged];
                        socket.broadcast.to(room).emit('updatechatpvt', room, cookieChanged, newCookie);
                    }
                }
                SocketsUsernames[name] = cookies.sec_session_id;
                updateUsers(room);
            }
            else 
            socket.emit('updatechat',null, null, null, null, null, null, room, null, null, null, 7);            
        }       
    });



socket.on('disconnect', function(){     
            if (socket.username)
            {
                // remove the username from global usernames list
                delete usernames[socket.username];          
                socket.leave('myroom');     
            }
        }); 

});

//CLIENT.JS

socket.on('connect', function (){
            // Retrieve the object from storage CHATROOM!!

            var retrievedRooms = localStorage.getItem('myRooms');
            console.log('retrievedRooms: ', JSON.parse(retrievedRooms));
            if (retrievedRooms && Object.keys(JSON.parse(retrievedRooms)).length>0)
            Object.keys(JSON.parse(retrievedRooms)).forEach(function(key) {
                if (key)
                {
                    myRooms[key]=key;               
                    socket.emit('checkuser', key, function(callback){
                        if(!callback) socket.emit('adduser', $('#modalPerfil').attr('data-username'), key, $('#modalPerfil').attr('data-picuser'), $('#modalPerfil').attr('data-userid'), 1);
                    });
                }
            });
        });

// CLIENT.JS 中的解决方案 - setTimeout

socket.on('connect', function (){
            // Retrieve the object from storage CHATROOM!!          
            var retrievedRooms = localStorage.getItem('myRooms');
            console.log('retrievedRooms: ', JSON.parse(retrievedRooms));
            if (retrievedRooms && Object.keys(JSON.parse(retrievedRooms)).length>0)
            Object.keys(JSON.parse(retrievedRooms)).forEach(function(key) {
                if (key)
                {
                    myRooms[key]=key;

                    setTimeout(function(){

                        socket.emit('checkuser', key, function(callback){
                            if(!callback) socket.emit('adduser', $('#modalPerfil').attr('data-username'), key, $('#modalPerfil').attr('data-picuser'), $('#modalPerfil').attr('data-userid'), 1);
                        });

                    }, 1000);                   

                }
            });
        });

【问题讨论】:

  • 请出示相关代码。 F5 将重新加载该页面。这将断开前一个套接字并连接一个新的。如果您的代码正确,一切都会正常工作。您不必手动从适配器中删除东西。当前一个套接字断开连接时,socket.io 会为您执行此操作,当页面重新加载时它将执行此操作。
  • @jfriend00 提问已更新! tks 引起注意!

标签: node.js socket.io


【解决方案1】:

这段代码给你带来了几个问题:

socket.onclose = function (reason) {
    roomsToLeaveClient = socket.rooms;
    Object.getPrototypeOf(this).onclose.call(this, reason);
});

首先,末尾有一个额外的 ) 来关闭你的 .on('connect') 块。

这会导致您的socket.on('disconnect', ...) 代码超出socket 的范围,因此它可能没有被正确调用。我建议您根本不需要收听关闭事件。您可以只监听断开事件并在那里进行任何清理工作。

而且,由于您在该代码中没有使用一组括号,因此您的代码中的其他地方可能存在相应的错误,仍然允许正确解析。将您的代码放入像 http://jshint.com 这样的 linter 会显示这些类型的错误。

那么,如果你真的想覆盖.onclose,你不能只调用原型版本。相反,您必须在分配覆盖并调用该版本之前保存已存在的版本。这是与任何其他覆盖兼容的唯一方式。但是,你真的应该只使用带有事件名称的.on() 来观察套接字生命周期的事情,那么你不必担心以任何方式进行适当的覆盖。

我不能马上判断是否还有其他问题,但这是一个需要首先解决的明显问题。

另外,您不需要您的roomsToLeaveClient 处理。 socket.io 会自动从它所在的任何房间中删除断开连接的客户端。这不是你需要做的。

如果您想知道套接字在哪些房间,以便告诉该房间的其他成员您要离开,那么 socket.io 有一个数据结构可以准确地告诉您套接字在哪些房间,您可以只需迭代该数据结构。您不必自己跟踪。

【讨论】:

  • There's an extra) at the end que is closing off your .on ('connect') block. 在手动复制和粘贴时编辑了stackOverflow 我无意中放了一个')`!我联系onclose 以获取要断开连接的房间的完整列表。http://stackoverflow.com/questions/25830415/get-the-list-of-rooms-the-client-is-currently-in-on-disconnect-event/25864163
  • @FábioZangirolami - 那么,该评论是什么意思?我不明白。您问题中的代码是错误的。如果那不是您的真实代码,则将问题中的代码编辑为真实代码,并在您更改时留下评论。在这里我们能做的不多,但对您发布的代码发表评论。
  • 对不起。我会这样做!
  • 我删除了我的代码的socket.onclose = function (reason) { ... },但问题仍然存在,我不知道该怎么办=/
  • 很遗憾我没有发现问题。但是我用setTimeout 解决了1秒进入房间的问题。
猜你喜欢
  • 1970-01-01
  • 2018-09-26
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 2021-03-13
相关资源
最近更新 更多