You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebSocket程序运行30分钟抛出远程主机连接丢失异常如何修复

问题排查与修复方案

典型特征匹配

程序稳定运行约30分钟后固定抛出websocket._exceptions.WebSocketConnectionClosedException: Connection to remote host was lost.异常,属于WebSocket长连接场景下的经典问题,时间点特征非常明确,基本可以直接定位根因。

核心根因

  • 绝大多数公网链路、反向代理(如Nginx)、企业防火墙的默认TCP空闲会话超时阈值为30分钟,若连接上连续30分钟无任何数据传输,中间网络设备会主动销毁会话,客户端不会实时感知到连接已断开,直到下次尝试收发数据才会抛出连接丢失异常。
  • Python生态常用的websocket-client库默认关闭协议层自动心跳(Ping/Pong帧)机制,空闲期不会主动发送保活包维持链路。
  • 代码未做连接异常捕获与自动重连处理,连接断开后直接抛出异常终止程序。

分步修复

1. 开启客户端自动心跳保活

初始化WebSocket连接时,显式配置心跳参数,保活间隔设置为小于30分钟即可,通用场景取10-20分钟为合理值,避免不必要的流量开销:

ws.run_forever(
    ping_interval=1200,  # 每20分钟发送一次Ping保活帧
    ping_timeout=30      # Ping发出后30秒未收到Pong响应判定连接失效
)

注意:不要依赖操作系统TCP层自带的Keepalive机制,该机制默认发送间隔为2小时,远长于中间链路的30分钟超时阈值,无法起到保活作用,必须使用WebSocket协议层的Ping/Pong帧。

2. 增加异常捕获与自动重连逻辑

网络本身是不可靠的,任何长连接场景都必须做断连自动恢复,避免单点网络波动导致程序完全不可用:

import time
import websocket
from websocket._exceptions import WebSocketConnectionClosedException

def run_ws_client():
    while True:
        try:
            # 初始化WebSocket实例、注册业务回调的原有逻辑保持不变
            ws = websocket.WebSocketApp(
                # 原有连接地址、on_message/on_error/on_close等回调配置
            )
            ws.run_forever(ping_interval=1200, ping_timeout=30)
        except WebSocketConnectionClosedException:
            # 连接正常断开场景,等待5秒后重连
            time.sleep(5)
        except Exception as e:
            # 其他网络异常场景,退避10秒后重连
            time.sleep(10)

if __name__ == "__main__":
    run_ws_client()

3. 服务端配套配置检查

如果你的WebSocket服务前置了Nginx等反向代理,需要同步调整代理配置,确保代理的长连接超时时间大于客户端心跳间隔,例如在Nginx配置中增加:

proxy_read_timeout 1800s;
proxy_send_timeout 1800s;

如果服务端本身配置了30分钟会话最大有效期主动踢连,上述自动重连逻辑也可以保证连接断开后快速恢复,不影响业务正常运行。


内容的提问来源于stack exchange,提问作者ArseneCC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:03:19