DEV Community

Mario Nachbaur
Mario Nachbaur

Posted on

WebSocket service behind nginx reverse proxy

I have all my backend services behind a nginx reverse proxy. It allows me to host many services with different URLs on the same machine, when they're lightweight enough. And it manages SSL and everything needed for secure connections for me, so I can keep my code simple.

The latest service I'm working on relies a lot on WebSockets. Most browsers only allow wss:// (secure web sockets) connections from web pages served with https://. So I needed to serve the socket with SSL.

Configuration

For a successful web socket connection, we need to ensure that the HTTP version is correct and pass some headers to the service.

server {
    location /ws {
        proxy_http_version 1.1;
        proxy_pass http://address:port;
        proxy_set_header Connection $http_connection;
        proxy_set_header Upgrade $http_upgrade;
    }
}
Enter fullscreen mode Exit fullscreen mode

This configuration only applies to the /ws route, because that is where the socket is. We set the HTTP version to 1.1 since nginx uses 1.0 by default, and forward the Connection and Upgrade HTTP headers to the service.

Keeping the socket open

The first thing I noticed after setting up the reverse proxy is that my connections were closing after a while. Turns out nginx closes connections that don't send any data within 60 seconds. You can increment this timeout thanks to the proxy_read_timeout directive:

location /ws {
    # ...
    proxy_read_timeout 300s;
}
Enter fullscreen mode Exit fullscreen mode

But I opted to send ping messages periodically from the client to tell the service that I'm still interested in keeping the connection open. I didn't like the idea of setting the timeout to some large time amount and have a connection open indefinitely.

Top comments (0)