服务器推送事件 Golang

5
我希望进行一些单向数据流的实验,并尝试使用SSE和Websockets。从一个golang服务器使用SSE时,我发现很难通知客户端会话何时结束(例如,服务器已经完成发送事件或服务器突然关闭或客户端失去连接)。其中一个需要解决的问题是可靠地了解这些断开连接的情况,而不使用超时等。到目前为止,我的实验表明,当我将服务器下线时,客户端会收到EOF。但是,我遇到了困难,试图弄清楚如何从服务器向客户端发出信号,表示连接已关闭/结束,然后如何处理/读取它?EOF是确定关闭/错误/完成状态的可靠方法吗?许多SSE示例未能展示良好的客户端连接处理。使用Websockets是否更容易?如果您有任何经验或建议,请告诉我。谢谢!

你能否从服务器发送一个数据消息,指示客户端关闭连接,然后让客户端显式地调用连接关闭吗? - dm03514
1
你在使用什么SSE客户端?EventSource吗? - dm03514
我之前使用过 https://github.com/JanBerktold/sse,但我的问题比特定库的实现更为普遍。我想我可以尝试编写一个好的客户端服务器示例。 - mcbain83
1个回答

3
SSE标准要求浏览器在N秒后自动重新连接,如果连接丢失或服务器故意关闭套接字。(在Firefox中,默认值为5,在Chrome和Safari中,默认值为3,上次我检查过。)所以,如果需要这样做,您不需要做任何事情。(在WebSockets中,您必须自己实现这种重新连接。)
如果不需要这种重新连接,则应向客户端发送一条消息,指示“演出结束,请离开”。例如,如果您正在流式传输金融数据,则可以在星期五晚上发送此消息,当市场关闭时。然后客户端应截取此消息并从其端关闭连接。(然后套接字将消失,因此服务器进程将自动关闭。)
在JavaScript中,并假设您正在使用JSON发送数据,代码大致如下:
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);

更新:

通过监听 "close" 事件,您可以了解重新连接发生的时间,然后查看 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.");
  }

没有其他信息可用,但更重要的是它无法区分您的服务器进程故意关闭连接、Web服务器崩溃还是客户端的互联网连接中断。

另一件您可以自定义的事情是重试时间,通过让服务器发送 retry:NN 消息来实现。因此,如果您不想进行快速重新连接,而是希望在任何重新连接尝试之间至少等待 60 秒,请让您的服务器发送 retry:60


好的,我明白了。也许我只是在假设连接协议中有一些我可以使用的东西。因此,我需要为我的客户端创建某种断开连接消息,然后处理它。我想这可能会很好地工作。我的特定客户端可能需要更严格的规则来处理断开连接,例如,如果失去连接,则关闭应用程序等。感谢您提供的信息! - mcbain83
刚刚查了一下我的书,在第59页中有介绍如何使用错误处理程序。不过,那并不是很有用,我不建议你在这种情况下使用它,但我会更新我的答案。 - Darren Cook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接