连接保活
WebSocket 交易推送是长连接服务。客户端需要正确处理 WebSocket 协议层的 ping/pong、网络超时、断线重连,以及重连后的重新鉴权。
WARNING
当前交易推送接口不定义业务层 JSON 心跳消息。请不要向连接发送自定义的 { "action": "heartbeat" }、{ "type": "ping" } 等业务心跳帧,也不要依赖服务端返回某种 JSON 心跳事件。
连接保活应使用 WebSocket 协议层 ping/pong 能力,或使用客户端 SDK / WebSocket 库提供的连接状态、超时和重连机制。
Ping / Pong
WebSocket 协议本身支持 ping/pong 控制帧。不同运行环境的处理方式不同:
| 客户端类型 | 建议 |
|---|---|
| 浏览器 WebSocket | 浏览器会在协议层自动响应服务端 ping。业务代码通常无法直接发送或监听协议层 ping/pong,只需要处理 open、message、error、close 等事件。 |
| Node.js、Java、Go、Python 等服务端客户端 | 优先使用 WebSocket 库内置的 ping/pong、读写超时和空闲检测能力。收到服务端 ping 时应及时返回 pong;如客户端库需要主动 ping,可按业务网络环境配置。 |
| 移动端或弱网络环境 | 关注前后台切换、网络切换、系统省电策略导致的连接挂起。恢复网络后应检查连接状态,必要时重连。 |
平台不要求客户端发送某个固定 JSON 格式的心跳包。若你的 WebSocket 库支持协议层 ping,可以开启库自带的 ping/pong 机制;若运行环境不暴露协议层 ping,则应通过连接关闭事件和业务消息超时来判断连接是否可用。
定时刷新 Token
OAuth 2.1 签发的 Access Token 有有效期限制。为避免 token 过期导致连接被服务端主动断开,客户端应在 token 到期前定时刷新:
- 在获取 token 时记录
expires_in(有效期秒数)。 - 建议在 token 有效期过半或到期前 5 分钟时,使用 Refresh Token 获取新的 Access Token。
- 获取新 token 后,通过当前 WebSocket 连接重新发送登录鉴权消息,完成 token 更新。
- 如果刷新失败(例如 Refresh Token 也已过期),应引导用户重新授权。
TIP
定时刷新 token 是长连接保活的关键步骤。即使网络和 WebSocket 协议层 ping/pong 一切正常,token 过期后服务端仍会断开连接。
超时处理
长连接可能因为以下原因断开或变得不可用:
- 本地网络切换、代理或防火墙中断连接。
- 客户端进程休眠、移动端进入后台、系统回收网络资源。
- 服务端发布、扩缩容或维护。
- 连接长时间无有效读写,被中间链路或 WebSocket 库判定为空闲超时。
建议客户端实现以下超时策略:
- 连接建立超时:发起连接后,如果在合理时间内未进入
open状态,应关闭本次连接并重试。 - 鉴权响应超时:连接建立后需要先完成登录鉴权。如果鉴权请求长时间没有响应,应关闭连接并重新建立。
- 业务消息空闲检测:如果连接处于打开状态但长时间没有任何消息,应结合协议层 ping/pong 判断连接是否仍然健康。不要仅因账户暂无交易事件就立即判定连接失效,交易推送是被动触发的,没有交易事件发生时不会有推送。
具体超时时间请按客户端所在网络环境、产品实时性要求和 WebSocket 库能力设置。
断线重连
收到 close 事件、连接异常、鉴权失败或本地检测到连接失效时,客户端应重新建立 WebSocket 连接。
推荐重连流程:
- 停止向旧连接发送新请求。
- 清理旧连接的本地状态,例如正在等待响应的请求、连接对象、临时定时器等。
- 使用退避策略重新连接,避免短时间高频重试。
- 连接建立后重新登录鉴权。
- 鉴权成功后,服务端自动重新建立推送通道,继续推送后续发生的事件。
- 如需了解断线期间的订单和成交状态,按需通过 REST 接口补齐。
建议使用指数退避或分段退避策略,例如首次断线后较快重试,连续失败后逐步增加等待时间,并设置最大重试间隔。不要在网络不可用或服务端持续拒绝时无限高频重连。
重新鉴权
WebSocket 推送通道与当前连接会话相关。连接断开后,不应假设服务端仍然保留旧连接上的鉴权状态。
每次重连后都应按以下顺序恢复:
建立 WebSocket 连接
-> 登录鉴权
-> 接收推送注意事项:
- 重连后必须重新鉴权。不要复用旧连接的会话状态。
- 如果访问凭证已经过期,应先刷新凭证,再重新建立连接或重新鉴权。
结合 REST 补齐状态
WebSocket 推送更适合接收实时事件通知,不适合作为状态重建的唯一来源。建议在以下场景结合 REST 接口:
| 场景 | 推荐做法 |
|---|---|
| 页面首次打开 | 先调用 REST 查询当前订单和成交状态,快速渲染首屏;随后建立 WebSocket 连接接收后续事件。 |
| 断线重连成功后 | 使用 REST 查询断线期间可能遗漏的订单状态变更,再继续消费 WebSocket 推送。 |
| 长时间后台后恢复 | 先检查连接是否仍然有效;如果发生重连,建议用 REST 补齐恢复时刻的最新状态。 |
常见误区
| 误区 | 说明 |
|---|---|
| 发送 JSON 心跳包即可保活 | 交易推送不定义业务层 JSON 心跳协议。应使用 WebSocket 协议层 ping/pong 或客户端库的连接保活能力。 |
| 断线后推送状态会自动恢复 | 不应这样假设。重连后应重新鉴权,断线期间的事件不会补发。 |
| 没有推送消息就是连接断了 | 交易事件是被动触发的,没有交易发生时不会有推送,不能以此判定连接失效。 |