![nginx proxy_pass 后面连接 websocket 时出现 404 错误](https://linux22.com/image/749461/nginx%20proxy_pass%20%E5%90%8E%E9%9D%A2%E8%BF%9E%E6%8E%A5%20websocket%20%E6%97%B6%E5%87%BA%E7%8E%B0%20404%20%E9%94%99%E8%AF%AF.png)
我想在我的网络服务器上的某个位置后面提供 websocket。例如,如果我的域名是,http://mydomain
我希望我的 websocket 在 处可用ws://mydomain/ws
。
我在端口 8080 上运行本地 websocket 服务器,我可以使用 localhost 和本地网络 ip (192.168.1.100) 连接到它。当我尝试使用此路径访问 websocket 时,我得到了Error: Unexpected server response (404)
。
下面是我为尝试执行此操作而配置的 nginx 配置:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:8080;
}
server {
listen 80;
listen [::]:80;
access_log /var/log/nginx/mydomain.access.log;
error_log /var/log/nginx/mydomain.error.log;
server_name mydomain;
location / {
alias /var/www/mydomain/htdocs;
index index.html;
try_files $uri $uri/ =404;
}
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://websocket;
}
}
我在网上找到了几个以前的疑问,但似乎没有一个解决这个问题;我甚至不确定这种类型的代理是否可行。
我最初有一个定义为“聊天”的 websocket 协议,但出现了错误Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
;删除它可以暂时解决问题。
我的 websocket 服务器使用的是本地构建的 NetCoreServer,来自https://github.com/chronoxor/NetCoreServer与他们提供的不安全 websocket 服务器示例几乎完全相同。如果我可以提供任何其他信息来帮助解决此问题,请告诉我。
答案1
解决方案是删除所有非强制标头,删除upstream
函数并指向所有 websockets 端点,没有没有端点的主服务器。对我来说,主服务器是ws.example.com
并且我有ws.example.com/chat
,ws.example.com/notifications
所以我将其设置为:
location /chat {
proxy_pass "http://127.0.0.1:2020/chat/";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /notifications
{
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass "http://127.0.0.1:2020/notifications/";
}
location / { return 405;}
如果您对每个服务使用了不同的端点,上游将无法工作,但我不知道为什么。
我差点忘了。我的 $http_upgrade 变量映射如下:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
在你的情况下,这可能是由于$connection_upgrade
你从 SoF 中获取错误而造成的,而我也犯了同样的错误:
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass "http://127.0.0.1:8080/ws/";
}