我已经阅读了很多关于什么 Nginx 配置适合 SSE 的不同问题,并提出了一些关于使用哪些设置的令人困惑的结果:
那么正确答案是什么?
c4u*_*elf 66
服务器发送事件 (SSE) 是一个长时间运行的 HTTP 连接**,所以对于初学者来说,我们需要这个:
proxy_http_version 1.1;
proxy_set_header Connection "";
Run Code Online (Sandbox Code Playgroud)
注意:HTTP/1.1 中的 TCP 连接默认是持久的,因此将 Connection 标头设置为空是正确的,这是 Nginx 的建议。
现在是一边;SSE 响应不设置 Content-Length 标头,因为它们不知道将发送多少数据,而是需要使用 Transfer-Encoding 标头 [0][1],它允许流连接。另请注意:如果您不添加 Content-Length,大多数 HTTP 服务器将为Transfer-Encoding: chunked;
您设置。奇怪的是,HTTP 分块警告并导致混淆。
混淆源于 W3 EventSource 描述的注释部分中有些模糊的警告:
作者还被警告说,HTTP 分块可能对该协议的可靠性产生意想不到的负面影响。在可能的情况下,应禁用分块以提供事件流,除非消息速率足够高以至于无关紧要。
这会让人们相信Transfer-Encoding: chunked;
对 SSE 来说是一件坏事。但是:情况并非一定如此,只有当您的网络服务器为您进行分块(不知道有关您的数据的信息)时才会出现问题。因此,虽然大多数帖子会建议chunked_transfer_encoding off;
在典型情况下添加这不是必要的[3]。
大多数问题来自应用服务器和客户端之间的任何类型的缓冲。默认情况下[4],Nginx 使用
proxy_buffering on
(也看看uwsgi_buffering
并fastcgi_buffering
取决于您的应用程序)并可能选择缓冲您想要发送给客户端的块。这是一件坏事,因为 SSE 的实时性被打破了。
但是,proxy_buffering off
实际上最好(如果可以的话)X-Accel-Buffering: no
在应用程序服务器代码中添加作为响应标头,而不是针对所有内容进行缓冲,以便仅关闭基于 SSE 的响应的缓冲,而不是关闭来自应用程序的所有响应的缓冲服务器。奖励:这也适用于uwsgi
和fastcgi
。
所以真正重要的设置实际上是应用服务器响应头:
Content-Type: text/event-stream;
Cache-Control: no-cache;
X-Accel-Buffering: no;
Run Code Online (Sandbox Code Playgroud)
并且可能会实施一些 ping 机制,以便连接不会闲置太久。这样做的危险是 Nginx 将使用keepalive
设置关闭空闲连接。
[0] https://tools.ietf.org/html/rfc2616#section-3.6
[1] https://en.wikipedia.org/wiki/Chunked_transfer_encoding
[2] https://www.w3.org/TR /2009/WD-eventsource-20091029/#text-event-stream
[3] https://github.com/whatwg/html/issues/515
[4] http://nginx.org/en/docs/http/ ngx_http_proxy_module.html#proxy_buffering
[5] https://tools.ietf.org/html/rfc7230#section-6.3
[6] https://gist.github.com/CMCDragonkai/6bfade6431e9ffb7fe88
归档时间: |
|
查看次数: |
26629 次 |
最近记录: |