This version is in beta. Some features may change before release.

Realtime

Push live data to one user or a room over SSE/WebSocket - model subscriptions, presence, room gating, and a Redis backplane. Full guides live in the Realtime section.

Realtime

umbral-realtime pushes data to one user or a named room without hand-rolling connection bookkeeping. It ships two transports - Server-Sent Events (push-only) and WebSocket (bidirectional) - over one connection registry, plus a GroupPolicy auth seam, live model-change fan-out, presence, and a Redis backplane for horizontal scale.

Code
rust
use umbral_realtime::Realtime;
 
// Fire-and-forget; no-ops when RealtimePlugin isn't installed.
Realtime::to_user("42").send("notification", &payload).await; // the user's PK as a string
Realtime::to_group("public:lobby").send("message", &msg).await;
Code
js
// One <script src="/realtime/client.js">, then - one shared connection across every tab:
umbral.realtime.subscribe("public:lobby", { message: (m) => render(m) });
Info

This is the plugin overview. The full guides - setup, room gating, model subscriptions, presence, transports, and scaling - live in the dedicated Realtime section.

The guides

At a glance

  • Two transports - SSE (push-only, auto-reconnect) and WebSocket (bidirectional): GET /realtime/sse, GET /realtime/ws (remount all four routes under any base with RealtimePlugin::new().at("/rt")).
  • Safe by default - anonymous connections may join only public:* rooms; model exposure and presence are opt-in, exposed model fields are whitelisted, and a built-in Origin guard rejects cross-origin WebSocket upgrades (CSWSH) in prod with no config. See Gating rooms and Transports.
  • One connection per browser - a SharedWorker shares a single SSE stream across all tabs and subscriptions, so opening many tabs never exhausts the browser's HTTP/1.1 connection limit.
  • Fire-and-forget sends - Realtime::to_user / to_group / broadcast publish without blocking on socket I/O and no-op when the plugin isn't installed, so a handler can call them unconditionally (Realtime::is_installed() if you need to check).

See also

  • The full Realtime section for setup, gating, model subscriptions, presence, transports, and scaling.
  • The Plugin trait - how RealtimePlugin (and every plugin) plugs in.
realtimessewebsocketpushpresenceredis