client.Realtime is the shared Centrifugo WebSocket client. Prefer typed service helpers
(client.Orders.Subscribe, client.Balances.Subscribe, โฆ). They return *realtime.Subscription[T].
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
| API | Behavior |
|---|---|
Messages() | <-chan T of decoded publications; closes when the sub ends |
Done() | Signal when the subscription has fully stopped |
Err() | Terminal error (*errors.QueueOverflowError on overflow) |
SetOnError | Callback for background transport/feed errors |
Resubscribes() | Count of successful reconnect subscriptions; continuity may be lost |
TakeResubscribed() | Edge-triggered reconnect-gap signal for reconciliation |
Close() | Stop the subscription |
There is no Recv() method in Go. Range or select on Messages() (or Updates() for
managed books).
sub, err := client.Orders.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 order := range sub.Messages() {
fmt.Println(order.Status, order.OrderID)
}
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.
Reconnects after a successful handshake use capped exponential backoff with per-subscription
jitter. A successful resubscription resets the backoff.
Private channels need Account ID
Private channels require API-key credentials and an Account ID (Subscribe(ctx, accountID) or Config.DefaultAccountID / POLYESTER_ACCOUNT_ID).
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.