当我反复按F5而不停止相同的socket.username进入房间时,生成一个重复名称列表。通过花时间,这个插座重复无效自动断开连接。
断开连接后我尝试使用这些线路而不工作!
delete io.sockets.adapter.sids[socket.id];
delete io.sockets.adapter.rooms[socket.id];
我该如何避免这种情况? TKS。
// 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);
}
});
});
答案 0 :(得分:1)
此代码导致您遇到一些问题:
socket.onclose = function (reason) {
roomsToLeaveClient = socket.rooms;
Object.getPrototypeOf(this).onclose.call(this, reason);
});
首先,最后有一个额外的)
关闭.on('connect')
块。
这会导致您的socket.on('disconnect', ...)
代码超出socket
的范围,因此可能无法正确调用。我建议你根本不需要听一个近距离的活动。您可以只是监听断开连接事件,并在那里进行任何清理业务。
而且,由于您在该代码中关闭了一组parens,因此代码中的其他位置可能存在相应的错误,仍然允许事情正确解析。将代码放在像http://jshint.com这样的linter中会显示这些类型的错误。
然后,如果您确实想要覆盖.onclose
,则无法调用原型版本。相反,您必须在分配覆盖并调用该覆盖之前保存已安装的版本。这是与任何其他覆盖兼容的唯一方式。但是,你真的应该只使用带有事件名称的.on()
来监视套接字生命周期的事情,然后你就不必担心以任何方式进行适当的覆盖。
如果还有其他问题,我无法立即告知,但这是一个需要先修复的明显问题。
此外,您不需要roomsToLeaveClient
处理。 socket.io将自动从它所在的任何房间中删除断开连接的客户端。这不是你需要做的事情。
如果您想知道套接字所在的房间,以便告诉该房间的其他成员您要离开,那么socket.io有一个数据结构,可以准确地告诉您套接字所在的房间,您可以只是迭代那个数据结构。你不必自己跟踪它。