Is an EventSource (SSE) supposed to try to reconnect indefinitely? Is an EventSource (SSE) supposed to try to reconnect indefinitely? google-chrome google-chrome

Is an EventSource (SSE) supposed to try to reconnect indefinitely?


Server Side Events work differently in all of the browsers, but they all close the connection during certain circumstances. Chrome, for example, closes the connection on 502 errors while a server is restarted. So, it is best to use a keep-alive as others suggest or reconnect on every error. Keep-alive only reconnects at a specified interval that must be kept long enough to avoid overwhelming the server. Reconnecting on every error has the lowest possible delay. However, it is only possible if you take an approach that keeps server load to a minimum. Below, I demonstrate an approach that reconnects at a reasonable rate.

This code uses a debounce function along with reconnect interval doubling. It works well, connecting at 1 second, 4, 8, 16...up to a maximum of 64 seconds at which it keeps retrying at the same rate. I hope this helps some people.

function isFunction(functionToCheck) {  return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';}function debounce(func, wait) {    var timeout;    var waitFunc;        return function() {        if (isFunction(wait)) {            waitFunc = wait;        }        else {            waitFunc = function() { return wait };        }                var context = this, args = arguments;        var later = function() {            timeout = null;            func.apply(context, args);        };        clearTimeout(timeout);        timeout = setTimeout(later, waitFunc());    };}// reconnectFrequencySeconds doubles every retryvar reconnectFrequencySeconds = 1;var evtSource;var reconnectFunc = debounce(function() {    setupEventSource();    // Double every attempt to avoid overwhelming server    reconnectFrequencySeconds *= 2;    // Max out at ~1 minute as a compromise between user experience and server load    if (reconnectFrequencySeconds >= 64) {        reconnectFrequencySeconds = 64;    }}, function() { return reconnectFrequencySeconds * 1000 });function setupEventSource() {    evtSource = new EventSource(/* URL here */);     evtSource.onmessage = function(e) {      // Handle even here    };    evtSource.onopen = function(e) {      // Reset reconnect frequency upon successful connection      reconnectFrequencySeconds = 1;    };    evtSource.onerror = function(e) {      evtSource.close();      reconnectFunc();    };}setupEventSource();


I rewrote the solution of @Wade and after a little bit of testing I came to the conclusion that the functionality stayed the same with less code and better readability (imo).

One thing I did not understand was, why you clear the Timeout if the timeout variable gets set back to null every time you try to reconnect. So I just omitted it completely. And I also omitted the check if the wait argument is a function. I just assume it is, so it makes the code cleaner.

var reconnectFrequencySeconds = 1;var evtSource;// Putting these functions in extra variables is just for the sake of readabilityvar waitFunc = function() { return reconnectFrequencySeconds * 1000 };var tryToSetupFunc = function() {    setupEventSource();    reconnectFrequencySeconds *= 2;    if (reconnectFrequencySeconds >= 64) {        reconnectFrequencySeconds = 64;    }};var reconnectFunc = function() { setTimeout(tryToSetupFunc, waitFunc()) };function setupEventSource() {    evtSource = new EventSource("url");     evtSource.onmessage = function(e) {      console.log(e);    };    evtSource.onopen = function(e) {      reconnectFrequencySeconds = 1;    };    evtSource.onerror = function(e) {      evtSource.close();      reconnectFunc();    };}setupEventSource();


What I've noticed (in Chrome at least) is that when you close your SSE connection using close() function, it won't try to reconnect again.

var sse = new EventSource("...");sse.onerror = function() {    sse.close();};