RTick

连接与心跳

为保障长连接稳定性并及时清理僵尸连接,客户端与服务端之间采用标准 Ping-Pong 心跳保活机制。

心跳规则

  1. 客户端心跳发送:连接建立成功后,客户端需每隔 30 秒发送一次 ping 请求帧:
{
  "requestId": "hb-1781962260000",
  "action": "ping"
}
  1. 服务端应答:服务端收到后立即返回控制帧(event: 0),并附带服务端秒级时间戳(可用于客户端本地时钟校准):
{
  "requestId": "hb-1781962260000",
  "event": 0,
  "code": 200,
  "msg": "pong",
  "server_time": 1781962260
}

超时判定与断线重连

  • 若服务端连续 60 秒未收到客户端任何数据帧,判定连接假死,下发 code=408 控制帧并主动断开连接。
  • 若客户端连续 30 秒未收到 pong 应答,建议主动断开并触发指数退避重连(如 1s, 2s, 4s,最长 30s)。
  • 重连恢复机制:断线重连后长连接会话重置,客户端需重新发起订阅请求以恢复行情订阅关系。

重连示例

const ws = new WebSocket("wss://api.rtick.io/ws?apiKey=<your_api_key>");

let pingTimer = null;
ws.onopen = () => {
  // 每 30 秒发送心跳
  pingTimer = setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ requestId: `hb-${Date.now()}`, action: "ping" }));
    }
  }, 30000);
  // 发起订阅 ...
};

ws.onclose = () => {
  clearInterval(pingTimer);
  // 指数退避重连:1s -> 2s -> 4s -> ... 最长 30s
  scheduleReconnect();
};

ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.event === 0 && msg.msg === "pong") {
    // 心跳应答,可校准本地时钟 msg.server_time
  }
};

说明

  • requestId 在请求与应答中原样返回,用于请求响应配对。
  • 服务端 server_time 为秒级时间戳,客户端可据此估算网络延迟与校准时钟。
连接与心跳 · RTick