WebSocket频繁断开主因是未显式保活,需成对设置ping_interval与ping_timeout(如45s/30s),并确保Nginx、内核conntrack等中间设备超时值匹配,同时维持recv循环或定时ping,避免静默关闭。
频繁断开不是代码写错了,而是没告诉连接“我还活着”——WebSocket 本身不保活,空闲超时后中间设备(Nginx、防火墙、内核 conntrack)会直接掐断 TCP 连接。
ping_interval 和 ping_timeout 必须成对设置
只设
不够,
库默认
,但网络延迟或服务端响应慢时,pong 回不来就会触发强制关闭(错误码
或直接
)。
必须 > 网络 RTT + 服务端处理时间,生产环境建议设为
;
要比中间设备的空闲超时小至少 10 秒,比如 Nginx 默认
,那就设
;
两者都得显式传给
,不能只靠
(那是旧版
的用法);
asyncio 版必须用
手动发,且要包在
里,否则一次失败就崩协程。
recv() 循环不能漏,空连接撑不过 5 秒
asyncio 下的 WebSocket 不是“连上就自动活着”,底层依赖持续有协程在 await 消息或 ping。如果业务只发不收,又没启动接收循环,连接会在几秒内被静默关闭(日志常见
)。
哪怕不处理消息,也得写一个最小 recv 占位:
或
;
若确定永不收消息,改用
配合定时
,但 sleep 时间别超过
;
绝对不要在 recv 循环外另起线程调
,会破坏 event loop,引发
或 CPU 暴涨。
重连不能裸 try/except ConnectionClosedError
捕获到异常后立刻
,会导致旧连接残留、socket 句柄泄漏、重试风暴打挂服务端。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
下载
立即学习
“
Python免费学习笔记(深入)
”;
先检查
,再调
并
完成;
重连前必须
,避免高频重试;
退避策略用
,上限卡死 30 秒,否则弱网下越等越长;
重连逻辑要用
启动,别
它,否则阻塞主连接循环。
nginx 和内核 conntrack 是隐藏断连元凶
客户端和 Python 服务端代码全对,连接仍每 60 秒断一次?八成是 nginx 或 Linux 内核在背后动手。
Nginx 默认
,需在 location 块加:
和
;
Linux 内核对“非标准流”连接(如长 WebSocket)常缩短
到 300–600 秒,查当前值:
,临时调高:
;
所有代理层(CDN、云 WAF)都要确认是否支持 WebSocket 长连接,有些会静默丢弃 ping 帧。
真正难搞的从来不是代码逻辑,而是你根本看不到的中间链路——ping/pong 能跑通不代表连接能活过 60 秒,得一层层确认从 Python 协程、到系统 socket、再到反向代理、最后到云厂商的超时配置,全都对齐了才行。
ping_interval=20websocketsping_timeout=201011ConnectionClosedErrorping_timeout30ping_intervalproxy_read_timeout=6045connect()run_forever()websocket-clientawait websocket.ping()try/exceptcode=1001async for _ in websocket:while True: await websocket.recv()await asyncio.sleep(1)ping()ping_intervalsend()RuntimeError: There is no current event loopawait connect()websocket.closedawait websocket.close()awaitawait asyncio.sleep(1)min(30, 2 ** attempt)asyncio.create_task()awaitproxy_read_timeout 60proxy_read_timeout 86400;proxy_send_timeout 86400;nf_conntrack_tcp_timeout_establishedsysctl net.netfilter.nf_conntrack_tcp_timeout_establishedsudo sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=7200