Fábio Zangirolami Fábio Zangirolami - 3 months ago 50
Node.js Question

double sockets in room

When I press F5 repeatedly without stopping the same socket.username enters the room, generating a list of duplicate names. By spending time, this sockets duplicated vain automatically disconnecting .

I tried with these lines after disconnecting and not work!

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


How can I avoid this? 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);
});
}
});
});


// SOLUTION IN 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);

}
});
});

Answer

This code is causing you a couple problems:

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

First off, There's an extra ) at the end that is closing off your .on('connect') block.

That then causes your socket.on('disconnect', ...) code to be outside the scope of socket so it probably isn't getting called appropriately. I'd suggest you don't need to listen for a close event at all. You can just listen for the disconnect event and do any of your cleanup business there.

And, since you're off one set of parens in that code, there's probably a corresponding error somewhere else in your code that still allows things to parse properly. Putting your code in a linter like http://jshint.com shows these types of errors.

Then, if you really did want to override .onclose, you can't just call the prototype version. Instead, you have to save the version that was in place before you assign your override and call that one. That's the only way the is compatible with any other overrides. But, you really ought to just be using .on() with event names to watch socket lifecycle things, then you don't have to worry about proper overrides in any way.

I can't tell right away if there are other issues, but this is a glaring one that needs to be fixed first.

Also, you do not need your roomsToLeaveClient handling. socket.io will automatically remove a disconnecting client from any rooms that it is in. That is not something you need to do.

If you want to know what rooms a socket is in so you can tell the other members of that room that you are leaving, then socket.io has a data structure that tells you exactly what rooms the socket is in and you can just iterate that data structure. You don't have to keep track of that yourself.