Golang服务器默认超时(长轮询)服务器发送的事件调用.呼叫已关闭,如何保持其打开状态



我在Golang使用这个令人惊叹的SSE服务器(https://github.com/r3labs/sse)Heroku。

这里有一个超时限制:https://devcenter.heroku.com/articles/request-timeout#long-轮询和流式响应:

如果您正在发送流式响应,例如服务器发送的事件,您需要检测客户端何时挂断,并确保应用服务器立即关闭连接。如果服务器在不发送任何数据的情况下保持连接打开55秒,您将看到请求超时。

我知道在WebSocket的世界里有Keep Alive ping的概念。

我正在尝试使用此代码:

go func() {
for range time.Tick(time.Second * 1) {
fmt.Println("a second")
sseServer.Publish("test", &sse.Event{Data: []byte("ping")})
}
}()

使用这样一个简单的服务器:

httpServer := &http.Server{
//...
ReadTimeout:  "10s",
WriteTimeout: "10s",
}

但它不起作用。呼叫在10秒钟后关闭(并发出10次ping(。

我认为它在赫罗库也会失败。

我哪里错了?

我们可以只更改这些SSE调用的超时吗

还有别的办法吗

更新

我不需要准确检测断开连接的客户端,我根本不在乎。当服务器上发生什么事情时,我用它来刷新仪表板。

我不喜欢使用WebSocket来做一些简单的事情。

我想我没有很好地解释自己,因为我不太想使用ping来检测断开连接的客户端,而是因为我希望连接不会被中断(就像在Heroku上发生的那样(。

现在的情况

局部

如果我在Windows上完全删除ReadTimeout字段,但在Docker linux容器上也删除了,则连接不会停止,一切正常。

论HEROKU

由于在Heroku上,连接每55秒就会中断一次,我在第一篇文章中告诉过你,我用那个非常简单的代码尝试了这个循环,它成功了:SSE调用不再关闭!

剩下的问题

  1. 如何在任何情况下为所有其他调用(而不是SSE(设置默认ReadTimeout;我认为最好的做法是设置一个默认的ReadTimeout

怎么办

您不需要ReadTimeout;在初始EventSource/server Sent Events(SSE(连接之后,服务器将永远不会从客户端读取任何内容。

因此,使用SSE连接设置默认读取超时不是最佳做法,因为该读取超时总是会被命中。您永远无法通过最初的SSE GET请求发送更多的数据。

你应该把SSE基本上看作是一个永远不会关闭的GET请求,因为它几乎就是这样。这意味着它在大多数代理服务器中都能很好地工作,而在它不工作的地方(代理服务器应用自己的超时(,客户端会自动重新连接,这实际上是websocket中没有的一个非常好的特性(尽管大多数websocket客户端库都实现了它(。

你可能想通读这篇文章,了解更多关于SSE的伟大(但不那么伟大(之处:https://www.smashingmagazine.com/2018/02/sse-websockets-data-flow-http2/

关于你的另一个问题,你可能正在寻找你的HTTP路由库,它将允许你对一些GET请求应用超时,而不是其他请求,但问题是为什么;如果您试图防止资源流失,那么应该在所有端点上均匀地应用这种保护。

相关内容

  • 没有找到相关文章

最新更新