Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js - socket disconnect event doesn't work properly

In my Node app, I am using socket.io for websocket functionality.

In order to let the client know when the server becomes unavailable, I'm using the following code:

socket.on('disconnect', function(){
        //show error to client
    });

This works fine, but there's a nasty side-effect. Every time I click a link to navigate away from the page (or just reload the page) the message pops up - because the client disconnects. I certainly do not wish to display a message saying 'the server is unavailable' every time the visitor clicks a link.

I could put a timeout on the error message, giving the browser time to simply navigate away before the error shows. But you'll admit this is a shabby solution. Also, there would be two problems:

1) the error message would be delayed by the timeout amount in cases when it needs to actually be displayed, leaving the user with a non-functioning app and no notification during that interval

2) it wouldn't work for page reloads (I think)

Anyway, there's gotta be a better way. Right?

Note: this is a problem in Firefox, but not Chrome. Haven't tested other browsers yet. Firefox also displays an error message in the console stating that the websocket connection was interrupted, and I'm inclined to believe these two problems have a common cause. I have read quite a few questions and answers regarding this console error, but none seem to apply to my situation.

like image 932
sveti petar Avatar asked Nov 15 '25 16:11

sveti petar


2 Answers

I've ran into this before.

You want to know when the user is leaving the page, and you don't want to popup an error.

Use onbeforeunload to signal when they are leaving, then just set a boolean so that socket.io doesn't trigger an error.

window.onbeforeunload = function(){
  window.unloading = true;
  return; // don't return a string here or it will pop up asking user if they want to navigate away.
}

socket.on('disconnect', function(){
  // setTimeout might be optional depending on when onbeforeunload is called
  setTimeout(function(){
    if (!window.unloading)
      //show error to client 
  }, 10); // 10 ms should be long enough for onbeforeunload, and short enough so your real disconnects don't wait
});

on before unload is called when the user tries to navigate away.

normally it's used to call a message asking the user if they wish to navigate away, but you could set a variable that says the disconnect is not in error.

like image 95
dansch Avatar answered Nov 18 '25 05:11

dansch


Why don't you try to unnregister the disconnect handler on page navigation.

function alertfun(){
    //show error to client
}
socket.on('disconnect', alertfun);

window.onbeforeunload = function(){
    socket.removeEventListener('disconnect',alertfun);
}

You can have several listeners to same event. Remove the ones which you don't want. You should try this as I am not sure if disconnect event is fired before or after onbeforeunload.

like image 41
user568109 Avatar answered Nov 18 '25 07:11

user568109