Django WebSocket连接失败求助:路由路径匹配异常
解决Django WebSocket连接错误的几个关键修复
1. 修复URL路径不匹配问题
你的前端请求路径末尾带有斜杠(/ws/jobs/<job_id>/),但后端urls.py中的路由规则没有斜杠,导致路由无法匹配。修改urls.py:
websocket_urlpatterns = [ path('ws/jobs/<job_id>/', consumers.JobConsumer.as_asgi()), ]
2. 修正Consumer的异步逻辑错误
你使用了AsyncWebsocketConsumer,但connect方法用了普通def,还错误使用了async_to_sync,同时disconnect方法存在变量名和方法名错误。修正consumer.py:
import json from channels.generic.websocket import AsyncWebsocketConsumer class JobConsumer(AsyncWebsocketConsumer): async def connect(self): self.job_id = self.scope['url_route']['kwargs']['job_id'] self.job_group_name = f'job_{self.job_id}' # 加入分组 await self.channel_layer.group_add( self.job_group_name, self.channel_name ) await self.accept() async def disconnect(self, close_code): # 退出分组 await self.channel_layer.group_remove( self.job_group_name, self.channel_name ) async def receive(self, text_data): text_data_json = json.loads(text_data) job = text_data_json['job'] print("Job", job)
3. 修复前端WebSocket事件绑定逻辑
你的waitForSocketConnection函数会导致错过onopen事件,应该在创建WebSocket实例后立即绑定事件。简化前端代码:
function updateCourierPosition(map) { // 根据当前页面协议自动选择ws/wss const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const url = `${protocol}//${window.location.host}/ws/jobs/{{ job.id }}/`; const jobSocket = new WebSocket(url); // 连接成功时触发 jobSocket.onopen = function(event) { jobSocket.send(JSON.stringify({"job": "{{ job.id }}"})); console.log("WebSocket连接成功"); }; // 接收消息时触发 jobSocket.onmessage = function(e) { const data = JSON.parse(e.data); const job = data.job; console.log(job); }; // 捕获错误 jobSocket.onerror = function(error) { console.error("WebSocket错误:", error); }; // 连接关闭时触发 jobSocket.onclose = function(event) { console.log("WebSocket连接关闭:", event); }; }
额外检查项
- 确保已正确安装
channels和channels-redis(如果使用Redis作为Channel Layer),并在settings.py中配置:
CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("127.0.0.1", 6379)], }, }, }
- 使用ASGI服务器运行项目(如
daphne yourproject.asgi:application或uvicorn yourproject.asgi:application),不要用普通的runserver(开发环境临时可用,但生产环境必须用ASGI服务器)。 - 确认
asgi.py中正确导入了websocket_urlpatterns,路径无误。
内容的提问来源于stack exchange,提问作者etnuh
相关产品推荐
相关产品推荐

