Django Channels路由未找到:WebSocket连接失败求助
WebSocket连接失败:提示"Not found : ws/play/testroomcode"
已花费4天调试,始终无法建立WebSocket连接,持续报错"Not found : ws/play/testroomcode"。以下是相关代码配置:
consumers.py
from channels.generic.websocket import WebsocketConsumer from asgiref.sync import async_to_sync import json class GameRoom(WebsocketConsumer): def connect(self,event): print('Websocket Received...',event) self.room_name = self.scope['url_route']['kwargs']['room_code'] self.room_group_name = 'room_%s' % self.room_name print(self.room_group_name) async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() def receive(self,event): print('Websocket Received...',event) def disconnect(self,event): print('Websocket Disconnected...',event)
game/asgi.py
import osfrom django.core.asgi import get_asgi_applicationfrom channels.routingimport ProtocolTypeRouter, URLRouterfrom channels.auth import AuthMiddlewareStackfrom app1 import routing # Import your routingfrom app1.consumers import GameRoomfrom django.urls import path os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'game.settings')websocket_urlpatterns = [path('ws/play/<room_code>', GameRoom.as_asgi()),] application = ProtocolTypeRouter({'http': get_asgi_application(),'websocket': AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),})
game/settings.py
INSTALLED_APPS = ['channels','django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app1', ] ASGI_APPLICATION = 'game.asgi.application' #WSGI_APPLICATION = 'game.wsgi.application' CHANNEL_LAYERS = {"default": {"BACKEND": "channels_redis.core.RedisChannelLayer","CONFIG": {"hosts": [("127.0.0.1", 6379)], # Use quotes around the IP address},},}
已尝试各类教程,安装了django、channels、channels-redis并使用虚拟环境,也查阅了同类解决方案,但均无效,求助解决该连接问题。
排查与修复方案
- 修正URL路由参数格式:ASGI路由中路径参数缺少类型转换器,Django无法识别无类型的
<room_code>,修改为:path('ws/play/<str:room_code>', GameRoom.as_asgi()), - 修复Python代码缩进:
consumers.py中connect、receive、disconnect方法的代码块无缩进,Python是缩进敏感语言,这会导致方法体无法被正确解析,进而引发路由注册失败。修复后代码:class GameRoom(WebsocketConsumer): def connect(self, event): print('Websocket Received...', event) self.room_name = self.scope['url_route']['kwargs']['room_code'] self.room_group_name = 'room_%s' % self.room_name print(self.room_group_name) async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() def receive(self, event): print('Websocket Received...', event) def disconnect(self, event): print('Websocket Disconnected...', event) - 修复ASGI文件语法错误:
game/asgi.py中代码存在连写(如import osfrom django.core.asgi),属于语法错误,会导致ASGI应用无法启动。修复后代码:import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack from app1.consumers import GameRoom from django.urls import path os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'game.settings') websocket_urlpatterns = [ path('ws/play/<str:room_code>', GameRoom.as_asgi()), ] application = ProtocolTypeRouter({ 'http': get_asgi_application(), 'websocket': AuthMiddlewareStack( URLRouter(websocket_urlpatterns) ), }) - 检查Redis服务状态:确保本地Redis服务已启动,运行
redis-server命令启动服务,channels-redis依赖Redis运行,服务未启动会导致连接异常。 - 验证依赖版本兼容性:确认channels与channels-redis版本匹配,比如channels 4.x对应channels-redis 4.x,可通过
pip freeze查看版本,若不匹配则重新安装:pip install channels==4.0.0 channels-redis==4.1.0
内容的提问来源于stack exchange,提问作者Muhammad Qasim Hassan
相关产品推荐
相关产品推荐

