Django2.2集成Channels时WebSocket请求/ws/live路径返回404问题
问题修复方案
- 修正asgi.py的导入顺序
当前asgi.py中先导入了项目内部的homepage.routing模块,再执行Django初始化,会导致路由加载失败。正确顺序为:先设置环境变量、执行django.setup(),再导入项目内部的路由模块,修正后代码如下:
import os import django from channels.http import AsgiHandler from channels.routing import ProtocolTypeRouter from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings') django.setup() # 初始化完成后再导入项目路由 import homepage.routing application = ProtocolTypeRouter({ "http": AsgiHandler(), "websocket": AuthMiddlewareStack( URLRouter( homepage.routing.websocket_urlpatterns ) ), })
- 修正WebSocket路径匹配问题
后端报错路径为/ws/live(无尾斜杠),你在routing中配置的是ws/live/(带尾斜杠),WebSocket协议不支持HTTP 301重定向,需要保证前后端路径完全匹配:可以修改routing.py的路径为path('ws/live', WSConsumer.as_asgi()),也可以用re_path兼容两种写法:re_path(r'^ws/live/?$', WSConsumer.as_asgi())。 - 修正consumers.py的方法调用错误
你当前connect方法里写的是self.accept,没有加括号执行,会导致连接一直挂起最终断开,需要改为self.accept()。 - 检查settings.py配置
Django 2.2配套使用Channels 2.x版本,必须在INSTALLED_APPS里添加channels,同时指定ASGI_APPLICATION配置:
INSTALLED_APPS = [ # 其他原有app 'channels', ] ASGI_APPLICATION = 'myapp.asgi.application'
如果需要使用channel layer还要配置CHANNEL_LAYERS指向已经部署的redis服务。
- 检查Nginx WebSocket代理配置
你使用Nginx做反向代理,必须添加WebSocket升级相关的请求头配置,否则Nginx会把WS请求当普通HTTP请求转发,导致404。你的nginx/sites-enabled/django.conf对应的location配置需要添加以下内容:
location / { proxy_pass http://web:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; }
- 确认Channels版本兼容性
Django 2.2最高支持Channels 2.4版本,不要安装Channels 3.x及以上版本,否则会出现兼容问题,在pip依赖里指定版本:channels==2.4.0。
内容的提问来源于stack exchange,提问作者Volpym
相关产品推荐
相关产品推荐

