在做美股实时数据开发时,相信不少朋友都遇到过和我一样的问题:WebSocket 连着连着就断了。
尤其是跑 tick 行情这种高实时性数据时,程序明明在正常运行,没有卡死、没有报错,却突然断开,让人特别无奈。
我踩过很多坑,也调试过无数次,最后发现:影响连接稳不稳定的关键,就是心跳间隔。
一、明明是长连接,为什么还会断?
很多人以为 WebSocket 连上就不会断,其实并不是。
在美股数据这种跨境场景里,断开通常是这几个原因:
服务器有空闲限制
大部分美股数据接口,如果一段时间收不到你的消息,会认为你不在线,直接关掉连接。
网络波动影响
跨境网络本来就容易有延迟和抖动,哪怕只是几百毫秒,也可能被误判为掉线。
客户端自身机制
一些网络库在心跳超时后,会主动断开,避免无效连接占用资源。
简单说:断连大多不是接口坏了,而是心跳没跟上。
二、心跳到底设几秒?我做了真实测试
为了找到最稳的配置,我在真实环境里测了 5s、10s、30s、60s 四档,结果非常明确:
5 秒:非常稳,但发包太频繁,CPU 和带宽消耗会高一些
10 秒:稳定、轻巧、兼容性最好,绝大多数场景直接用
30 秒:网络一差就容易被断开,风险明显变高
60 秒:基本不可用,断连概率非常大
我的经验结论是:
美股实时数据场景,10 秒心跳是最舒服的选择。
既可以保持连接活跃,又不会给设备增加多余负担。
如果追求极致稳定,也可以用 5 秒,但要接受更高的资源占用。
心跳其实很简单,就是定时给服务器发一句 “我还在”,一般用空包或者 ping 消息就够了。
按照 API 要求正常发送,连接就会稳定很多。
三、实战技巧:让 WebSocket 更稳的 3 个方法
只设置间隔还不够,我平时会用这几个策略,让连接几乎不掉:
用独立协程 / 线程发心跳
即使主逻辑卡住、阻塞,心跳也不会断。
加自动重连机制
心跳一失败就立刻重连,把数据缺口降到最低。
支持动态调整间隔
行情高峰、网络差的时候,可以自动缩短心跳,提高稳定性。
我在开发中常用AllTick API对接美股实时行情,下面是我一直在用的 Python 心跳代码,稳定好用:
importasyncio
importwebsockets
importjson
asyncdefheartbeat(ws,interval=10):
whileTrue:
try:
awaitws.send(json.dumps({"type":"ping"}))
exceptExceptionase:
print("心跳发送失败:",e)
breakawaitasyncio.sleep(interval)
asyncdefmain():
url="wss://apis.alltick.co/ws/stock/subscribe"
asyncwithwebsockets.connect(url)asws:
asyncio.create_task(heartbeat(ws,10))
awaitws.send(json.dumps({
"type":"subscribe",
"symbols":["AAPL","MSFT"]
))
asyncformessageinws:
data=json.loads(message)
print(data)
asyncio.run(main())
这段代码把心跳和数据订阅放在同一个异步循环里,用协程单独管理。
即使网络有轻微抖动,也能快速识别连接状态,不容易断开。
四、实际跑出来的真实效果
根据我长时间在线上运行的观察:
10 秒心跳:连续跑一两天都很稳,几乎不会被服务器断开
30 秒以上:经常丢消息、断连
5 秒:确实稳,但长期运行更耗性能
另外一个小细节:
心跳包越简单越好。
只发最必要的内容就行,带太多数据反而更容易断。
我现在做美股实时 tick 数据,统一用:
10 秒心跳 + 协程管理 + 自动重连
这套方案在跨境、高实时场景里,能稳住绝大多数情况。
如果你也在做美股数据、行情接口、WebSocket 开发,欢迎在评论区交流~
你平时心跳设几秒?用的是什么方案?
