Implementing WebSocket Support
1. Configuring Proxy for WebSocket
| Directive | Description | Values | Notes |
|---|---|---|---|
| proxy_pass | Specifies the address of the WebSocket server to forward requests to | ws://backend:8080, wss://secure-backend:443 |
Must use ws:// or wss:// scheme for WebSocket connections |
| proxy_http_version | Sets the HTTP version to use for proxying requests | 1.1 |
Required for WebSocket support; must be set to 1.1 |
| proxy_set_header | Allows setting custom headers for WebSocket upgrade requests | Connection, Upgrade |
Must include headers required for WebSocket handshake |
| proxy_read_timeout | Timeout for reading response from the backend server | 300s |
Recommended to set high enough for long-lived WebSocket connections |
| proxy_send_timeout | Timeout for sending request to the backend server | 300s |
Should match read timeout to maintain connection consistency |
Example: Basic WebSocket proxy configuration
location /websocket {
proxy_pass ws://backend:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
Note: Ensure that the backend server supports WebSocket connections and is configured to handle upgrade requests properly.
2. Setting Upgrade Header
| Directive | Values | Description |
|---|---|---|
| proxy_set_header | Upgrade $http_upgrade |
Sets the Upgrade header to the value of the client's Upgrade request header |
| proxy_set_header | Connection "upgrade" |
Sets the Connection header to "upgrade" to indicate that the connection should be upgraded |
Example: Configuring WebSocket Upgrade Headers
location /websocket {
proxy_pass http://backend;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
3. Setting Connection Header
| Directive | Values | Description |
|---|---|---|
| proxy_set_header | Connection $connection_upgrade |
Sets the Connection header to the value of the $connection_upgrade variable |
| proxy_set_header | Upgrade $http_upgrade |
Sets the Upgrade header to the value of the $http_upgrade variable |
Example: Configuring WebSocket Headers
location /websocket/ {
proxy_pass http://backend;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
4. Using Map for Connection
| Directive | Description | Values | Notes |
|---|---|---|---|
| map | Defines a mapping between input variables and output values | $variable |
Used to dynamically set connection parameters based on input |
Example: Setting up a map for WebSocket connections
map $http_upgrade $connection_upgrade {
default close;
"upgrade" $http_connection;
}
Note: The
map directive is useful for setting up dynamic behavior based on request headers or other variables.
5. Setting WebSocket Timeouts
| Directive | Values | Description |
|---|---|---|
| proxy_connect_timeout | 60s |
Timeout for connecting to the WebSocket server |
| proxy_send_timeout | 60s |
Timeout for sending data to the WebSocket server |
| proxy_read_timeout | 60s |
Timeout for reading data from the WebSocket server |
| proxy_timeout | 60s |
General timeout for proxy operations (includes WebSocket) |
Example: Configuring WebSocket timeouts
location /websocket {
proxy_pass http://websocket_backend;
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_timeout 60s;
}
6. Configuring WebSocket with SSL
| Directive | Description | Example |
|---|---|---|
| proxy_pass | Specifies the WebSocket server address | proxy_pass https://websocket-server; |
| proxy_ssl_enable | Enables SSL for the proxy connection | proxy_ssl_enable on; |
| proxy_ssl_verify | Enables SSL certificate verification | proxy_ssl_verify on; |
| proxy_ssl_trusted_certificate | Specifies the CA certificate file | proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; |
Example: Basic WebSocket over SSL Configuration
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
location /websocket {
proxy_pass https://websocket-server;
proxy_ssl_enable on;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
7. Load Balancing WebSockets
| Directive | Description | Values | Notes |
|---|---|---|---|
| upstream | Defines a group of servers to be load balanced | name |
Used in conjunction with server blocks to define backend servers |
| server | Defines a server in the upstream group | address [parameters] |
Can include weight, max_fails, and fail_timeout |
| keepalive | Number of idle keepalive connections to the upstream servers | number |
Improves performance by reusing connections |
Example: Basic WebSocket Load Balancing Configuration
upstream websocket_backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
location /websocket {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
Note: Ensure that all upstream servers support WebSocket connections and are configured to handle them properly.
Load Balancing Strategies for WebSockets
- Round Robin: Default method, distributes requests evenly among servers
- IP Hash: Uses client IP to determine server, ensures consistency
- Least Connections: Routes to server with the fewest active connections
8. Handling WebSocket Keepalive
| Directive | Description | Default | Notes |
|---|---|---|---|
| proxy_send_timeout | Timeout for sending data to the WebSocket server | 60s |
Controls how long Nginx waits before closing the connection |
| proxy_read_timeout | Timeout for reading data from the WebSocket server | 60s |
Used to maintain the connection and prevent timeouts |
| proxy_http_version | HTTP version to use for proxying WebSocket connections | 1.1 |
Must be set to 1.1 for WebSocket support |
| proxy_set_header Upgrade | Header to set for WebSocket upgrade request | $http_upgrade |
Must be set to allow WebSocket upgrade |
| proxy_set_header Connection | Header to set for WebSocket connection | upgrade |
Must be set to maintain WebSocket connection |
Example: Configuring WebSocket Keepalive
location /websocket {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
Note: Setting
proxy_read_timeout and proxy_send_timeout to a high value (e.g. 86400 seconds) ensures that the WebSocket connection remains open for extended periods without timing out.
9. Debugging WebSocket Connections
| Aspect | Description | Notes |
|---|---|---|
| ws_transport | tcp or ssl |
Specifies the transport protocol for WebSocket connections |
| proxy_pass | ws://backend or wss://backend |
Used to forward WebSocket connections to backend servers |
| proxy_http_version | 1.1 |
Must be set to 1.1 for WebSocket support |
| proxy_set_header | Connection "upgrade" |
Required to upgrade HTTP to WebSocket |
| proxy_set_header | Upgrade "$http_upgrade" |
Passes the upgrade header to backend |
Example: Basic WebSocket Proxy Configuration
location /websocket {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Note: Ensure that the backend server supports WebSocket connections and is configured to handle upgrades properly.
Warning: Misconfigurations in WebSocket proxy settings can lead to connection timeouts or failed upgrades.
Common Debugging Steps
- Check logs for
400 Bad Requestor502 Bad Gatewayerrors - Verify that
proxy_http_versionis set to1.1 - Confirm that
UpgradeandConnectionheaders are correctly forwarded - Ensure backend server supports WebSocket protocol
10. Using WebSocket with Subprotocols
WebSocket connections can use subprotocols to define specific communication protocols between client and server. These subprotocols are negotiated during the WebSocket handshake.
| Directive | Description | Example |
|---|---|---|
| websocket | Enables WebSocket support for a location block. | websocket |
| proxy_pass | Specifies the backend WebSocket server to forward connections to. | proxy_pass ws://backend; |
| proxy_set_header | Sets headers to be passed to the backend server, including Sec-WebSocket-Protocol. |
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol; |
Example: Configuring WebSocket with Subprotocols
location /websocket {
websocket;
proxy_pass ws://backend_server;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol;
}
Note: The
Sec-WebSocket-Protocol header is used to specify the subprotocol(s) supported by the client. The server must support one of these protocols for the handshake to succeed.
11. Implementing WebSocket Ping/Pong
| Directive | Description | Default |
|---|---|---|
| proxy_set_header | Sets a header to be passed to the upstream server | None |
| proxy_http_version | Specifies the HTTP version to use for proxying | 1.1 |
| proxy_ssl_enable | Enables SSL for the proxy connection | off |
Example: Basic WebSocket Configuration with Ping/Pong
location /websocket {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
Note: The
proxy_read_timeout should be set to a value that allows for long-lived WebSocket connections, such as 86400 seconds (24 hours).
12. Handling WebSocket Disconnections
| Directive | Description | Default | Notes |
|---|---|---|---|
| proxy_bind | Binds the proxy to a specific IP address | Off | Useful for multi-homed servers |
| proxy_connect_timeout | Timeout for connecting to the WebSocket server | 60s | Adjust based on server response time |
| proxy_send_timeout | Timeout for sending data to the WebSocket server | 60s | Prevents hanging connections |
| proxy_read_timeout | Timeout for reading data from the WebSocket server | 60s | Prevents idle connection timeouts |
| proxy_http_version | HTTP version to use for proxying | 1.1 | Required for WebSocket support |
| proxy_set_header | Sets custom headers for the WebSocket upgrade request | None | Must include Upgrade and Connection headers |
Example: Basic WebSocket Configuration with Timeout Handling
location /websocket {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
Note: Ensure that the backend WebSocket server is configured to handle disconnections gracefully. Nginx will close the connection if it exceeds the timeout limits.
Warning: Setting very low timeouts can cause premature disconnections if the WebSocket server is slow to respond. Adjust based on your application's behavior.