Keep-Alive
WebSocket Quote Push is a long-connection service. Clients must correctly handle WebSocket protocol-layer ping/pong, network timeouts, reconnection, and re-authentication and re-subscription after reconnection.
WARNING
The current Quote Push API does not define a business-layer JSON heartbeat message. Do not send custom business heartbeat frames such as { "action": "heartbeat" } or { "type": "ping" } to the connection, and do not rely on the server to return any JSON heartbeat event.
Connection keep-alive should use the WebSocket protocol-layer ping/pong capability, or the connection state, timeout, and reconnect mechanisms provided by the client SDK / WebSocket library.
Ping / Pong
The WebSocket protocol itself supports ping/pong control frames. Handling varies by runtime:
| Client Type | Recommendation |
|---|---|
| Browser WebSocket | The browser automatically responds to server pings at the protocol layer. Business code typically cannot directly send or observe protocol-layer ping/pong; it only needs to handle open, message, error, and close events. |
| Server-side clients (Node.js, Java, Go, Python, etc.) | Prefer the built-in ping/pong, read/write timeout, and idle detection of the WebSocket library. Return pong promptly when receiving a server ping; if the client library needs to initiate pings, configure it based on your network environment. |
| Mobile or weak-network environments | Watch for connection hangs caused by foreground/background switches, network changes, and system power-saving policies. After the network recovers, check the connection state and reconnect if necessary. |
The platform does not require the client to send a heartbeat packet in any fixed JSON format. If your WebSocket library supports protocol-layer ping, you can enable the library's built-in ping/pong mechanism; if the runtime does not expose protocol-layer ping, determine connection availability via close events and business-message timeouts.
Periodic Token Refresh
Access Tokens issued by OAuth 2.1 have a validity period. To prevent the server from actively disconnecting due to token expiry, the client should refresh the token periodically before it expires:
- When obtaining the token, record
expires_in(validity period in seconds). - At around half of the token's validity period, or 5 minutes before expiry, use the Refresh Token to obtain a new Access Token.
- After obtaining the new token, send a login/auth message again over the current WebSocket connection to complete the token update.
- If the refresh fails (for example, the Refresh Token has also expired), guide the user to re-authorize.
TIP
Periodic token refresh is a key step in long-connection keep-alive. Even if the network and WebSocket protocol-layer ping/pong are working normally, the server will still disconnect once the token expires.
Timeout Handling
Long connections may be dropped or become unavailable for the following reasons:
- Local network changes, proxies, or firewalls interrupting the connection.
- Client process sleep, mobile app backgrounding, or the system reclaiming network resources.
- Server release, scaling, or maintenance.
- No effective read/write on the connection for a long time, judged as idle timeout by intermediate links or the WebSocket library.
It is recommended that clients implement the following timeout strategies:
- Connection establishment timeout: If the connection does not enter the
openstate within a reasonable time after being initiated, close the current connection and retry. - Auth response timeout: After the connection is established, login/auth must be completed first. If the auth request has no response for a long time, close the connection and re-establish it.
- Subscription response timeout: After a subscription request is sent, if no response is received for a long time, decide whether to retry the subscription or reconnect based on the connection state.
- Business-message idle detection: If the connection is open but no messages arrive for a long time, combine protocol-layer ping/pong, market trading hours, and the activity of subscribed symbols to judge whether the connection is still healthy. Do not immediately declare the connection dead just because there are no quote pushes outside trading hours.
Set specific timeouts based on your client's network environment, product realtime requirements, and WebSocket library capabilities. The document does not commit to fixed public ping intervals or timeout thresholds.
Reconnect
When receiving a close event, connection exception, auth failure, unavailable subscription link, or upon local detection of connection failure, the client should re-establish the WebSocket connection.
Recommended reconnect flow:
- Stop sending new requests on the old connection.
- Clean up the local state of the old connection, such as pending requests awaiting response, the connection object, and temporary timers.
- Use a backoff strategy to reconnect; avoid high-frequency retries within a short period.
- After the connection is established, log in/authenticate again.
- After successful auth, re-subscribe to the symbols and data types still needed by the current business.
- After subscriptions are restored, use the REST realtime quote API to backfill the latest state if needed.
It is recommended to use exponential or segmented backoff — for example, retry quickly after the first disconnection, then gradually increase the wait time on consecutive failures, with a maximum retry interval cap. Do not retry at high frequency indefinitely when the network is unavailable or the server keeps rejecting.
Re-authentication and Re-subscription
WebSocket subscription state is tied to the current connection session. After a disconnection, do not assume the server still retains the subscription state from the old connection.
After every reconnect, recover in the following order:
Establish WebSocket connection
-> Login / authenticate
-> Subscribe to quote / order_book / ticker / kline, etc.
-> Receive pushesNotes:
- You must re-authenticate after reconnecting. Do not reuse the session state of the old connection.
- You must re-send subscription requests after reconnecting. The client should maintain "what the current business needs to subscribe to" locally, rather than relying on the server to recover it.
- If the access credentials have expired, refresh them first, then re-establish the connection or re-authenticate.
- If the user has left the page or unfollowed some symbols during the reconnect window, do not restore those no-longer-needed subscriptions.
- Subscription requests are recommended to carry a client-generated request
idso that responses can be correlated with local recovery tasks.
Combining REST for the Initial Snapshot
WebSocket push is better suited for receiving realtime changes and is not suitable as the sole source of the full initial state. To reduce first-render wait time and avoid missing the latest state during disconnections, combine the REST realtime quote API in the following scenarios:
| Scenario | Recommended Practice |
|---|---|
| First page open | First call REST to fetch the quote snapshot or realtime quote and render the first screen quickly; then establish a WebSocket connection and subscribe to realtime pushes. |
| After a successful reconnect | Use REST to query the latest snapshot, order book, current K-line, or ticker, then continue consuming WebSocket pushes. |
| Recovery after long background period | First check whether the connection is still valid; if a reconnect occurred, use REST to backfill the latest state at the recovery moment. |
| High consistency requirements for full state | Use the REST query result as the full-state baseline at a given point in time, then apply incremental refreshes from WebSocket pushes. |
Related REST APIs:
Server-Side Session Cleanup
After a connection drops, the server identifies the offline connection in the background and cleans up the corresponding session and subscription resources. This cleanup is an internal server protection mechanism to release resources held by offline connections.
The client should not rely on the server's cleanup timing to manage its own subscription state:
- When leaving a page normally, switching symbols, or no longer needing a certain type of data, proactively send an unsubscribe request.
- On an abnormal disconnection, the client should follow the reconnect flow to re-authenticate and re-subscribe, rather than waiting for the old session to recover.
- Do not assume subscriptions on the old connection are automatically inherited by the new connection.
- Do not wait for server-side session cleanup to complete before re-subscribing; treat the new connection as a fresh, independent session.
Client Implementation Recommendations
It is recommended that the client maintain a local subscription-intent table recording the subscription items the current business actually needs:
symbol + data_type + optional params (e.g. kline period / adjust)When the connection recovers, re-send subscription requests based on this subscription-intent table. This avoids the following issues:
- Forgetting to restore some subscriptions after a disconnection.
- Restoring old subscriptions the user has already unfollowed.
- Multiple pages or modules subscribing to the same symbol, causing local state confusion.
- Being unable to tell which subscription responses correspond to the current connection during reconnect.
Also recommended:
- Surface the connection state to the user, e.g. "Connecting", "Realtime quote connected", "Reconnecting".
- Set alerts or user prompts for consecutive reconnect failures.
- Handle business errors such as subscription failure, permission insufficient, and quota insufficient independently; do not simply reconnect indefinitely.
- On page close, component unmount, or when the business no longer needs data, proactively unsubscribe and close the connection.
Common Misconceptions
| Misconception | Explanation |
|---|---|
| Sending a JSON heartbeat packet is enough for keep-alive | Quote Push does not define a business-layer JSON heartbeat protocol. Use WebSocket protocol-layer ping/pong or the client library's connection keep-alive capability. |
| Subscriptions auto-restore after disconnection | Do not assume this. Re-authenticate and re-subscribe after reconnecting. |
| WebSocket push means REST is unnecessary | WebSocket is for realtime changes; first-screen full state, disconnection backfill, and consistency calibration still benefit from REST. |
| No quote push means the connection is broken | Outside trading hours, for inactive symbols, or for subscription types with inherently low update frequency, there may be no business pushes for a long time. Judge via protocol-layer heartbeat and connection events. |
| The client must wait for the server to clean up the old session before reconnecting | The client can directly establish a new connection and restore subscriptions. The server cleans up offline session resources on its own. |
Next Steps
- Authentication — Learn the auth flow after a connection is established.
- Subscribe and Unsubscribe — Learn how to restore subscriptions and proactively unsubscribe.
- Data Format — Learn the push message structure and fields.
- Error Codes — Troubleshoot auth, subscription, permission, and quota errors.