0

I've a simple code which set offline for the user in my sql database.

Server

io.on('connection', function (socket) { ApiHelper.setUserOnline(socket.token); socket.on('disconnect', function () { ApiHelper.setUserOffline(socket.token); }); } 

So lets say,

An user connect to socket than he lost the network connection then reconnect.

I get this logs.

  • User connected (he is online)
  • Network losted.
  • Network losted but disconnect event has not received by server yet, so user is still online
  • User reconnect to network and then socket. User is still online.
  • Previous disconnect event recevied by server and user is set offline in database. But wait user has just reconnect so actually user must be online.

Because of disconnect event fired late we saw the user is offline in database.

How can I achieve this problem?

5
  • 1
    Does each session have a unique ID or something like that? Commented Aug 19, 2017 at 14:26
  • @tobifasc yes, token is an unique ID for each user. Commented Aug 19, 2017 at 14:26
  • 1
    I meant not for each user but for each session a user creates. You could add a session ID to the connected and disconnected logs. So when a user disconnects with an old session ID but he already got a new one he doesn't get disconnected from that new one. Do you get the idea? Commented Aug 19, 2017 at 14:31
  • 1
    This code would never work if the user had more than one tab open either. I'd suggest maintaining a count of how many connections a given user has and only set offline when the count goes to zero. Then, you won't care about the order of the events and your code will work if the user happens to be using more than one tab or computer on your site. Commented Aug 20, 2017 at 6:46
  • @jfriend00, I got it and write the code it worked well. Commented Aug 22, 2017 at 12:47

1 Answer 1

1

I think the best way is to store the socket.id in the sql database, so when a user login / connects you first check if that user.account is already online or not.

If it is online, then use the old socket.id to notify that the account has been opened from another window/device/whatever and replace it in the db for the new socket.id

and by replacing the old socket.id for the new one in the db, when a disconnect occurs you will really know if it was the currently active client (socket.id) using that account or not.

So at the disconnection : check if the disconnecting socket.id is in the database or not (in other words : currently connected or not)

io.on('connection', function (socket) { /* check if the account associated to this socket was previously associated to another socket.id ... (that might be currently connected or about to disconnect (lost connection) */ if(thisAccountWasOnlineBefore){ socket.to(old.socket.id).emit('exit', 'account opened from another session'); } //pass also the socket.id so you can store it in the db ApiHelper.setUserOnline(socket.id, socket.token); socket.on('disconnect', function () { //check if socket.id is associated to any account in the db // if true : remove the socket.id and set as account status : offline }); } 
Sign up to request clarification or add additional context in comments.

3 Comments

Everytime when the user connects it gets a new, unique socket.id so there is no sense in storing it in a database: 1. when it connects it's socket.id is not in the database, 2 when it disconnects it's socket.id certainly is in the database
@mk12ok It makes no sense what you are saying, of course its new and unique but that way you will know what id is currently using what account, so when a disconnection occurs you can check if it corresponds to an active user's socket connection or to an old user's connection (preventing disconnection of the currently active one).
This can be useful specially for games where you can only access the account from a single instance at a time. (so when you connect with the same account you already have open, the older client gets a message "Connection Lost : this account was opened from another client.") :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.