Ce face Proxy pentru WebSocket
O conexiune WebSocket începe ca o cerere HTTP/1.1 obișnuită care conține antetele Upgrade: websocket și Connection: Upgrade. Dacă serverul acceptă, răspunde cu codul 101 Switching Protocols, iar conexiunea TCP rămâne deschisă pentru mesaje în ambele sensuri.
Pentru că Upgrade și Connection sunt antete hop-by-hop (valabile doar pe o singură legătură), un reverse proxy nu le transmite automat mai departe. În plus, Nginx folosește implicit HTTP/1.0 către backend. De aceea, pentru WebSocket sunt obligatorii trei directive în location: proxy_http_version 1.1 și transmiterea explicită a celor două antete.
De asemenea, conexiunile WebSocket pot rămâne deschise minute sau ore fără trafic; cum proxy_read_timeout este implicit de 60s, conexiunea se va închide după un minut de liniște dacă nu mărești acest timeout sau dacă aplicația nu trimite periodic pachete ping/pong.
Opțiuni și argumente
| Opțiune / Parametru | Descriere |
|---|---|
proxy_http_version 1.1 |
Obligatoriu: mecanismul Upgrade există doar în HTTP/1.1. |
Upgrade $http_upgrade |
Transmite mai departe valoarea antetului Upgrade trimis de browser. |
Connection $connection_upgrade |
Setează upgrade când există $http_upgrade și close (sau "") pentru cereri HTTP normale. |
proxy_read_timeout |
Timpul maxim între două citiri succesive de la backend; crește-l (de exemplu 3600s) pentru conexiuni WebSocket de durată. |
Exemple
Exemplul 1: Locație dedicată pentru WebSocket (/ws/ sau /socket.io/)
Cea mai simplă variantă când conexiunile WebSocket au o cale separată:
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
Exemplul 2: Același location pentru HTTP normal și WebSocket (cu map)
Blocul map din http setează Connection: upgrade doar când clientul cere într-adevăr un upgrade:
# În contextul http:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# În contextul server:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
Greșeli frecvente
- Uitarea
proxy_http_version 1.1;: backend-ul primește cererea pe HTTP/1.0, ignorăUpgradeși răspunde cu 200 sau 400 în loc de101 Switching Protocols. - Deconectarea exact la 60 de secunde de inactivitate: cauza este
proxy_read_timeoutlăsat la valoarea implicită de60s.
Comenzi înrudite
proxy_pass: Trimite cererea către un server backend (Node.js, Python, Go, Docker) și returnează răspunsul clientului.proxy_set_header: Setează sau modifică antetele HTTP trimise către backend (Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto).upstream: Definește un grup de servere backend între care Nginx distribuie traficul (load balancing) și gestionează conexiunile keepalive.