我已经阅读了关于Nginxconfiguration适合SSE的一系列不同的问题,并提出了一些关于使用什么设置的令人困惑的结果:
那么正确的答案是什么?
服务器发送的事件(SSE)是一个长时间运行的HTTP连接**,所以对于初学者我们需要这个:
proxy_http_version 1.1; proxy_set_header Connection "";
注意:默认情况下,HTTP / 1.1中的TCP连接是持久的,因此将Connection标头设置为空是正确的,并且是Nginx的build议。
现在旁边; SSE响应不会设置Content-Length报头,因为他们不知道将发送多less数据,而是需要使用Transfer-Encoding报头[0] [1],它允许stream式连接。 还要注意:如果不添加Content-Length,大多数HTTP服务器将设置Transfer-Encoding: chunked; 为你。 奇怪的是,HTTP分块警告并造成混乱。
在W3 EventSource描述的Notes部分,这个混淆源于一个模糊的警告:
作者也警告说,HTTP分块会对这个协议的可靠性产生意想不到的负面影响。 在可能的情况下,应该禁用分块处理事件stream,除非消息的速率足够高,否则无关紧要。
这将导致人们相信Transfer-Encoding: chunked; 对上证所来说是一件坏事。 然而,这不一定是这种情况,当你的web服务器正在为你分块的时候(不知道你的数据的信息),这只是一个问题。 所以,虽然大多数post会build议chunked_transfer_encoding off; 这在典型情况下是不必要的[3]。
大多数问题来自于在应用程序服务器和客户端之间进行任何types的缓冲。 默认情况下[4],Nginx使用proxy_buffering: on (根据你的应用程序,也可以看看uwsgi_buffering和fastcgi_buffering ),并且可以select缓冲你想要发送给客户端的数据块。 这是一件坏事,因为SSE的实时性破坏了。
但是,并不是将proxy_buffering: off为proxy_buffering: off ,而是将所有X-Accel-Buffering: no作为应用程序服务器代码中的响应头进行添加,以便仅为基于SSE的缓冲closures(如果可以)响应,而不是来自您的应用程序服务器的所有响应。 奖金:这将同样适用于uwsgi和fastcgi。
所以真正重要的设置实际上是应用程序服务器响应头文件:
Content-Type: text/event-stream; Cache-Control: no-cache; X-Accel-Buffering: no;
并可能执行一些ping机制,以便连接不会闲置太久。 这样做的危险在于,Nginx会使用keepalive设置closures空闲连接。
[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