Django WebSocket握手失败:No route found路由错误求助
WebSocket路由错误排查:No route found for path 'ws/chat_app/3wVCio/'
错误信息
python3.12/site-packages/channels/routing.py", line 134, in __call__ raise ValueError("No route found for path %r." % path) ValueError: No route found for path 'ws/chat_app/3wVCio/'. WebSocket DISCONNECT /ws/chat_app/3wVCio/ [192.168.0.11:58136]
问题根源及修复步骤
1. 错误混入HTTP路由系统
项目urls.py中将WebSocket路由加到了HTTP的urlpatterns里,这是核心错误——WebSocket协议路由由ASGI层单独处理,不需要通过Django的HTTP路由分发。
修复:
删除项目urls.py中以下代码:
path('ws/', include(websocket_urlpatterns)),
2. 路由规则未匹配请求前缀
当前routing.py的正则路由是r'chat_app/(?P<unique_id>\w+)/$',但客户端请求路径是/ws/chat_app/3wVCio/,ASGI层接收的完整路径包含ws/前缀,路由规则需匹配该前缀。
修复:
修改routing.py的正则规则,添加ws/前缀:
from django.urls import re_path from .consumers import ChatConsumer websocket_urlpatterns = [ re_path(r'ws/chat_app/(?P<unique_id>\w+)/$', ChatConsumer.as_asgi()), ]
3. 异步消费者方法需改为异步(额外修复)
ChatConsumer继承了AsyncWebsocketConsumer,但disconnect、receive、chat_message方法为同步写法,会导致运行时错误,需改为异步:
修复后的consumer.py关键代码:
async def disconnect(self, close_code): # Leave room group await self.channel_layer.group_discard( self.room_group_name, self.channel_name ) # Receive message from WebSocket async def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] # Save message to database await sync_to_async(Message.objects.create)( room=self.unique_id, user=self.scope['user'], content=message ) # Send message to room group await self.channel_layer.group_send( self.room_group_name, { 'type': 'chat_message', 'message': message, 'username': self.scope['user'].username } ) # Receive message from room group async def chat_message(self, event): message = event['message'] username = event['username'] # Send message to WebSocket await self.send(text_data=json.dumps({ 'message': message, 'username': username }))
4. 验证ASGI配置正确性
确保项目asgi.py正确导入websocket_urlpatterns:
import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack from chat_app.routing import websocket_urlpatterns # 替换为你的app实际路径 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( websocket_urlpatterns ), ) })
总结
核心问题是WebSocket路由配置错误:一是错误将其混入HTTP路由系统,二是路由规则未匹配请求路径的ws/前缀。修复这两点后路由可正常匹配,同时需修正异步消费者的方法写法,避免后续运行时错误。
内容的提问来源于stack exchange,提问作者Geo48
相关产品推荐
相关产品推荐

