user2997295
user2997295

Reputation: 603

How can I detect disconnects on socket.io?

I am using socket.io in my project. I turned on reconnect feature. I want to if user disconnects from server show an alert (Your internet connection loss. Trying reconnect). And if the user reconnects again I want to show one more alert (Don't worry, you are connected).

How can I do it?

Upvotes: 25

Views: 39340

Answers (4)

Naruto Uzumaki
Naruto Uzumaki

Reputation: 622

inpired on invicibleTrain iv made a online checker also

SERVER SIDE

const sockets={online:{},admins:{}}

// the disconnect function you create the way you wish to, example:
const disconnect=()=>{
  socket.emit('disconected')
  io.in(socket.id).disconnectSockets()
  delete sockets.online[socket.uid]
}
io.on('connection',socket=>{
  socket.emit('connection',socket.id)

  // the checker if user is online
  let drop
  const dropCheck=()=>{
    if(!socket) return; // if user connects twice before the check, simply stops process
    socket.emit('dropCheck')
    drop = setTimeout(()=>disconnect(),4000) // 4 secs to recieve answer
  }

  const setDrop=()=>setTimeout(()=>dropCheck(),60000) // 60 secs to restart the process

  socket.on('dropCheck',()=>{
    clearTimeout(drop) // cancells actual drop coutdown (if any)
    setDrop() // sets a new
  })

  //sets the user ID inside the socket used for comunication
  socket.on('uid',uid=>{
    socket.online[uid] = {status:'busy',socket:socket.id}
    setDrop()
  })
})

CLIENT SIDE

const sio = io(`...httpAddress...`,{transports:['websocket']})
sio.on('connection',socket=>{
  sio.emit('uid','user Id here..') // sends the the user ID: uid

  sio.on('dropCheck',()=>{ // responds to the checker
    sio.emit('dropCheck')
  })
})

Explanation:

  1. The user logs in and after 60 seconds dropCheck is called
  2. the dropCheck emits a ping and set a timmer of 4 seconds
  3. the user handle the emited ping and responds with another ping
  4. a: if the response comes within 4 secs the 4 secs timmer is cancelled and refreshes the 60 seconds timmer (restarting the process)
  5. b: if the response fails or delay too much the disconnect() function is called

Upvotes: 0

InvincibleTrain
InvincibleTrain

Reputation: 49

I handled this problem this way. I've made an emit sender on client which is calling heartbeat on server.

socket.on('heartbeat', function() {
        // console.log('heartbeat called!');
        hbeat[socket.id] = Date.now();
        setTimeout(function() {
            var now = Date.now();
            if (now - hbeat[socket.id] > 5000) {
                console.log('this socket id will be closed ' + socket.id);
                if (addedUser) {
                    --onlineUsers;
                    removeFromLobby(socket.id);

                    try {
                        // this is the most important part
                        io.sockets.connected[socket.id].disconnect();
                    } catch (error) {
                        console.log(error)
                    }
                }
            }
            now = null;
        }, 6000);
    });

I found this code function to call:

io.sockets.connected[socket.id].disconnect();

Upvotes: 4

roryhughes
roryhughes

Reputation: 652

To detect on the client you use

  // CLIENT CODE
  socket.on('disconnect', function(){
      // Do stuff (probably some jQuery)
  });

It's the exact same code as above for a node.js server too.

If you want for some reason to detect a user disconnecting and display it to the others, you will need to use the server one to detect it the person leaving and then emit back out a message to the others using something like:

socket.on('disconnect', function(){
    socket.broadcast.to(roomName).emit('user_leave', {user_name: "johnjoe123"});
});

Hope this helps

Upvotes: 40

tymeJV
tymeJV

Reputation: 104775

socket.io has a disconnect event, put this inside your connect block:

socket.on('disconnect', function () {
    //do stuff
});

Upvotes: 15

Related Questions