跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Python怎么写WebSocket_FastAPI/Django Channels实时通信

必须在 FastAPI WebSocket 路由开头 await websocket.accept(),否则连接因未完成握手而被拒绝;Channels 中 connect/receive/disconnect 均需 async def 且 self.send() 必须 await;Nginx 需配置 proxy_set_header Upgrade $http_upgrade 和 Connection "upgrade" 并启用 HTTP/1.1。 WebSocket 在 FastAPI 里怎么接住连接不立刻断开 FastAPI 的
WebSocket
路由必须显式调用
websocket.accept()
,否则客户端会收到 403 或直接关闭。这不是可选步骤,是协议握手的硬性要求。 常见错误现象:
WebSocket closed with code 403
或浏览器控制台报
Failed to execute 'send' on 'WebSocket': Still in CONNECTING state
必须在
async def
路由函数开头就 await
websocket.accept()
,不能放在 if 判断后、不能漏掉、不能写成
websocket.accept
(少括号) 如果要做鉴权,得在
accept()
前完成(比如读 cookie / header),因为 accept 后无法再返回 HTTP 错误
websocket.close()
要主动调用,不然连接可能滞留;但别在异常未捕获时跳过它,否则 ASGI server 可能卡住 Django Channels 的
consumers.py
为什么收不到消息 Channels 默认用
AsyncWebsocketConsumer
,但很多人写了
receive()
却没加
async
,或把
self.send()
当同步方法用——结果消息静默丢弃,无报错。 错误现象:前端发消息过去,服务端日志没打印,也没回传,
receive()
像没执行
connect()
、
receive()
、
disconnect()
全部必须是
async def
,哪怕你只做简单字符串处理
self.send()
是异步方法,必须
await self.send(...)
,写成
self.send(...)
不报错但无效 确保
ASGI_APPLICATION
指向正确的 module.path(比如
myproject.asgi.application
),而不是旧的 WSGI 配置 FastAPI 和 Channels 都要处理心跳,但方式完全不同 浏览器 WebSocket 默认不发心跳,超时后代理/NAT 会单向断连。两边都得自己保活,但实现位置和逻辑不能混。 FastAPI:通常在
while True:
循环里用
await asyncio.sleep(25)
+
await websocket.send_json({"type": "ping"})
,注意别在 send 前忘了检查
websocket.client_state == WebSocketState.CONNECTED
Channels:在
receive()
里识别
{"type": "ping"}
并
await self.send(...)
回 pong;同时建议用
self.channel_layer.group_send()
向组内广播状态,避免轮询 别依赖
ping_interval
这类浏览器私有 API,iOS Safari 和某些企业防火墙会拦截非标准 ping 帧 生产环境部署时,Nginx 怎么配才不吞掉 upgrade 头 Nginx 默认不转发
Connection: upgrade
和
Upgrade: websocket
,导致 WebSocket 握手失败,降级成普通 HTTP 请求。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 立即学习 “ Python免费学习笔记(深入) ”; 错误现象:
WebSocket connection to 'wss://...' failed: Error during WebSocket handshake: Unexpected response code: 200
必须在 location 块里显式设置:
proxy_set_header Upgrade $http_upgrade;
和
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
必须开启,HTTP/1.0 不支持 upgrade 机制 如果用 HTTPS,确认证书链完整,且 Nginx 的
ssl_protocols
包含 TLSv1.2+,老版本 TLS 可能导致 ws/wss 协商失败 真实线上问题往往卡在 Nginx 那一层,而不是代码逻辑——尤其是换了云厂商 SLB 或 CDN 后,它们默认不透传 upgrade 头,得单独开开关。

相关文章