Skip to main content

Realtime

Three optional features push changes to clients. All of them ride the runtime's StreamBus (NATS, Redis, or Postgres LISTEN/NOTIFY), so an update made on one replica reaches clients connected to any other.

cargo add riverbase_http --git https://github.com/riverbase-io/riverbase --features websocket,sse,rxdb

WebSocket bridge (websocket)​

RtcBridge connects browser clients to bus channels for bidirectional messages:

use std::sync::Arc;
use riverbase_http::websocket::{RtcBridge, StreamRtcTransport};

let bus = runtime.stream_bus.clone();
let rtc = RtcBridge::new("default", "/rtc", bus.clone())
.with_transport(Arc::new(StreamRtcTransport::new(bus)))
.register_builtins()?
.into_router();

The bridge serves:

PathPurpose
{prefix}/{name}~websocket/{*channel}The WebSocket endpoint for a channel
{prefix}/{name}~ssestream/{*channel}The same channel as server-sent events
{prefix}/{name}.meta, {prefix}/{name}.infoBridge metadata

Channel access is authorized per principal (authorize_channel, default_channel_permissions). Messages are framed with a WireCodec: JSON by default (rtc_wire_encoding), or CBOR when the client negotiates it through Sec-WebSocket-Protocol. Custom message types register on a MessageRegistry.

Server-sent events (sse)​

bus_sse_stream turns any StreamBus subscription into an SSE response. Use it in a custom route for one-way feeds such as progress or notifications.

RxDB replication (rxdb)​

RxDB clients keep a local database in sync with a resource. Implement RxdbCollection for each collection:

MethodRole
collection_name()The collection's public name
resource_name()The resource it maps to
policy_required()Whether scope authorization applies
pull(ctx, checkpoint, limit, scope)Return up to limit documents changed since checkpoint, plus the next checkpoint
push(ctx, rows, scope)Apply client writes, usually by dispatching commands

Then register and mount:

use riverbase_http::rxdb::RxdbRegistry;

let rxdb = RxdbRegistry::new()
.with_stream_bus(runtime.stream_bus.clone())
.register(Arc::new(TodoRxdbCollection::new(dbpool)))?
.into_router();
app.merge(rxdb); // pull/push appear in OpenAPI

Routes live under /rxdb within api_base. To tell clients to re-pull after a change, publish on rxdb_notify_channel(collection), for example from a custom DomainCommandEngine::execute after each successful command (see Commands).

Choosing one​

NeedUse
Offline-first UI with a local databaseRxDB
One-way live feedSSE
Bidirectional messages, presence, custom protocolsWebSocket bridge