nginx - 使用 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_buffering
都chunked_transfer_encoding
关闭,所以我不明白为什么会这样。我也尝试过更改缓冲区大小,但没有任何运气。
谁能告诉我为什么会这样?如何修复它,以便使用 nginx 导致与我不使用它时相同的行为?谢谢你。
解决方案
上面提到的配置确实有效。但是,我使用的服务器包含另一个覆盖我的配置的 nginx 配置。当特定于 SSE 的配置参数也添加到该配置中时,事情开始按预期工作。所以这个问题一直都是正确的。
推荐阅读
- javascript - 一些网站要求您下载他们的 AppStore 应用程序 - 我该如何为我的网站执行此操作?
- laravel - Laravel - 有两列的表,每列都有来自不同表的 ID
- python - 使用递归避免编写嵌套循环数等于层数?
- java - 如何解决创建名称为“dataFlowController”的错误 bean 的错误
- php - 未找到基表或视图:1146 表 'admin.model' 不存在
- html - 我正在使用 JqueryUI Sortable,但我无法让句柄选项工作。我用错了吗?
- python - 在 Python 中绘制一个通用函数
- c# - 如何导出C#编写的接口实现TLB生成的Delphi代码
- python - 如何从 asyncpg 库连接到 pgbouncer?
- python - 添加两个不同的子类作为它们的公共超类