Docker Compose中Django Channels REST Framework单WebSocket连接失效问题
排查Docker部署下WebSocket消息接收异常的步骤
针对你遇到的ws/coordinates/无法接收消息但ws/operations/正常的问题,结合你的配置,按以下步骤排查:
1. 确认Channels消息中间件(Redis)的一致性配置
Channels依赖Redis实现跨进程/容器的消息广播,这是最可能的问题点:
- 检查
settings.py中的CHANNEL_LAYERS配置,确保Docker环境下使用容器名redis作为主机地址,而非本地127.0.0.1,同时Redis密码正确匹配:CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("redis", 6379, {"password": os.environ.get("REDIS_PASSWORD")})], }, }, } - 进入asgi容器测试Redis连接:
确保返回docker exec -it operations_asgi /bin/bash # 安装redis-cli(如果容器内没有) apt-get update && apt-get install redis-tools # 连接Redis redis-cli -h redis -a $REDIS_PASSWORD # 测试ping pingPONG,同时测试发布订阅:在一个终端执行SUBSCRIBE test_channel,另一个终端执行PUBLISH test_channel "hello",看是否能收到消息。
2. 验证模型Observer的触发与订阅日志
添加日志确认订阅动作和消息触发是否正常:
- 修改
CoordinateConsumer,添加日志:import logging logger = logging.getLogger(__name__) class CoordinateConsumer(GenericAsyncAPIConsumer): # ... 原有代码 ... @model_observer(Coordinate) async def coordinates_activity(self, message, action=None, **kwargs): logger.info(f"Received coordinate update: {message}") await self.send_json(message) @action() async def subscribe_to_coordinates_activity(self, request_id, **kwargs): logger.info(f"Client subscribed to coordinates, request_id: {request_id}") await self.coordinates_activity.subscribe(request_id=request_id) logger.info(f"Subscription successful for request_id: {request_id}") - 查看asgi容器的日志:
确认:docker logs -f operations_asgi- 客户端连接后,
subscribe_to_coordinates_activity的日志是否输出 - 当Coordinate模型更新时,
coordinates_activity的日志是否输出
- 客户端连接后,
3. 检查Nginx WebSocket代理配置
虽然两个WebSocket路径都走asgi_server,但补充WebSocket相关的关键配置:
- 修改Nginx的
location ~* ^/ws/块,添加:
确保HTTP版本为1.1(WebSocket依赖),并延长超时时间避免连接断开。proxy_http_version 1.1; proxy_read_timeout 86400; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - 查看浏览器控制台的Network面板,确认
ws/coordinates/的连接状态:- 连接是否返回101 Switching Protocols
- 是否有错误日志(如连接超时、403/404等)
4. 确认模型信号与事务的兼容性
如果Coordinate的更新是在数据库事务中执行的,可能导致Observer延迟触发:
- 检查Coordinate模型的保存逻辑,是否存在事务回滚的情况
- 尝试在非事务环境下更新Coordinate,看是否能触发消息
- 可以手动触发信号测试:在wsgi容器中执行Python代码更新Coordinate,同时观察asgi日志是否有消息
5. 验证应用加载的完整性
确保Docker环境下正确加载了gnss应用:
- 检查
settings.py的INSTALLED_APPS是否包含gnss - 确认asgi容器中的代码与本地一致,没有缺失gnss应用的文件
6. 跨容器消息传递验证
如果Coordinate的更新是由wsgi容器处理的,需确保wsgi容器也能连接到Redis:
- 进入wsgi容器,执行和asgi容器相同的Redis连接测试
- 确认wsgi容器的
CHANNEL_LAYERS配置与asgi完全一致
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

