FastAPI WebSocket连接约40秒自动断开,无法升级uvicorn如何解决
40秒断开原因
你使用的uvicorn 0.13.4版本默认开启了WebSocket协议层的存活检测机制:
- 默认每20秒向客户端发送标准WebSocket
PING帧 - 若发出
PING后20秒未收到客户端返回的PONG帧,服务端会主动断开连接
两项默认值相加刚好40秒,和你观察到的稳定断开时间完全吻合。你当前实现的是应用层JSON格式的ping/pong逻辑,和WebSocket协议层的ping/pong无关,客户端没有响应服务端发出的协议层PING帧,因此触发超时断连。
不升级uvicorn的解决方案
两种方案二选一即可:
方案1:修改Zephyr客户端响应协议层PING帧(推荐)
Zephyr自带的WebSocket库支持识别PING帧,只需在接收逻辑中增加对应判断,收到PING后直接返回PONG帧即可,无需修改服务端任何逻辑:
// 此处省略JSON包定义代码 while(1) { websocket_send_msg(sock, send_buffer, json_length, WEBSOCKET_OPCODE_DATA_TEXT, true, true, SYS_FOREVER_MS); int recv_len = websocket_recv_msg(sock, receive_buffer, sizeof(receive_buffer), &message_type, 0, SYS_FOREVER_MS); // 新增PING帧处理逻辑 if (message_type == WEBSOCKET_OPCODE_PING) { websocket_send_msg(sock, receive_buffer, recv_len, WEBSOCKET_OPCODE_PONG, true, true, SYS_FOREVER_MS); continue; } // 原有业务消息处理逻辑 }
方案2:关闭服务端默认PING检测
uvicorn 0.13.4版本已支持通过代码配置关闭协议层PING检测,无需升级版本,也不需要用到后续版本才新增的--ws-开头命令行参数。
如果是代码启动uvicorn,修改启动配置即可:
import uvicorn from your_app import app if __name__ == "__main__": uvicorn.run( app, host="0.0.0.0", port=8000, # 关闭自动PING检测 websocket_ping_interval=None, websocket_ping_timeout=None )
如果是命令行启动uvicorn,使用全参数名即可:
uvicorn main:app --websocket-ping-interval 0 --websocket-ping-timeout 0
注意:关闭服务端协议层PING检测后,需确保你的应用层JSON ping/pong机制正常运行,避免出现死连接无法被识别的问题。
内容的提问来源于stack exchange,提问作者El tornillo
相关产品推荐
相关产品推荐

