Error 404 when connecting to websocket behind nginx proxy_pass
I would like to serve up a websocket behind a location on my webserver. For example, if my domain is http://mydomain
I would like my websocket to be available at ws://mydomain/ws
.
I am running a local websocket server on port 8080, and I can connect to it using both localhost and the local network ip (192.168.1.100). When I try to access the websocket using this path, I get Error: Unexpected server response (404)
.
Here is my nginx config in an attempt to do this:
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;
}
}
I've found several previous questions on the internet but none seem to address this issue; I'm not even sure if this type of proxy is possible.
I originally had a websocket protocol defined "chat" and I was getting a Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
error; removing it fixes it for now.
My websocket server is using a locally-built NetCoreServer from https://github.com/chronoxor/NetCoreServer and is nearly identical to the example unsecure websocket server example they have. Let me know if there's any additional information I can give that would help to resolve this issue.
Solution 1:
Solution is to remove all not mandatory headers, remove upstream
function and point all websockets endpoints, no the main server without endpoints. For me main server was ws.example.com
and i have ws.example.com/chat
and ws.example.com/notifications
so i set it like this:
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;}
If you have used different endpoints for each service, upstream won't work, but i have no idea why.
I almost forgot. My $http_upgrade variable is mapped like this:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
In your case it will be caused of wrong $connection_upgrade
you took it from SoF and i made same mistake:
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/";
}