通常的补偿机制思路

客户端如果发现 WebSocket 断了,需要马上重新连接(重连机制一般自动做)。连接上后,客户端必须主动拉取一份最新的快照(snapshot)数据。客户端拿到最新快照,比如订单簿、自己的挂单列表。再用快照之后发生的WebSocket增量更新(diff)数据,把本地状态补到最新。这就是快照(snapshot)+增量(diff)同步机制

假设在币安通过 WebSocket 订阅了某个交易对的深度行情(比如 BTC/USDT 的盘口),订阅的是depthUpdate推送。正常推送时,WebSocket 每秒推送多条 depthUpdate 增量消息(如买单挂了/卖单撤了)。每条增量消息里面有一个连续递增的 u(update id)。客户端应该根据 u,一条一条地应用这些变化到本地的订单簿上。

如果断了,需要重新连接 WebSocket 断线重连后,不能直接信任新推送的增量消息。因为中间有一段断开的消息流,可能漏了。用 HTTP API,拉取完整深度快照(比如最近 500 条盘口挂单信息)。这个快照接口是专门提供的,比如 /api/v3/depth?symbol=BTCUSDT&limit=1000

衔接快照和 WebSocket 流,HTTP 快照里有一个 lastUpdateId 字段,告诉这是到哪个位置的深度数据。WebSocket 收到的增量消息的 Uu(first update id / final update id)可以对齐快照。应用所有 u > lastUpdateId 的 WebSocket 消息,补上中间断掉的部分。当本地盘口跟服务器状态一致时,继续实时应用后续 WebSocket 推送。这样即使 WebSocket 断开了,也能把丢失期间的盘口变化补回来,保证本地是正确的、同步的。

订单系统也是同样道理,如果订阅的是自己账户的订单更新流(account/order update stream),比如:成交通知、撤单通知、挂单失败通知,一旦 WebSocket 断了,一样的,重连后,重新通过 REST API 拉取自己最新的活跃订单列表成交记录。补充丢失的那一段交易数据。这样才能保证:本地看到的订单状态是最新的,不漏单、不错单。

这样设计的原因在于:WebSocket 断开是常态,不是异常(网络、服务器限流都会导致短时间断开)。TCP虽然保证消息顺序和可靠传输,但连接断开后,中间的消息就可能丢失。补快照是最保险的方法,避免由于漏了一条关键消息(比如成交通知)而导致严重后果(比如资金账不对)。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐