I am trying to find the list of rooms a client is currently in on disconnect event (closes the browsers / reloading the page / internet connection was dropped).
I need it for the following reason: user has entered few rooms. Then other people has done the same. Then he closes a browser tab. And I want to notify all the people in the rooms he is in that he left.
So I need to do something inside of on 'disconnect' event.
io.sockets.on('connection', function(client){
...
client.on('disconnect', function(){
});
});
I already tried two approaches and found that both of them are wrong:
1) iterating through adapter.rooms
.
for (room in client.adapter.rooms){
io.sockets.in(room).emit('userDisconnected', UID);
}
This is wrong, because adapter rooms has all rooms. Not only the rooms my client is in.
2) Going through client.rooms
. This returns a correct list of rooms the client is in, but no on the disconnect event. On disconnect this list is already empty []
.
So how can I do it? I am using the latest socket.io at the time of writing: 1.1.0
This is not possible by default. Have a look at the source code of socket.io.
There you have the method Socket.prototype.onclose
which is executed before the socket.on('disconnect',..)
callback. So all rooms are left before that.
/**
* Called upon closing. Called by `Client`.
*
* @param {String} reason
* @api private
*/
Socket.prototype.onclose = function(reason){
if (!this.connected) return this;
debug('closing socket - reason %s', reason);
this.leaveAll();
this.nsp.remove(this);
this.client.remove(this);
this.connected = false;
this.disconnected = true;
delete this.nsp.connected[this.id];
this.emit('disconnect', reason);
};
A solution could be either to hack the socket.js library code or to overwrite this method and then call the original one. I tested it pretty quick at it seems to work:
socket.onclose = function(reason){
//emit to rooms here
//acceess socket.adapter.sids[socket.id] to get all rooms for the socket
console.log(socket.adapter.sids[socket.id]);
Object.getPrototypeOf(this).onclose.call(this,reason);
}
I know, it's an old question, but in the current version o socket.io there is a event that runs before disconnect that you can access the list of the rooms he joined.
client.on('disconnecting', function(){
Object.keys(socket.rooms).forEach(function(roomName){
console.log("Do something to room");
});
});
https://github.com/socketio/socket.io/issues/1814
See also:
Server API documentation - 'disconnecting' event