http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } # ... } server { listen 80; server_name domain.com; location /ws/ { proxy_pass http://localhost:8060; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } 

If you connect to port 8060, the socket server is working. And through nginx I can not configure proxying

Connect

 var socket = new WebSocket("ws://domain.com/ws"); 

Mistake

 WebSocket connection to 'ws://domain.com/ws' failed: Error during WebSocket handshake: Unexpected response code: 301 

If you add the last slash

 var socket = new WebSocket("ws://domain.com/ws/"); WebSocket connection to 'ws://domain.com/ws/' failed: Error during WebSocket handshake: Unexpected response code: 404 
  • Your socket server is configured to handle URL /ws/ ? Something tells me that he can only handle / , and you try to /ws/ open, to which he naturally answers 404 - andreymal
  • so in the location I specify / ws / - maximus
  • one
    Well, yes, that is why this /ws/ passed on to the socket server on port 8060, but it does not know how to handle /ws/ and gives an error 404. Most likely. - andreymal
  • Yes, location / ws didn’t think at all that aiohttp doesn’t treat urles like django, missed this moment - maximus
  • Please write separately to mark the decision - maximus

1 answer 1

When you write

 location /ws/ { proxy_pass http://localhost:8060; # ... } 

nginx sends to the socket server (your aiohttp, which hangs on port 8060) a request of the form ws://localhost:8060/ws/ - that is, it keeps the link that the browser sent. Your socket server should be able to handle just such a link, otherwise it can answer 404 - apparently, my inner telepath guessed that this is exactly what is happening.

You can throw a piece /ws/ out of the link by writing the following setting:

 location /ws/ { proxy_pass http://localhost:8060/; # ... } 

That is, just add a slash at the end of the proxy_pass . In this case, nginx does not transmit the original link as is, but bites off the piece specified in the location , and a request of the form ws://domain.com/ws/ will be redirected to ws://localhost:8060/ - and this is most likely a socket server will be able to process without additional changes in it.

Note that in the last example, a request of the form ws://domain.com/ws/чтототам/ will be redirected to ws://localhost:8060/чтототам/ - if you have such links, then I think it’s better not to do so avoid confusion and it is better to just teach aiohttp to recognize the link /ws/ .

More information about the proxy_pass behavior can be found in the nginx documentation .