Skip to content
AllTick
Integration TutorialsPython 3.11 · websockets 12

Python WebSocket: Reconnect & Heartbeats

Build a production-ready Python WebSocket client with market subscriptions, periodic heartbeats, exponential backoff, and automatic resubscription.

Updated:
Maintained by:AllTick Technical Team
Audience:Python engineers consuming real-time streaming market data

Core Takeaway · 30-Second Brief

A production-grade WebSocket market client requires four components: sending the subscription payload on connect, transmitting periodic application heartbeats, reconnecting with jittered exponential backoff on disconnect, and automatically resubscribing on every new connection.

01

Protocol Essentials

ItemAllTick Specification
Equities WebSocket URLwss://quote.alltick.co/quote-stock-b-ws-api?token=YOUR_TOKEN
Forex / Metals / Commodities URLwss://quote.alltick.co/quote-b-ws-api?token=YOUR_TOKEN
Trade Subscription Commandcmd_id 22004 with data.symbol_list
Application Heartbeatcmd_id 22000 sent every 10 seconds

02

Complete Runnable Code

Terminal Commandbash
pip install websockets
stream_quotes.pypython
import asyncio, json, os, random, uuid
import websockets
WS_URL = "wss://quote.alltick.co/quote-stock-b-ws-api?token={token}"
CMD_SUBSCRIBE_TRADE = 22004
CMD_HEARTBEAT = 22000
HEARTBEAT_SECONDS = 10
CODES = ["700.HK", "AAPL.US"]
def message(cmd_id: int, data: dict) -> str:
return json.dumps({"cmd_id": cmd_id, "seq_id": 1, "trace": str(uuid.uuid4()), "data": data})
async def heartbeat(ws):
while True:
await asyncio.sleep(HEARTBEAT_SECONDS)
await ws.send(message(CMD_HEARTBEAT, {}))
async def run_once(url: str):
async with websockets.connect(url, ping_interval=None) as ws:
await ws.send(message(CMD_SUBSCRIBE_TRADE, {"symbol_list": [{"code": c} for c in CODES]}))
beat = asyncio.create_task(heartbeat(ws))
try:
async for raw in ws:
handle(json.loads(raw))
finally:
beat.cancel()
def handle(msg: dict):
if msg.get("cmd_id") == CMD_HEARTBEAT + 1:
return
print(msg)
async def main():
token = os.getenv("ALLTICK_API_TOKEN", "YOUR_API_TOKEN")
url = WS_URL.format(token=token)
delay = 1
while True:
try:
await run_once(url)
delay = 1
except (websockets.WebSocketException, OSError) as exc:
wait = min(delay, 60) + random.uniform(0, 1)
print(f"Disconnected: {exc!r}, reconnecting in {wait:.1f}s")
await asyncio.sleep(wait)
delay *= 2
if __name__ == "__main__":
asyncio.run(main())

03

Key Design Decisions

  • Subscription runs inside run_once, guaranteeing automatic resubscription after every reconnect.
  • Backoff starts at 1 second, doubles up to 60 seconds, and adds random jitter to prevent thundering herds.
  • The heartbeat task is cancelled inside finally so it never writes to a closed socket.
  • ping_interval=None disables protocol-level pings in favor of AllTick’s application-level cmd_id 22000 heartbeat.
  • Heartbeat acknowledgments are filtered out in handle() to keep downstream consumers clean.

04

Production Hardening Checklist

1Replace print statements with structured logging that records disconnect reasons and recovery duration.
2Alert when consecutive reconnection attempts exceed a threshold.
3Backfill missed K-line bars via REST after a reconnection completes.
4Keep subscribed symbol counts within your plan tier’s per-connection limit.

Sources & Verification · 2026-10-13

Relevant endpoint, field, and exchange rules were checked against the primary specifications linked below.

Python examples passed ast.parse on Python 3.14.0. This checks syntax only; dependencies, runtime compatibility, and network responses were not tested.

Authenticated AllTick requests and production end-to-end tests were not run for this review. Record your token plan, library versions, market session, ret/trace, and observed results when reproducing these checks.

Reproduce before deployment

  • Send cmd_id 22000 every 10 seconds and inspect response 22001; the documented timeout is 30 seconds. Force disconnection and stop old heartbeat tasks before reconnecting.
  • Resubscribe after recovery and check acknowledgement. Use jitter and a capped retry budget; avoid parallel reconnects exceeding token connection limits.