django原生不支持websocket因其同步架构与websocket长连接本质冲突,需通过channels引入异步运行时和消息分发层;配置须正确安装channels及asgi应用、设置路由与consumer,并注意协议、路径、http头等握手细节。

为什么 Django 原生不支持 WebSocket
Django 本身是同步框架,HTTP 请求-响应模型和长连接的 WebSocket 天然冲突。runserver 启动的开发服务器完全不处理 ws:// 或 wss:// 协议,直接访问会返回 404 或 502(如果前端连了反向代理但后端没接住)。这不是配置问题,是架构层面的缺失。
必须引入异步运行时和消息分发层——Channels 就是官方推荐的、与 Django 深度集成的方案,它把 WebSocket 连接转成「通道(channel)」,用 Redis 或内存层做背板,让 consumer 能收发消息。
安装 Channels 并替换 ASGI 入口
装错包或漏改入口点是最常见的卡点。别只 pip install django-channels,还要确认 ASGI 配置生效:
提供使用 django-unfold (v0.56+) 构建高级 Django 管理界面的专业指导。当用户提及 django-unfold、unfold admin 等内容时使用此技能。
-
pip install channels channels-redis(后者非必需,但生产环境几乎必选) - 在
settings.py中添加'channels'到INSTALLED_APPS顶部 - 设置
ASGI_APPLICATION = 'myproject.asgi.application',并确保myproject/asgi.py是 Channels 生成的版本(含ProtocolTypeRouter) - 删掉旧的
wsgi.py引用,启动命令必须是daphne myproject.asgi:application或python manage.py runserver(新版 Channels 已兼容 runserver 的 WebSocket 支持,但仅限开发)
写一个能收发消息的 WebSocket Consumer
别一上来就搞 AsyncWebsocketConsumer,简单广播场景用同步版更稳;而且路径路由、组管理、断开清理这些细节极易漏:
- 路由要写在
routing.py,不是urls.py:re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi())</room_name> -
connect()里必须调用self.accept(),否则连接立刻关闭,浏览器控制台只显示WebSocket closed before being accepted - 发消息用
self.send(text_data=json.dumps(...)),不是print或HttpResponse;接收时text_data是字符串,得手动json.loads() - 想群聊?用
self.channel_layer.group_add("chat_room", self.channel_name),但记得在disconnect()里group_discard,否则内存泄漏
前端连不上 ws://localhost:8000/ws/chat/xxx/ 怎么查
90% 的连接失败不是代码问题,而是协议或路径不匹配:
- 浏览器地址栏输的是
http://,但 JS 里new WebSocket("ws://...")—— 确保开发服务器跑在http://127.0.0.1:8000,而不是http://localhost:8000(Chrome 对ws://localhost有更严的同源策略) - 路径末尾多了斜杠:
ws://.../chat/room1/和ws://.../chat/room1在路由正则里是两个东西,re_path默认不自动处理尾部斜杠 - 没开
daphne或uvicorn,还在用runserver且没升级到 Channels 4+ —— 检查pip show channels,低于 4.0.0 的版本在runserver下 WebSocket 不工作 - 用 Nginx 反代?必须透传 Upgrade 头:
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade";缺一不可
真正麻烦的从来不是写 consumer,是让那个绿色的 WebSocket connected 出现在浏览器控制台里——路径、协议、头、ASGI 入口,四个点只要一个偏移,就卡在握手阶段。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










