Django Channels部署AWS EC2后WebSocket远程连接失败(本地正常)
问题排查:Django Channels远程WebSocket连接404错误
现象
本地/ngrok环境下WebSocket连接正常,但AWS EC2远程连接时出现404错误,日志如下:
17-03-2025 18:57:13 | django.request | WARNING | Not Found: /ws/chat/ 17-03-2025 18:57:13 | gunicorn.access | INFO | "GET /ws/chat/?first_user=19628&second_user=19629 HTTP/1.1" 404 179
相关配置
routing.py
from django.urls import path from apps.chat.consumers.consumers import ChatConsumer websocket_urlpatterns = [ path('ws/chat/', ChatConsumer.as_asgi()), ]
asgi.py
import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.main') django.setup() from channels.auth import AuthMiddlewareStack # noqa: E402 from channels.routing import ProtocolTypeRouter # noqa: E402 from channels.routing import URLRouter # noqa: E402 from django.core.asgi import get_asgi_application # noqa: E402 from apps.chat.middlwares.queryparams import QueryParamsMiddleware # noqa: E402 from apps.chat.routing import websocket_urlpatterns # noqa: E402 application = ProtocolTypeRouter( { 'http': get_asgi_application(), 'websocket': AuthMiddlewareStack(QueryParamsMiddleware(URLRouter(websocket_urlpatterns))), } )
settings.py
ASGI_APPLICATION = 'apps.asgi.application' INSTALLED_APPS += [ # Third-party apps 'daphne' 'django.contrib.admin', 'django.contrib.auth', ... 'channels', # Local apps ... 'apps.chat.apps.ChatConfig', ] CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { 'hosts': [os.environ.get('REDIS_URL', ('127.0.0.1', 6379))], }, }, }
docker-compose.yml
volumes: pg_data: driver: local x-base: &base-backend build: . volumes: - .:/code depends_on: - db - redis services: backend: <<: *base-backend ports: - "8000:8000" env_file: .env environment: - DJANGO_SETTINGS_MODULE=settings.main entrypoint: ["/code/entrypoint.sh"] depends_on: - db - redis restart: unless-stopped volumes: - .:/code - ./logs:/code/logs db: image: postgres:13 volumes: - "pg_data:/var/lib/postgresql/data" environment: POSTGRES_DB: db_name POSTGRES_USER: db_user POSTGRES_PASSWORD: db_password ports: - "5432:5432" restart: unless-stopped redis: image: redis:alpine ports: - "6379:6379" restart: unless-stopped worker: <<: *base-backend command: celery -A apps.celery worker --loglevel=info environment: - REDIS_URL=redis://redis:6379 depends_on: - backend - redis restart: unless-stopped daphne: <<: *base-backend container_name: daphne command: bash -c "daphne -v 3 -b 0.0.0.0 -p 8001 apps.asgi:application" ports: - "8001:8001" depends_on: - worker - backend - redis volumes: - .:/code - ./logs:/code/logs
前端连接代码
const socket = new WebSocket("wss://<server ip>/ws/chat/?first_user=19628&second_user=19629", ["Bearer", token]);
排查方向
- 端口不匹配:Daphne运行在8001端口,但前端连接用的是wss默认443端口,未指定8001。需修改前端地址为
wss://<server ip>:8001/ws/chat/?first_user=19628&second_user=19629。 - 请求被Gunicorn接收:日志显示请求由gunicorn处理,说明WebSocket请求未转发到Daphne。确认EC2安全组8001端口已开放,同时检查前端请求是否确实发送到8001端口而非Gunicorn的8000端口。
- settings.py语法错误:
INSTALLED_APPS中'daphne'后缺少逗号,会导致Daphne无法被正确识别为ASGI服务器,必须修正为'daphne',。 - Daphne服务状态:检查EC2上Daphne容器是否正常运行,执行
docker ps查看容器状态,或通过docker logs daphne查看启动日志是否有异常。 - SSL配置问题:如果使用wss协议,需确保Daphne配置了有效SSL证书。可先尝试用ws协议(非加密)测试连接,再排查SSL配置。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

