Перейти к основному содержимому

Real-time Events

When an agent finishes processing a message, the user should see the response instantly, not on their next API poll.

In plain language, this page answers: "How does the app know something changed without constantly asking the backend?"

Crawbl uses Socket.IO backed by Redis pub/sub to push events to connected clients in real time.

Architecture Overview

Real-time Events Architecture
Click diagram to zoom

How It Works

The orchestrator runs a Socket.IO server on the /v1 namespace. When a mobile client opens the app, it connects via WebSocket and authenticates using the same headers as REST requests (X-Token or Authorization: Bearer). On successful authentication, the client automatically joins a workspace room (workspace:{workspaceId}).

If the term "room" is unfamiliar, think of it as a private broadcast group for one workspace. Events sent to that room reach every connected client that is currently viewing that workspace.

When a service needs to notify clients — say, a new message arrived from an agent — it calls the Broadcaster interface. The broadcaster emits the event to the workspace room, and every connected client in that room receives it.

Multi-Pod Fan-Out with Redis

In production, you run multiple orchestrator pods behind a load balancer. Client 1 might be connected to Pod A, while Client 2 is connected to Pod B. Without coordination, an event emitted on Pod A would only reach Client 1.

Redis pub/sub solves this. When Pod A emits an event, the Redis adapter publishes it to a Redis channel. Pod B subscribes to the same channel and re-emits the event to its local clients. The result: every connected client receives every event, regardless of which pod they are connected to.

Graceful Fallback

If Redis is not configured, the orchestrator falls back to a local-only mode that silently discards broadcast events. The system continues to work -- clients just will not receive real-time updates and will need to poll for new data.

Event Types

EventPayloadWhen It Fires
message.newFull message objectA new message is created (user or agent)
message.updatedFull message objectA message's content or status changes
agent.typing{conversationId, agentId, isTyping}An agent starts or stops processing
agent.status{agentId, status}An agent goes online, busy, or offline

These four events cover the full lifecycle of a conversation turn. The mobile app uses agent.typing and agent.status to show typing indicators, and message.new to append messages to the chat in real time.

What's Next

Now that you understand how events flow back to clients, see the UserSwarm Lifecycle to learn how agent runtimes are provisioned and managed.