Architecting websocket infrastructure: Daphne + Gunicorn Proxy

2021-07-30MODULE: proxy_gateway

Gunicorn is a WSGI HTTP server for Python applications. It serves dynamic Python applications behind a reverse-proxy like Nginx.

Daphne is an ASGI server. It supports HTTP/2.0 and WebSocket protocols natively.

Infrastructure Requirements

Handling real-time, non-polling WebSocket traffic requires an ASGI server like Daphne. While Gunicorn manages standard HTTP traffic, Daphne is strictly required for protocols like WebSocket. A reverse-proxy (Nginx) must be configured to route WebSocket traffic (e.g., path /ws/) to Daphne, routing the remaining HTTP traffic to Gunicorn.

Server Comparison

Daphne

  • Handles HTTP, HTTP/2, WebSocket requests.
  • Eliminates the need to reverse-proxy WebSocket requests by specific path.

Gunicorn

  • Standard stability and community support.
  • Lacks native support for HTTP/2 and WebSockets.
  • Requires a reverse-proxy and supplementary server for unsupported protocols.

Concurrent Proxy Configuration

Incoming requests are redirected to their respective backend services via Nginx. The following configuration implements this routing protocol:

upstream server_http {
    server backend:8000;
}

upstream server_ws {
    server daphne:9001;
}

server {
    listen 80;
    # ...

    location / {
        proxy_pass http://server_http;
        # ...
    }

    location /ws/ {
        proxy_pass http://server_ws;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # ...
    }

    # ...
}

Result: Connections matching the /ws/ path are routed to the daphne service on port 9001. All other traffic defaults to the backend service (Gunicorn) on port 8000.