How to determine that an SSE connection was closed?

sse detect client disconnect
server sent events c#
node sse
sse connection limit
close sse connection
express sse
react server-sent events
sse vs websockets

We have an SSE connection open in javascript which can time to time get closed, either because of server restarts or other causes. In that case it would be good to reestablish the connection. How to do it? Is there a way to find out on the client side that the connection was closed?

Here: https://developer.mozilla.org/en-US/docs/Web/API/EventSource I found only a way to close the connection, but no callback or a test method for determining whether the connection is still alive.

Thank you for your help.

If the connection is closed (in such a way that the browser can realize it), it will auto-connect. And it tends to do this quickly (default is 3 seconds in Chrome, 5 seconds in Firefox). readyState will be CONNECTING (0) while it is doing this. It is only ever CLOSED (2) if there was some problem connecting in the first place (e.g. due to a CORS issue). Once CLOSED, it does not retry.

I prefer to add a keep-alive mechanism on top, as the browser cannot always detect dead sockets (not to mention a remote server process that is locked up, etc.). See ch.5 of Data Push Apps with HTML5 SSE for detailed code, but basically it involves having the server send a message every 15 seconds, then a JavaScript timer that runs for 20 seconds, but is reset each time a message is received. If the timer ever does expire, we close the connection and reconnect.

EventSource.close(), The SSE standard defines an EventSource API that opens a connection to the is usually because the server closed the connection in such a way as to tell the  How to determine that an SSE connection was closed? javascript,server-sent-events. If the connection is closed (in such a way that the browser can realize it), it will auto-connect. And it tends to do this quickly (default is 3 seconds in Chrome, 5 seconds in Firefox). readyState will be CONNECTING (1) while it is doing this. It is only ever

Update -

EventSource now has three event handlers: onerror, onmessage, and onopen. These should be enough to handle everything you need on the client side.

Something like this:

ssEvent = new EventSource( eventUrl );
ssEvent.onopen = function (evt) {
  // handle newly opened connection
}
ssEvent.onerror = function (evt) {
  // handle dropped or failed connection
}
ssEvent.onmessage = function (evt) {
  // handle new event from server
}

Ref: mozilla.org : EventSource : Event handlers

Understanding Server-Sent Events – kaazing.io, If you're familiar with the HTTP protocol, you know that fetching data revolves around When communicating using SSE s, a server can push data to your app The magical part is that whenever the connection is closed, the  When connection is closed - you are freeing it indeed, but anyway long requests to rails server are evil and can lock up your server. If these are rare and you do not expect more than 1-2 in parallel - you can get away with current setup, otherwise it's better to handle them in background jobs with progress delivered via anycable (users will see that their job is waiting to start, then

Check readyState property:

var es = new EventSource();

// Сheck that connection is not closed
es.readyState !== 2;
// or
es.readyState !== EventSource.CLOSED;

Stream Updates with Server-Sent Events, When a connection is finally closed, there's no way to “reopen” it. If we'd like to We can query this property to know the state of EventSource . After you determine when to troubleshoot an issue instead of migrating or redeploying, you can identify and resolve specific SSH errors based on which phase of a successful SSH connection you need to debug. When connecting an SSH client to an SSH server, basic network connectivity must be properly established.

It is best not to try to determine if the connection was closed. I do not think there is a way to do it. 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 retry
var 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();

Server Sent Events, If I understand correctly, there's no way to detect if SSE connection was closed until you send something. If server is passive and don't initiate  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more How to close a “Server-Sent Events”-connection on the server?

Hook for SSE disconnects · Issue #338 · pedestal/pedestal · GitHub, Close SSE connection if server sends a "CLOSE" message ID. EventSource How does the browser know the ID, type, and boundary of each message? This is  In order to determine if the connection has actually been closed (or if in fact new data is available to be read), we need to call read again. Bad. Bad. The solution to the problem is called recv , and it does a wonderful job.

Browser APIs and Protocols: Server-Sent Events (SSE), 6. Close SSE connection if server sends a “CLOSE” message ID How does the browser know the ID, type, and boundary of each message? This is where the  Single Sign-On authentication is here to stay. Decentralized systems are becoming more and more common and authentication is an essential aspect of all of them. SSO solves a big problem: how to manage the increasing number of users across a whole ecosystem of applications and services.

16. Server-Sent Events (SSE) - High Performance Browser , So, SSE typically reuses one connection for more messages (called events). Since Jersey runtime does not implicitly close the connection to the client fill the data with a JAXB annotated bean instance and define media type to JSON. The AD FS proxy service is designed to be installed on a non-domain joined computer. Therefore, the communication between the AD FS proxy server and the AD FS Federation Service can't be based on an Active Directory trust or credentials. Instead, the communication between these two server roles is established by using a token that is issued to

Comments
  • thank you for the explanation, I also thought about adding a heartbeat message coming from the server, somehow I wasn't sure whether I can trust the readyState flag.
  • FYI, the EventSource constants are CLOSED: 2, CONNECTING: 0, OPEN: 1 (checked in Safari 11.1).
  • @terrymorse Thanks. I double-checked against both developer.mozilla.org/en-US/docs/Web/API/EventSource and my book (!), and you right. Fixed. Sorry for the typo.