Skip to content

Real-Time Communication

Real-Time Communication is the foundation of the RTC Agent user experience. Built on Centrifuge WebSocket, the system uses a dual-channel architecture: the Topic channel ensures no messages are lost, and the Live channel ensures low-latency streaming output — reliability and speed, without compromising either.

Topic ChannelLive Channel
PurposeState change eventsStreaming message intermediate chunks
Persistence✅ Written to database❌ Redis PUB/SUB
Offset✅ Strictly incrementing❌ None
Offline Recovery✅ Supported❌ Not supported
LatencyLower (requires persistence)Extremely low (in-memory forwarding)

💡 Design principle: Important messages go through Topic, speed-critical messages go through Live. State changes must be delivered reliably, while losing one or two intermediate chunks of streaming output is harmless.

Different types of events are routed to different channels:

Event TypeTopicLiveDescription
session.created/updatedSession state changes
turn.created/updatedTurn state changes
message.createdNew message created
message.updated (stream complete)Final state after stream completion
message.updated (stream intermediate chunk)Intermediate fragments of streaming output
rtc.updatedRTC tool call state changes

The Offset is the core of the Topic channel’s reliability — each event is assigned a strictly incrementing sequence number. Clients detect lost messages by checking sequence continuity:

FeatureDescription
Strictly incrementingEach Topic event’s Offset is greater than the previous one
Gap detectionWhen the client detects an Offset gap, it automatically fetches missing history
No loss, no duplicatesGuarantees messages are neither lost nor duplicated

AI model streaming output is the most frequently perceived real-time feature by users. The system achieves both real-time and reliable streaming through Topic + Live collaboration:

PhaseChannelAction
First chunkTopicCreate message record, push message.created
Intermediate chunksLiveAppend to Redis buffer, push to Live for real-time display
Last chunkTopicConcatenate full content, update database, push final state

💡 Why two steps? The Live channel lets each chunk reach the frontend instantly, giving users a smooth typing effect. Finally, the Topic channel pushes the complete message, ensuring that even if Live lost some chunks, the final state is complete and correct.

Network connections can’t always be stable. The system provides different strategies for recovery after disconnection:

ScenarioBehaviorUser Perception
🟢 Brief disconnectionMessages from offline period are automatically pushed after reconnectionNearly imperceptible
🟡 Extended disconnectionOffset gap detected, proactively fetches history to fill inSees backfilled messages
🔴 History cleaned upEpoch changed, local Offset cleared, starts from latest positionContinues from current state

Epoch is the timeline identifier for Offsets. When the server performs large-scale cleanup or rebuilding, the Epoch changes and clients need to reset their Offset to start from the latest position — because the old history no longer exists.

MechanismDescription
Auto-reconnectCentrifuge SDK built-in reconnection with exponential backoff
Token refreshAutomatically refreshes authentication token when connection is restored
Offset persistenceOffset is stored in IndexedDB and restored after page refresh
Fallback strategyUser must re-login when token refresh fails

📌 Offset persistence to IndexedDB means: even if the user closes the browser tab and reopens it, they can continue receiving messages from where they left off, without missing any updates.