The WebSocket gateway (cmd/ws) is the real-time event delivery layer. Clients maintain a single persistent WebSocket connection through which they receive all server-push events (messages, guild updates, presence, voice notifications) and send control commands (heartbeats, subscriptions, presence updates).
GET /subscribe
Traefik routes /ws → ws:3100 (with StripPrefix), so the external URL is wss://example.com/ws/subscribe.
Important
Two separate WebSocket connections exist in gochat:
| Connection | Service | Endpoint | Purpose |
|---|---|---|---|
| Gateway WS | cmd/ws (port 3100) |
/subscribe |
Chat events, presence, subscriptions, heartbeat |
| Voice SFU WS | cmd/sfu (port 3300) |
/signal |
WebRTC signaling, media negotiation, speaking indicators |
These are independent connections — a client has one Gateway WS open at all times, and opens a separate SFU WS only when joining a voice channel. This documentation covers the Gateway WS. For the SFU WS protocol, see Voice Protocol docs.
- zlib-stream compression — append
?compress=zlib-streamto receive binary frames compressed with zlib (best-speed level). - Connection Hub — one shared NATS subscription per topic across all local connections, with in-memory fan-out.
- Writer pump — async outbound channel (256 buffer) with non-blocking drop for slow consumers.
- OpenTelemetry telemetry — connection lifecycle, subscriptions, heartbeat timeouts, inbound/outbound delivery, and drop metrics flow into OpenObserve through the shared observability pipeline.
- Connection Lifecycle — Authentication, heartbeat, and disconnect flows
- Event Message Structure — Envelope format, OP codes, and client-sent payloads
- Event Types — Complete list of
t(event type) values and their payloads - Subscription Model — How guild, channel, and presence subscriptions work