如何解决 Django Channels 无法处理 WebSocket 请求的问题?

为什么我的django channels按网上配置好了,还是不能用websocket?
setting
image.png

asgi
image.png

routing
image.png

consumer
image.png

我用在线工具测试,之前也用前端代码测试过
image.png
结果都是:
image.png

我把wsgi和它在setting的配置都注释了,它好像也没办法获取websocket请求,都是Get,我看网上视频结果应该是
image.png

setting里的daphne是后面加的,但是加不加都一样

image.png
image.png
更新了正则表达式后还是一样

阅读 630
avatarAI BotBETA

根据你的配置和错误信息,以下是可能的问题原因及解决方案:

  1. ASGI服务器未正确启动
  2. 不要使用runserver命令启动,应该用:daphne your_project.asgi:application
  3. 或使用:python manage.py runserver --protocol websockets
  4. 中间件顺序问题
    修改settings.py中间件配置:

    MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'corsheaders.middleware.CorsMiddleware',  # 确保CORS中间件在Session前
     'django.middleware.common.CommonMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
    ]
  5. Consumer缺少accept()调用
    修改consumer.py:

    def connect(self):
     self.accept()  # 必须显式调用accept建立连接
  6. 路由配置问题
    检查asgi.py配置:

    application = ProtocolTypeRouter({
     "http": get_asgi_application(),
     "websocket": AllowedHostsOriginValidator(  # 处理跨域
         AuthMiddlewareStack(
             URLRouter(
                 chat.routing.websocket_urlpatterns
             )
         )
     )
    })
  7. 跨域问题(CORS)
    安装并配置django-cors-headers:

    # settings.py
    CORS_ALLOW_ALL_ORIGINS = True  # 开发环境临时允许所有
    INSTALLED_APPS += ['corsheaders']
  8. 检查实际访问地址
    确保前端使用ws://协议:

    // 正确地址应该是:
    const socket = new WebSocket('ws://localhost:8000/ws/chat/')

验证步骤:

  1. 使用Daphne启动服务:

    daphne your_project.asgi:application --port 8000
  2. 在浏览器控制台测试连接:

    const socket = new WebSocket('ws://localhost:8000/ws/chat/');
    socket.onopen = () => console.log('Connected!');
    socket.onmessage = (e) => console.log('Message:', e.data);
    socket.onclose = (e) => console.log('Closed:', e.reason);

如果仍然出现403错误,尝试暂时关闭CSRF中间件:

# settings.py
CSRF_TRUSTED_ORIGINS = ['http://localhost:8000']
1 个回答

核心问题是 URL路由不匹配
你 的路由模式是 r'room/(?P<group>\w+)/$',而您尝试访问的URL是 /room/123/。注意你的正则表达式中 \w+ 只匹配字母、数字和下划线,而且最后有一个$表示路径结束。

还要检查你的服务中是否包含了 /root/xxxx 类似的 http 服务端口。尝试修改一下正则表达式 r'ws/room/(?P<group>\w+)/$' 增加 ws 前缀,或者 r'^room/(?P<group>\w+)/$'

代码是否可以私信提供给我,我帮你修改一下,目前只有这几个截图没办法准确的定位。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题