我已经制作了一个小型Sinatra应用程序,可以或多或少地实时跟踪我们的一些公司数据。
设置与dashing.io/非常相似:
这一切都运作良好,但是,我注意到如果我让工作的运行频率低于每分钟,客户端将一直断开连接并重新连接。让我解释一下:
订阅javascript代码如下所示:
<script type="text/javascript">
var source = new EventSource('/stream/channels-energy');
source.onopen = function(event) {
console.log("Connection opened", event)
}
source.onerror = function(event) {
console.log("Connection error", event)
}
source.onmessage = function(event) {
var data_energy = JSON.parse(event.data);
console.log("Time: " + event.lastEventId + "Length: " + Object.keys(data_energy).length);
}
</script>
如果我让这项工作每30秒运行一次,那么每件事情都会完美无缺。在Chrome(或Firefox)中的控制台中查看以下内容:
Connection opened Event
Time: 2016-03-13T13:33:39.625ZLength: 2854
Time: 2016-03-13T13:34:09.656ZLength: 2854
Time: 2016-03-13T13:34:39.698ZLength: 2854
Time: 2016-03-13T13:35:09.395ZLength: 2854
Time: 2016-03-13T13:35:39.493ZLength: 2854
Time: 2016-03-13T13:36:09.592ZLength: 2854
Time: 2016-03-13T13:36:39.674ZLength: 2854
但是,如果我将作业间隔调整为3分钟,则控制台会显示客户端经常断开连接:
Connection opened Event
Time: 2016-03-13T13:00:16.018ZLength: 2909
Connection error Event
Connection opened Event
Connection error Event
Connection opened Event
Connection error Event
Connection opened Event
Time: 2016-03-13T13:03:15.912ZLength: 2891
Connection error Event
Connection opened Event
Connection error Event
Connection opened Event
Connection error Event
Connection opened Event
Time: 2016-03-13T13:06:15.857ZLength: 2891
Connection error Event
Connection opened Event
Connection error Event
Connection opened Event
Connection error Event
Connection opened Event
...
客户端似乎仍然能够检索输入数据,因此最终结果不会受此影响。我的问题是,这是否一直断开/重新连接正常行为?无论数据流的频率如何,客户端都不应该保持连接打开状态吗?
答案 0 :(得分:1)
是的,无论发送什么数据,客户端(浏览器)都会保持套接字打开。
这可能是因为你的后端服务器在安静时关闭套接字。但是,它也可能是您的本地ISP关闭套接字。您可以通过从另一个物理位置进行测试来诊断它是什么。
然而,一个很好的解决方案,很好地涵盖了任何一个原因,是添加一个keep-alive(aka heartbeat)信号。这是从服务器发送到客户端的,例如每N秒,例如, N = 50。
对于网络级别的断开连接,发送SSE注释就足够了。但我喜欢做的是发送一个正确的信息。这允许客户端跟踪它从服务器上次听到的时间,并且如果它怀疑出现了问题,即如果没有数据在N + 10秒内到达,则启动它自己的断开连接和重新连接。 (这种情况很少见,但有时会发生。)