You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx反向代理后Daphne协议升级始终路由至HTTP而非WebSocket

解决Nginx反向代理下Django Channels WebSocket被错误路由的问题

看起来你遇到的核心问题是Nginx没有正确区分WebSocket握手请求和普通HTTP请求,导致WebSocket连接被误转发给了不处理WebSocket的uWSGI。本地环境正常是因为Daphne直接处理了所有请求(包括HTTP和WebSocket),但部署后拆分了uWSGI和Daphne,就需要Nginx做正确的路由转发。下面是一步步的解决方案:

关键配置要点

Nginx需要识别WebSocket的握手特征:请求头里的Upgrade: websocket和Connection: upgrade,并将这类请求转发给Daphne,而普通HTTP请求转发给uWSGI。

完整的Nginx配置示例

假设你的Daphne服务监听127.0.0.1:8000,uWSGI通过unix套接字/path/to/your/project.sock通信,WebSocket请求路径以/ws/开头,配置如下:

server {
    listen 80;
    server_name your-domain.com;  # 替换成你的域名

    # 处理普通HTTP请求,转发给uWSGI
    location / {
        uwsgi_pass unix:/path/to/your/project.sock;  # 或者用uwsgi://127.0.0.1:8001(如果uWSGI监听端口)
        include uwsgi_params;
        # 传递必要的请求头,确保Django能正确获取客户端信息
        uwsgi_param Host $host;
        uwsgi_param X-Real-IP $remote_addr;
        uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
        uwsgi_param X-Forwarded-Proto $scheme;
    }

    # 专门处理WebSocket请求,转发给Daphne
    location /ws/ {
        proxy_pass http://127.0.0.1:8000;  # Daphne的监听地址
        proxy_http_version 1.1;  # WebSocket需要HTTP/1.1支持
        # 必须设置的WebSocket握手头
        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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 可选但推荐:设置长连接超时,避免WebSocket被Nginx过早断开
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }
}

部署注意事项

  1. 独立运行Daphne:确保Daphne是单独启动的服务(比如用systemd管理),而不是和uWSGI共用端口。例如systemd服务配置:
    [Unit]
    Description=Daphne service for Django Channels
    After=network.target
    
    [Service]
    User=your-user
    WorkingDirectory=/path/to/your/project
    ExecStart=/path/to/venv/bin/daphne -b 127.0.0.1 -p 8000 yourproject.asgi:application
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
  2. 匹配WebSocket路径:确保前端请求的WebSocket路径(比如ws://your-domain.com/ws/notifications/)和Nginx的location /ws/规则匹配。如果你的WebSocket路径不同,要调整Nginx的location规则。
  3. 重启服务:修改Nginx配置后执行sudo systemctl restart nginx,并确保Daphne和uWSGI服务都正常运行。

验证与排查

  1. 检查WebSocket握手:用浏览器开发者工具打开Network面板,筛选WebSocket请求,查看响应状态码是否为101 Switching Protocols,请求头里的Upgrade和Connection是否被正确传递。
  2. 测试握手命令:用curl手动测试WebSocket握手:
    curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: your-domain.com" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-WebSocket-Version: 13" http://your-domain.com/ws/
    
    如果返回HTTP/1.1 101 Switching Protocols,说明握手成功。
  3. 查看日志:如果还是失败,检查Nginx的错误日志(通常在/var/log/nginx/error.log)和Daphne的日志,看是否有连接被拒绝或路由错误的信息。

内容的提问来源于stack exchange,提问作者Jagadesh Babu T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:17:37