Nginx websocket 将适用于单个响应或根本不适用,似乎是随机的
Posted
技术标签:
【中文标题】Nginx websocket 将适用于单个响应或根本不适用,似乎是随机的【英文标题】:Nginx websocket will work for a single response or not at all, seemly at random 【发布时间】:2020-10-30 19:16:40 【问题描述】:我一直在通过 nginx 在 Asp.net core 3 上使用 SignalR 来将 Unity3d 应用程序联网。在我通过 Kestral 进行的本地构建中,websockets 工作得很好。但是,一旦我通过 Nginx 代理我的 WebApp,我的 websocket 将用于单个响应或根本不工作,似乎是随机的。想法?
我当前的 nginx 构建配置:
server
listen 80;
server_name ip domain.com www.domain.com;
return 301 https://$host$request_uri;
server
listen 443 ssl http2;
server_name ip domain.com www.domain.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#make sure to check for more up to date ciphers
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
root /var/www/html;
location /
proxy_pass http://localhost:5000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep_alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
location /notifications
proxy_pass http://localhost:5000/notifications/;
include /etc/nginx/proxy_params;
proxy_http_version 1.1;
set $http_upgrade "websocket";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
proxy_read_timeout 3600;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffers 8 32k;
proxy_buffer_size 64k;
location ~^/identity
rewrite ^/identity/login? /login/ break;
proxy_pass http://localhost:5050;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
【问题讨论】:
嗨@re-fuse,写第一篇文章并不容易。在我看来,您可能需要考虑向社区提供更多信息,而不仅仅是粘贴配置文件。例如,当您说它随机工作时,您可能会提供更多详细信息。此外,您可能需要说明您已经尝试解决的问题。 @RonaldRink'd-fens' 嘿!感谢您的答复。我在下面添加了一个答案。这是下划线 Nginx 行为的问题。这种行为在早期版本中不存在,因为我的代理设置在这篇文章之前有效。让我相信这是最近的行为更新。 【参考方案1】:问题: 启用 signalr 的调试日志后,我发现我的 websocket 被降级到 HTTP 1.0,这解释了为什么我在使用 websockets 时只收到一次或全部来自服务器的响应。
我的应用程序(Unity Game)支持这两种协议,如果您查看我的配置,您会发现分别配置为 HTTP 和 Websockets 的“location /”块和“location /notifications”块。我的应用程序使用 http 进行身份验证,使用 websockets 来实际玩游戏。因此,Nginx 在通过 http 进行身份验证后保留了原始的 http 代理标头,然后调用“/notifications”端点,尽管它是为 websockets 设置的(我期望的行为是基于我要创建的配置的新 websocket 连接)。
修复: 我更改了“location/”(我的常规 http 端点)块标头以支持 HTTP 1.1,如下所示:
location /
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
根据 asp.net 核心文档清理 websocket 块:
location /notifications
proxy_pass http://localhost:5000/notifications/;
# include /etc/nginx/proxy_params;
proxy_http_version 1.1;
# Configure WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
#proxy_cache_bypass $http_upgrade;
proxy_cache off;
# Configure ServerSentEvents
proxy_buffering off;
# Configure LongPolling
proxy_read_timeout 100s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; $
proxy_set_header X-Forwarded-Proto $scheme;
在此编辑之后,我的 HTTP 和 websocket 端点都按预期工作。我不确定为什么标头会保留在 websocket“位置/通知”块中,但我确信某处有一些细微的 Nginx 文档。
希望这对将来的某人有所帮助。
【讨论】:
以上是关于Nginx websocket 将适用于单个响应或根本不适用,似乎是随机的的主要内容,如果未能解决你的问题,请参考以下文章
Websocket 适用于 EC2 url,但不适用于 ElasticBeanstalk URL
docker 中的 nginx + websocket 代理 + Ratchet
适用于 Android 和 iOS 的基于 websocket 的 MQTT