Safari服务器已发送事件(SSE)无限循环 [英] Safari Server Sent Event (SSE) Infinte Loop

查看:220
本文介绍了Safari服务器已发送事件(SSE)无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Safari 9和Safari 10中遇到服务器发送事件(SSE)的问题.SSE连接打开,立即关闭,然后无限循环地重新连接.

I am having issues with server-send events (SSE) in Safari 9 and Safari 10. The SSE connection opens, immediately closes and then reconnects in an infinite loop.

这是客户端代码:

var events = new EventSource("/stream/events")

这些是http响应标头:

These are the http response headers:

> GET /stream/events HTTP/1.1
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Cache-Control: no-cache
< Connection: keep-alive
< Content-Type: text/event-stream
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Last-Modified: Tue, 19 Sep 2017 05:28:22 GMT
< Strict-Transport-Security: max-age=31536000
< X-Accel-Buffering: no
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-Xss-Protection: 1; mode=block
< Date: Tue, 19 Sep 2017 05:28:22 GMT
< Transfer-Encoding: chunked

一些附加说明:

  • 我在Chrome和Firefox中进行了测试,无法重复
  • 我在Safari中进行了测试,没有https ,并且无法重复
  • 我在Safari中使用https 在Safari中进行了测试,并且可以重复
  • https证书是使用Lets Encrypt自动生成的
  • 后端服务器是用Go编写的,默认情况下使用http/2
  • I tested in Chrome and Firefox and cannot repeat
  • I tested in Safari without https and cannot repeat
  • I tested in Safari with https and can repeat
  • The https certificates are auto-generated using Lets Encrypt
  • The backend server is written in Go and uses http/2 by default

我只能在Safari中使用https重复这一事实,这很有趣.因此,我想知道SSE和https是否存在任何已知问题,或者在这里是否存在其他配置错误或丢失的信息.

The fact that I can only repeat in Safari with https is interesting. I am therefore wondering if there are any known issues with SSE and https, or if there is anything else I might be misconfiguring or missing here.

编辑

我已隔离问题并找到与协议的关联.启用http2协议后,我可以重现此问题.在服务器上禁用http2时,我不再能够重现此问题.

I have isolated the problem and found a correlation to the protocol. When the http2 protocol is enabled, I am able to reproduce this issue. When http2 is disabled on the server, I am no longer able to reproduce this problem.

我使用以下服务器补丁进行了验证:

I used the following server patch to verify:

--- before.go   2017-09-19 13:31:45.668891000 -0400
+++ after.go    2017-09-19 13:31:55.100891000 -0400
@@ -2,6 +2,6 @@
            Addr: ":443",
            TLSConfig: &tls.Config{
                GetCertificate: manager.GetCertificate,
-               NextProtos:     []string{"h2", "http/1.1"},
+               NextProtos:     []string{"http/1.1"},
            },
        }

推荐答案

我敢打赌Safari javascript控制台充满了:

I bet that the Safari javascript console is filled with:

[Error] Failed to load resource: The operation couldnt be completed. Protocol error

,很可能是协议错误. http/2的部分8.1.2.2 表示

and it is very probably a protocol error. The section 8.1.2.2 of the http/2 says that

端点不得生成包含特定于连接的报头字段的HTTP/2消息;任何包含特定于连接的报头字段的消息都必须被视为格式错误.

An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields; any message containing connection-specific header fields MUST be treated as malformed.

我无法确保这是您的问题,因为我看不到您的http/2尝试的HTTP标头,但是许多http/2实现选择在多个用户代理(包括Safari和curl决定对此事严格.

I cannot ensure that this is your problem, since I don't see the HTTP headers of your http/2 attempt, but many http/2 implementations made the choice of still sending Connection: Keep-Alive headers while several user agents, including Safari and curl, decided to be strict on the matter.

更新

我应该补充指出,错误的标头(很可能是标准的连接:保持活动"标头)可以由任何服务器端组件(通常是应用程序的SSE服务器端组件)设置,而不是由容器本身设置的.我敢打赌,容器应该在http/2中对其进行过滤.

I should add that the faulty header, most probably the standard `Connection: keep-alive' one, can have been set by any server side component (typically the SSE server-side component of the application), not the container itself. I bet that containers should filter it in http/2.

这篇关于Safari服务器已发送事件(SSE)无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆