
做美股相关的数据服务时我碰到一个小烦恼WebSocket连接偶尔断开。尤其是实时tick数据程序明明还在跑提示“断开”有时候还挺突然的。我自己测试了不少方法发现心跳设置是最容易影响稳定性的一个点。为什么WebSocket会断连WebSocket看起来是长连接但其实服务器和客户端都可能主动关闭连接。断开的原因大概有这些服务器端限制有些美股api服务端对连接空闲时间有限制长时间没有消息就会断开。网络波动即便延迟几百毫秒也可能让服务端误判掉线。客户端策略某些库在心跳失败时会主动断开连接。所以断连不一定是接口问题往往是心跳间隔不合理或者丢失导致的。心跳间隔设多少比较合适我自己测试过几个时间间隔心跳间隔实际体验5秒很稳但消息频繁CPU稍微升高10秒稳定性不错性能消耗小大多数场景够用30秒偶尔会被服务器断开网络不稳时风险明显60秒不太行断连概率大增所以我的经验是10秒左右最合适既保证连接活跃又不会频繁增加负担。如果追求极致稳定5秒也可以但CPU和网络压力会高一点。心跳就是给服务器发“我还在线”的信号通常是发送空包或者ping消息。大部分API要求按文档发心跳否则连接容易断开。心跳实现技巧我会用几个策略保证WebSocket不轻易掉独立线程/协程发送心跳主逻辑阻塞时也不会漏掉心跳。失败重连机制心跳失败马上尝试重连减少数据缺口。动态调整间隔高峰时可稍微缩短心跳保证稳定。以 AllTick API为例订阅美股实时tick数据时可以用 Python 写一个简单心跳逻辑保持连接稳定import asyncio import websockets import json async def heartbeat(ws, interval10): while True: try: await ws.send(json.dumps({type: ping})) except Exception as e: print(心跳发送失败:, e) break await asyncio.sleep(interval) async def main(): url wss://apis.alltick.co/ws/stock/subscribe async with websockets.connect(url) as ws: asyncio.create_task(heartbeat(ws, 10)) await ws.send(json.dumps({ type: subscribe, symbols: [AAPL, MSFT] })) async for message in ws: data json.loads(message) print(data) asyncio.run(main())这个示例里心跳和订阅都在一个事件循环里即使网络轻微波动也能尽快确认连接状态。实践观察实际运行一天两天10秒心跳几乎不会被服务器断开。30秒以上偶尔会丢消息5秒虽然稳定但CPU和网络压力增加。心跳消息尽量轻量只要服务器收到就够带复杂数据反而可能增加断连概率。我的做法是把心跳和订阅放在同一个循环里用协程管理网络小抖动也不会导致断开。像实时tick这种场景这套逻辑足够应付大多数情况。