Django(DRF)集成WebSocket聊天时wss连接失败,求解决方法
}
WebSocket路由配置: ```python websocket_urlpatterns = [ re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()), ]
Consumer代码:
class ChatConsumer(WebsocketConsumer): def connect(self): self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.room_name # Join room group async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() def disconnect(self, close_code): # Leave room group async_to_sync(self.channel_layer.group_discard)( self.room_group_name, self.channel_name ) # Receive message from WebSocket def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] # Send message to room group async_to_sync(self.channel_layer.group_send)( self.room_group_name, { 'type': 'chat_message', 'message': message } ) # Receive message from room group def chat_message(self, event): message = event['message'] # Send message to WebSocket self.send(text_data=json.dumps({ 'message': message }))
发送请求 wss://localhost:6060/ws/chat/r1 时,出现“Could not connect to wss”错误,服务器端Nginx日志显示:
nginx_1 | 172.18.0.1 - - [28/Sep/2022:19:55:22 +0000] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03<\xA1\xCE\xACW\x06T\x84\x1F\xE3\x13\xD8F\x00\x03\x11\xC3><4k~_\x14\x83j=\xD1}u^R '\xCE\xF3\xB2\x142\x84+J~\xEC\xDAG?c\xD0)q\xBDZ\xD9\x95_\x1C\xED\x83L,\x1C" 400 157 "-" "-" "-"
修复方案
1. 补充Nginx的WebSocket代理配置
当前Nginx仅处理HTTP请求,缺少WebSocket协议升级支持,需添加专门的location块处理WebSocket路径:
upstream app { server django:8800; } server { listen 80; # 若使用WSS(加密WebSocket),需配置HTTPS # listen 443 ssl; # ssl_certificate /path/to/your/cert.pem; # ssl_certificate_key /path/to/your/key.pem; server_name 127.0.0.1; client_max_body_size 100M; location / { proxy_pass http://django:8800; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; proxy_read_timeout 300s; proxy_connect_timeout 75s; } # WebSocket专用代理配置 location /ws/ { proxy_pass http://django:8800; # 启用HTTP/1.1以支持WebSocket升级 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 延长超时时间,防止连接被过早断开 proxy_read_timeout 86400; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; } ... }
2. 匹配协议与端口
- 你用
wss://localhost:6060请求,但当前Nginx监听80端口(HTTP),若要使用WSS,需确保Nginx配置了443端口的SSL证书,且请求端口对应。 - 测试阶段可改用
ws://localhost:80/ws/chat/r1(非加密WebSocket)验证连接是否正常,再配置HTTPS。
3. 修正Consumer方法拼写错误
disconnect方法中误用了group_discard,Channels正确的方法名是group_remove:
def disconnect(self, close_code): # Leave room group async_to_sync(self.channel_layer.group_remove)( self.room_group_name, self.channel_name )
4. 验证Channels核心配置
确保项目settings.py中Channels配置正确:
INSTALLED_APPS = [ # ... 其他已安装应用 'channels', ] # 指定ASGI应用入口 ASGI_APPLICATION = '你的项目名称.asgi.application' # 配置Redis通道层 CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('redis', 6379)], # 根据你的Redis服务地址调整 }, }, }
5. 检查ASGI路由配置
确认asgi.py正确路由WebSocket请求:
import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack # 导入你的WebSocket路由模块 import chat.routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', '你的项目名称.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( chat.routing.websocket_urlpatterns ) ), })
内容的提问来源于stack exchange,提问作者mascai
相关产品推荐
相关产品推荐

