Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

server-sent events Golang

I would like to do some one way streaming of data and am experimenting with SSE vs Websockets.

Using SSE form a golang server I'm finding it confusing on how to notify the client when sessions are finished. (eg the server has finished sending the events or the server suddenly goes offline or client looses connectivity)

One thing I need is to reliably know when these disconnect situations. Without using timeouts etc. My experiments so far , when I take the server offline the client gets EOF. But I'm having trouble trying to figure out how to signal from the server to the client that a connection is closed / finished and then how to handle / read it? Is EOF a reliable way to determine a closed / error / finished state?

Many of the examples with SSE fail to show client good client connection handling.

Would this be easier with Websockets?

Any experiences suggestions most appreciated.

Thanks

like image 995
mcbain83 Avatar asked Oct 20 '22 07:10

mcbain83


1 Answers

The SSE standard requires that the browser reconnect, automatically, after N seconds, if the connection is lost or if the server deliberately closes the socket. (N defaults to 5 in Firefox, 3 in Chrome and Safari, last time I checked.) So, if that is desirable, you don't need to do anything. (In WebSockets you would have to implement this kind of reconnect for yourself.)

If that kind of reconnect is not desirable, you should instead send a message back to the client, saying "the show is over, go away". E.g. if you are streaming financial data, you might send that on a Friday evening, when the markets shut. The client should then intercept this message and close the connection from its side. (The socket will then disappear, so the server process will automatically get closed.)

In JavaScript, and assuming you are using JSON to send data, that would look something like:

var es = EventSource("/datasource");
es.addEventListener("message", function(e){
  var d = JSON.parse(e.data);
  if(d.shutdownRequest){
    es.close();
    es=null;
    //Tell user what just happened.
    }
  else{
    //Normal processing here
    }
  },false);

UPDATE:

You can find out when the reconnects are happening, by listening for the "close" event, then looking at the e.target.readyState

es.addEventListener("error", handleError, false);
function handleError(e){
  if(e.target.readyState == 0)console.log("Reconnecting...");
  if(e.target.readyState == 2)console.log("Giving up.");
  }

No other information is available, but more importantly it cannot tell the difference between your server process deliberately closing the connection, your web server crashing, or your client's internet connection going down.

One other thing you can customize is the retry time, by having the the server send a retry:NN message. So if you don't want quick reconnections, but instead want at least 60 seconds between any reconnect attempts do this have your server send retry:60.

like image 103
Darren Cook Avatar answered Oct 22 '22 02:10

Darren Cook