Configure Nginx as Reverse Proxy for WebSocket

WebSocket is a computer communication protocol which provides full-duplex communication channels over a single TCP connection. It makes possible to create web applications that supports real-time bi-directional communication between both clients and servers. Most of the modern web browsers support WebSocket including all size devices.

While making web applications having realtime communication features like audio or video calls, instant messaging or realtime file transfer, there will need a load balancer to distribute load among multiple instances of the application servers to make sure quality services are being delivered to the end uses. NGINX is a well known open source web server which can be used as advance load balancer and reverse proxy server.

Nginx supports web socket by setting up a tunnel between both the client and backend servers. The WebSocket protocol is different from the HTTP protocol, but the WebSocket handshake is compatible with HTTP, using the HTTP Upgrade facility to upgrade the connection from HTTP to WebSocket. This allows WebSocket applications to more easily fit into existing infrastructures.

The web socket connection keeps a long running bidirectional connection between the client and the server. The HTTP Upgrade mechanism used to upgrade the connection from HTTP to WebSocket uses the Upgrade and Connection headers.

WebSocket is a hop by hop protocol, so when a proxy server intercepts an Upgrade request from a client it needs to send its own Upgrade request to the backend server, including the appropriate headers. WebSocket connections are long lived, as opposed to the typical short‑lived connections used by HTTP, the reverse proxy needs to allow these connections to remain open, rather than closing them because they seem to be idle.

Update your virtual host configuration as follows, we need to set revers proxy configuration and a map block so that the Connection header is correctly set to close when the Upgrade header in the request is set to ”.

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
 
    upstream websocket {
        server 127.0.0.1:8000;
    }
 
    server {
        listen 443;
        location / {
            proxy_pass http://websocket;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
        }
    }
}

Here NGINX listens on port 443 and proxies requests to the backend WebSocket server. The proxy_set_header directives enable NGINX to properly handle the WebSocket protocol. You can install SSL and make the connection secure by using wss:// Most of the browsers are not allowing non secured connections over web socket.

To test the web socket configuration, you can install the open source Node.js WebSocket library ws by running npm install ws command or you can try connecting your web socket application.

Leave a Reply