Skip to content

連接保活

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,只需要處理 openmessageerrorclose 等事件。
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 到期前定時刷新:

  1. 在獲取 token 時記錄 expires_in(有效期秒數)。
  2. 建議在 token 有效期過半或到期前 5 分鐘時,使用 Refresh Token 獲取新的 Access Token。
  3. 獲取新 token 後,通過當前 WebSocket 連接重新發送登錄鑑權消息,完成 token 更新。
  4. 如果刷新失敗(例如 Refresh Token 也已過期),應引導用户重新授權。

TIP

定時刷新 token 是長連接保活的關鍵步驟。即使網絡和 WebSocket 協議層 ping/pong 一切正常,token 過期後服務端仍會斷開連接。

超時處理

長連接可能因為以下原因斷開或變得不可用:

  • 本地網絡切換、代理或防火牆中斷連接。
  • 客户端進程休眠、移動端進入後台、系統回收網絡資源。
  • 服務端發佈、擴縮容或維護。
  • 連接長時間無有效讀寫,被中間鏈路或 WebSocket 庫判定為空閒超時。

建議客户端實現以下超時策略:

  1. 連接建立超時:發起連接後,如果在合理時間內未進入 open 狀態,應關閉本次連接並重試。
  2. 鑑權響應超時:連接建立後需要先完成登錄鑑權。如果鑑權請求長時間沒有響應,應關閉連接並重新建立。
  3. 訂閲響應超時:訂閲請求發出後,如果長時間未收到響應,應結合連接狀態決定是否重試訂閲或重連。
  4. 業務消息空閒檢測:如果連接處於打開狀態但長時間沒有任何消息,應結合協議層 ping/pong、行情時段和訂閲標的活躍度判斷連接是否仍然健康。不要僅因非交易時段沒有行情推送就立即判定連接失效。

具體超時時間請按客户端所在網絡環境、產品實時性要求和 WebSocket 庫能力設置。文檔不承諾固定的公網 ping 間隔或超時閾值。

斷線重連

收到 close 事件、連接異常、鑑權失敗、訂閲鏈路不可用或本地檢測到連接失效時,客户端應重新建立 WebSocket 連接。

推薦重連流程:

  1. 停止向舊連接發送新請求。
  2. 清理舊連接的本地狀態,例如正在等待響應的請求、連接對象、臨時定時器等。
  3. 使用退避策略重新連接,避免短時間高頻重試。
  4. 連接建立後重新登錄鑑權。
  5. 鑑權成功後重新訂閲當前業務仍然需要的標的和數據類型。
  6. 訂閲恢復後,按需通過 REST 實時行情接口補齊最新狀態。

建議使用指數退避或分段退避策略,例如首次斷線後較快重試,連續失敗後逐步增加等待時間,並設置最大重試間隔。不要在網絡不可用或服務端持續拒絕時無限高頻重連。

重新鑑權與重新訂閲

WebSocket 訂閲狀態與當前連接會話相關。連接斷開後,不應假設服務端仍然保留舊連接上的訂閲狀態。

每次重連後都應按以下順序恢復:

text
建立 WebSocket 連接
  -> 登錄鑑權
  -> 訂閲 quote / order_book / ticker / kline 等數據
  -> 接收推送

注意事項:

  • 重連後必須重新鑑權。不要複用舊連接的會話狀態。
  • 重連後必須重新發送訂閲請求。客户端應在本地維護“當前業務需要訂閲什麼”,而不是依賴服務端恢復。
  • 如果訪問憑證已經過期,應先刷新憑證,再重新建立連接或重新鑑權。
  • 如果重連期間用户已經離開頁面或取消關注某些標的,不要恢復這些不再需要的訂閲。
  • 訂閲請求建議攜帶客户端生成的請求 id,便於將響應與本地待恢復任務對應起來。

結合 REST 獲取首屏快照

WebSocket 推送更適合接收實時變化,不適合作為首屏完整狀態的唯一來源。為了減少首次渲染等待時間,並避免在斷線期間遺漏最新狀態,建議在以下場景結合 REST 實時行情接口:

場景推薦做法
頁面首次打開先調用 REST 獲取行情快照或實時報價,快速渲染首屏;隨後建立 WebSocket 連接並訂閲實時推送。
斷線重連成功後使用 REST 查詢最新快照、買賣盤、當前 K 線或逐筆成交,再繼續消費 WebSocket 推送。
長時間後台後恢復先檢查連接是否仍然有效;如果發生重連,建議用 REST 補齊恢復時刻的最新狀態。
對完整狀態一致性要求高以 REST 查詢結果作為某一時點的完整狀態基線,再用 WebSocket 推送增量刷新。

相關 REST 接口可參考:

服務端會話清理

連接斷開後,服務端會在後台識別離線連接並清理對應會話和訂閲資源。該清理過程是服務端內部保護機制,用於釋放離線連接佔用的資源。

客户端不應依賴服務端清理時機來管理自身訂閲狀態:

  • 正常退出頁面、切換標的或不再需要某類數據時,應主動發送反訂閲請求。
  • 連接異常斷開時,客户端應按重連流程重新鑑權並重新訂閲,而不是等待舊會話恢復。
  • 不要假設舊連接上的訂閲會在新連接中自動繼承。
  • 不要依賴服務端會話清理完成後才重新訂閲;新連接應作為新的獨立會話處理。

客户端實現建議

建議客户端維護一份本地訂閲意圖表,用於記錄當前業務真正需要的訂閲項:

text
symbol + data_type + 可選參數(如 kline period / adjust)

連接恢復時,根據這份訂閲意圖表重新發送訂閲請求。這樣可以避免以下問題:

  • 斷線後忘記恢復部分訂閲。
  • 用户已經取消關注後仍然恢復舊訂閲。
  • 多個頁面或模塊重複訂閲同一標的,導致本地狀態混亂。
  • 重連過程中無法區分哪些訂閲響應對應當前連接。

同時建議:

  • 將連接狀態展示給用户,例如“連接中”“實時行情已連接”“正在重連”。
  • 對連續重連失敗設置告警或用户提示。
  • 對訂閲失敗、權限不足、配額不足等業務錯誤進行獨立處理,不要簡單地無限重連。
  • 頁面關閉、組件卸載或業務不再需要時,主動反訂閲並關閉連接。

常見誤區

誤區說明
發送 JSON 心跳包即可保活行情推送不定義業務層 JSON 心跳協議。應使用 WebSocket 協議層 ping/pong 或客户端庫的連接保活能力。
斷線後訂閲會自動恢復不應這樣假設。重連後應重新鑑權並重新訂閲。
有 WebSocket 推送就不需要 RESTWebSocket 適合實時變化;首屏完整狀態、斷線補齊和一致性校準仍建議結合 REST。
沒有行情推送就是連接斷了非交易時段、標的不活躍或訂閲類型本身更新頻率低時,可能長時間沒有業務推送。應結合協議層心跳和連接事件判斷。
服務端清理舊會話後客户端才能重連客户端可以直接建立新連接並恢復訂閲。服務端會自行清理離線會話資源。

下一步