server-sent events Golang
Asked Answered
H

1

6

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

Hydroxyl answered 7/7, 2015 at 12:31 Comment(3)
Could you send a data message from the server indicating that the client should close the connection, and then having the client expilicitly call close on the connection?Jueta
what sse client are you using ? EventSource?Jueta
I was using github.com/JanBerktold/sse but my question is a little more general that a specific lib implementation. I think I might try work out a good client server example..Hydroxyl
C
3

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.

Castorena answered 7/7, 2015 at 21:48 Comment(2)
Ok I see, maybe I was just working under the assumption that there was something in the connection protocol I could use. So essentially I would need to create some sort of disconnect message for my client then handle it. I guess that could work ok. My specific client might need to stricter rules around handling disconnects ie, shutdown the app if it looses connection etc..Thanks for the info!Hydroxyl
Just checked my book, and that is covered on p.59 - using the error handler. It is not very useful, and I don't recommend you use it for your case, but I will update my answer.Castorena

© 2022 - 2024 — McMap. All rights reserved.