我在Safari 9和Safari 10中遇到服务器发送事件(SSE)问题.SSE连接打开,立即关闭,然后以无限循环重新连接。
这是客户端代码:
var events = new EventSource("/stream/events")
这些是http响应标头:
> 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
一些补充说明:
我只能在Safari中使用https重复这一事实很有意思。因此,我想知道SSE和https是否存在任何已知问题,或者如果还有其他任何问题,我可能会在此处进行错误配置或遗漏。
修改
我已经隔离了问题并发现了与协议的相关性。启用http2协议后,我可以重现此问题。在服务器上禁用http2时,我无法再重现此问题。
我使用以下服务器补丁验证:
--- 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"},
},
}
答案 0 :(得分:1)
我敢打赌Safari javascript控制台充满了:
[Error] Failed to load resource: The operation couldnt be completed. Protocol error
,很可能是协议错误。 http / 2的section 8.1.2.2表示
端点不得生成包含特定于连接的报头字段的HTTP / 2消息;包含特定于连接的标头字段的任何消息都必须被视为格式错误。
我无法确保这是您的问题,因为我看不到您的http / 2尝试的HTTP标头,但是许多http / 2实现选择在多个用户代理仍发送Connection: Keep-Alive
标头的情况下进行选择包括Safari和curl在内,决定对此事严格执行。
更新
我应该补充指出,错误的标头(很可能是标准的“连接:保持活动”标头)可以由任何服务器端组件(通常是应用程序的SSE服务器端组件)设置,而不是由容器本身设置的。我敢打赌,容器应该在http / 2中对其进行过滤。