連接保活
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 或客戶端庫的連接保活能力。 |
| 斷線後推送狀態會自動恢復 | 不應這樣假設。重連後應重新鑑權,斷線期間的事件不會補發。 |
| 沒有推送消息就是連接斷了 | 交易事件是被動觸發的,沒有交易發生時不會有推送,不能以此判定連接失效。 |