如何在AWS EC2上部署Django Channels(ASGI)并解决WS端点404问题?
AWS EC2部署ASGI应用以修复WebSocket 404问题
核心排查与修复步骤
REST端点正常但WebSocket(WS)返回404,核心原因是反向代理/服务器未正确转发WS请求,或ASGI服务配置遗漏WS支持。以下是具体解决方法:
1. 确认ASGI服务器选型与启动配置
- 必须使用支持WebSocket的ASGI服务器(如Uvicorn、Daphne),禁止使用仅支持WSGI的服务(如Gunicorn)。
- 以Uvicorn为例,启动命令示例:
Uvicorn默认支持WebSocket,无需额外参数。uvicorn main:app --host 0.0.0.0 --port 8000 --workers 2
2. 配置Nginx反向代理(关键)
若用Nginx做反向代理,必须添加WS转发规则,否则Nginx会将WS请求识别为普通HTTP请求,导致404。
编辑Nginx配置文件(路径通常为/etc/nginx/sites-available/或/etc/nginx/conf.d/):
server { listen 443 ssl; server_name your-domain.com; # SSL证书配置(根据实际证书路径调整) ssl_certificate /path/to/fullchain.pem; ssl_certificate_key /path/to/privkey.pem; location / { proxy_pass http://127.0.0.1:8000; 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路由前缀 location /ws/ { proxy_pass http://127.0.0.1:8000/ws/; # 强制HTTP/1.1协议,支持WS握手 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 延长超时时间,避免WS连接被过早断开 proxy_read_timeout 86400; } }
修改后重启Nginx:
sudo systemctl restart nginx
3. 检查EC2安全组规则
- 开放对应端口:若用Nginx转发,开放80(HTTP)和443(HTTPS/WSS);若直接暴露ASGI服务器,开放对应端口(如8000)。
- 确保入站规则允许客户端IP访问上述端口。
4. 验证应用内WebSocket路由
确认应用内WS路由定义与请求路径完全匹配(注意尾部斜杠),以FastAPI为例:
from fastapi import FastAPI, WebSocket app = FastAPI() @app.websocket("/ws/teacher/") async def teacher_websocket(websocket: WebSocket): await websocket.accept() while True: data = await websocket.receive_text() await websocket.send_text(f"收到消息: {data}")
5. 排查请求转发链路
- 查看ASGI服务器日志,确认WS请求是否到达服务器:若到达仍404,检查路由配置;若未到达,排查Nginx转发规则或安全组拦截。
- 确认客户端请求包含
Upgrade: websocket和Connection: Upgrade头,且Nginx已正确转发这些头。
内容的提问来源于stack exchange,提问作者mathis t
相关产品推荐
相关产品推荐

