The connection and session lifecycle state machine.
One session owns one WebSocket via a Lightstreamer.Transport — a protocol
constraint (TLCP allows one stream connection per session), not a design
choice. The process is a thin router: it feeds inbound text through
Lightstreamer.Protocol.Frame, merges update deltas with
Lightstreamer.Protocol.Update, and forwards events to each subscription's
owner pid. No consumer logic ever runs here.
States: :connecting → :ws_handshake → :creating | :binding → :streaming,
plus :backoff between recovery attempts and :failed holding an initial
connection error until the connect/2 caller collects it.
Lifecycle rules:
LOOP— the server asks for a rebind: new transport,wsok+bind_session. Silent, and per-item field state is preserved (the session survives).- Keepalive expiry / socket loss — try
bind_sessionfirst (cheap, keeps the server-side session); if the bind is refused, fall back to a fullcreate_session. END/ re-create — the session is dead: freshcreate_session, all subscriptions re-issued with their original parameters and their per-item state reset, so stale merges cannot survive into the new snapshot (owners seesnapshot?: trueagain).- Backoff between failed recovery attempts is exponential with jitter,
capped.
CONERRcode 1 (bad credentials) is never retried — retrying bad credentials is how upstream accounts get locked. reconnect: :neverturns any of the above failures into notification and a stop.
Use through Lightstreamer — this module is not called directly.