client.Realtime is the shared Centrifugo WebSocket client. Prefer typed service helpers
(client.Balances.Subscribe, client.Trades.Subscribe, ...). They return *realtime.Subscription[T]. Your order updates use the private WebSocket instead: see Orders.Subscribe.
Realtime is binary-only: the transport negotiates centrifuge-protobuf and uses length-delimited
Protobuf control frames and publication payloads. JSON wire mode applies only to ConnectRPC
debugging, never to realtime. Incoming WebSocket messages and protobuf record/field lengths are
capped at 8 MiB.
Managed order-book and market-overview subscriptions return dedicated types that expose Updates() instead of Messages(). They also expose SetOnError(...) and Err(); register
the callback so a managed feed failure cannot leave quoting logic on a frozen book.
Subscription contract
Messages():<-chan Tof decoded publications; closes when the sub endsDone(): Signal when the subscription has fully stoppedErr(): Terminal error (*errors.QueueOverflowErroron overflow)SetOnError: Callback for background transport/feed errorsResubscribes(): Count of successful reconnect subscriptions; continuity may be lostTakeResubscribed(): Edge-triggered reconnect-gap signal for reconciliationClose(): Stop the subscription
There is no Recv() method in Go. Range or select on Messages() (or Updates() for
managed books).
sub, err := client.Balances.Subscribe(ctx, accountID)
if err != nil { log.Fatal(err) } // handshake already completed
defer sub.Close()
sub.SetOnError(func(err error) {
log.Printf("realtime interruption: %v", err)
})
for balance := range sub.Messages() {
fmt.Println(balance.AssetID, balance.Available)
}
if err := sub.Err(); err != nil {
log.Printf("ended: %v", err)
}Handshake before return
SubscribeProto / service subscribe helpers wait for the Centrifugo connect/subscribe handshake
(including private token fetch) before returning. Initial auth failures return an error immediately;
they do not reconnect forever in the background. Orders.Subscribe is the exception: it returns at
once and reports the connection as events.
Reconnects after a successful handshake use capped exponential backoff with per-subscription
jitter. A successful resubscription resets the backoff. Private subscriptions renew their connection
and subscription tokens before they expire; a failed renewal is reported through SetOnError and
the subscription then resubscribes as usual.
Private channels need Account ID
Private channels require API-key credentials and an Account ID (Subscribe(ctx, accountID) or Config.DefaultAccountID / POLYESTER_ACCOUNT_ID).
The accountID argument is any:
- Account ID string (or
*string)
Used as given. This is the value shown in Profile. nilor""
Uses the client's default Account ID.- Positive integer
Addresses the account it names, encoded as its public ID ascodecs.FormatIDdoes (42becomes"j"). It is not formatted as decimal text. - Anything else
0, a negative value, abool, a float or another type returns*errors.ValidationErrorbefore connecting.
Fail-closed overflow
*errors.QueueOverflowError instead of dropping updates.Generic typed subscriptions default to a 1000-item queue. Managed order-book subscriptions use a dedicated 200-item update queue. Either queue fails closed on overflow.
Snapshot-then-stream
Order book and market overview managed subscriptions snapshot via REST, then stream deltas/batches with gap recovery. Their create methods wait for the WebSocket handshake and initial snapshot before returning. Prefer those helpers over wiring raw channels yourself.
Lower-level
sub, err := realtime.SubscribeProto(ctx, client.Realtime, channel, decodeFn)See Streaming. Session model: WebSocket session model.