Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EventSource permanent auto reconnection

I am using JavaScript EventSource in my project front-end.

Sometimes, the connection between the browser and the server fails or the server crashes. In these cases, EventSource tries to reconnect after 3 seconds, as described in the documentation.

But it tries only once. If there is still no connection, the EventSource stops to try reconnection and the user have to refresh the browser window in order to be connected again.

How I can prevent this behavior? I need the EventSource to try reconnecting forever, not only once.

The browser is Firefox.

like image 630
johnfound Avatar asked Feb 17 '14 14:02

johnfound


1 Answers

I deal with this by implementing a keep-alive system; if the browser reconnects for me that is all well and good, but I assume sometimes it won't work, and also that different browsers might behave differently.

I spend a fair few pages on this in chapter five of my book (Blatant plug, find it at O'Reilly here: Data Push Applications Using HTML5 SSE), but if you want a very simple solution that does not require any back-end changes, set up a global timer that will trigger after, say, 30 seconds. If it triggers then it will kill the EventSource object and create another one. The last piece of the puzzle is in your event listener(s): each time you get data from the back-end, kill the timer and recreate it. I.e. as long as you get fresh data at least every 30 seconds, the timer will never trigger.

Here is some minimal code to show this:

var keepAliveTimer = null;

function gotActivity(){
  if(keepaliveTimer != null)clearTimeout(keepaliveTimer);
  keepaliveTimer = setTimeout(connect, 30 * 1000);
}

function connect(){
  gotActivity();
  var es = new EventSource("/somewhere/");
  es.addEventListener('message', function(e){
    gotActivity();
    },false);
}
...
connect();

Also note that I call gotActivity() just before connecting. Otherwise a connection that fails, or dies before it gets chance to deliver any data, would go unnoticed.

By the way, if you are able to change the back-end too, it is worth sending out a blank message (a "heartbeat") after 25-30 seconds of quiet. Otherwise the front-end will have to assume the back-end has died. No need to do anything, of course, if your server is sending out regular messages that are never more than 25-30 seconds apart.

If your application relies on the Event-Last-Id header, realize your keep-alive system has to simulate this; that gets a bit more involved.

like image 59
Darren Cook Avatar answered Sep 20 '22 12:09

Darren Cook