首页 > 解决方案 > 使用 Nginx 时 SSE 事件数据被切断

问题描述

我正在使用 React 和 Flask 实现一个 Web 界面。该接口的一个组件是服务器发送的事件,用于在数据库中更新数据时更新前端的数据。这个数据非常大,一个事件可能包含超过 16000 个字符。

React 前端使用一个反向代理到烧瓶后端,以便将 API 请求转发给它。当直接访问这个后端时,这与 SSE 一起工作得很好,并且数据按预期推送。但是,当使用 Nginx 提供反向代理时,会发生一些奇怪的事情。似乎 nginx 缓冲和分块事件流,并且在填充大约 16000 个字符之前不会发送结果。如果事件中的数据小于这个值,则意味着前端将不得不等待,直到发送更多事件。如果来自事件的数据较大,则意味着告诉 EventSource 已收到消息的换行符不是事件的一部分。这导致前端在发送事件 X+1 时接收到事件 X(即,当换行符实际出现在流中时)。

这是使用 nginx 时的响应标头:

HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 19 Nov 2020 13:10:49 GMT
Content-Type: text/event-stream; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive

这是直接运行flask run和访问端口时的响应标头(gunicorn稍后我将使用,但我进行了测试flask run以确保 nginx 是问题而不是 gunicorn):

HTTP/1.0 200 OK
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-transform
Connection: keep-alive
Connection: close
Server: Werkzeug/1.0.1 Python/3.7.6
Date: Thu, 19 Nov 2020 13:23:54 GMT

这是 nginx 配置sites-available

upstream backend {
        server 127.0.0.1:6666;
}

server {
        listen 7076;
        root <path/to/react/build/>;
        index index.html;

        location / {
                try_files $uri $uri/ =404;
        }

        location /api {
                include proxy_params;
                proxy_pass http://backend;
                proxy_set_header Connection "";
                proxy_http_version 1.1;
                proxy_buffering off;
                proxy_cache off;
                chunked_transfer_encoding off;
        }
}

此配置基于此处提到的答案。

如您所见,两者proxy_bufferingchunked_transfer_encoding关闭,所以我不明白为什么会这样。我也尝试过更改缓冲区大小,但没有任何运气。

谁能告诉我为什么会这样?如何修复它,以便使用 nginx 导致与我不使用它时相同的行为?谢谢你。

标签: nginxflaskreverse-proxyserver-sent-eventschunked-encoding

解决方案


上面提到的配置确实有效。但是,我使用的服务器包含另一个覆盖我的配置的 nginx 配置。当特定于 SSE 的配置参数也添加到该配置中时,事情开始按预期工作。所以这个问题一直都是正确的。


推荐阅读