Realtime event transport
Use a Realtime channel when backend producers need to send live events to a browser dashboard, admin console, or operations view. The route receives events, normalizes the payload, and broadcasts it through a named channel.
Configure the app
Section titled “Configure the app”import { backend } from "@layeron/core"import { realtime } from "@layeron/modules"
const app = backend()const live = realtime({ name: "transport", historyLimit: 500,})app.use(live)Relay an event
Section titled “Relay an event”app.post("/feeds/:feedId/events", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const feedId = pathSegments[2] const body = await request.json() const channel = live.channel(`feed_${feedId}`)
return await channel.broadcast({ type: body.type, data: { feedId: feedId, eventId: body.eventId, payload: body.payload, receivedAt: new Date().toISOString(), }, metadata: { source: body.source ?? "api", }, idempotencyKey: body.eventId, })})Use an idempotencyKey when the producer may retry the same event. Realtime
keeps the event stream stable while still allowing safe producer retries.
Read events after reconnect
Section titled “Read events after reconnect”app.get("/feeds/:feedId/events", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const feedId = pathSegments[2] return await live.channel(`feed_${feedId}`).history({ limit: Number(new URL(request.url).searchParams.get("limit") ?? 100), cursor: new URL(request.url).searchParams.get("cursor") ?? undefined, })})The dashboard can call this route after reconnecting and continue from the cursor returned by the previous page.
Send control messages
Section titled “Send control messages”Use a second event type for commands that should travel over the same live stream:
app.post("/feeds/:feedId/control", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const feedId = pathSegments[2] const body = await request.json()
return await live.channel(`feed_${feedId}`).publish({ type: "feed.control", data: { action: body.action, target: body.target, requestedAt: new Date().toISOString(), }, idempotencyKey: body.commandId, })})Use channels for fan-out event transport. Use rooms when the same stream also needs membership, presence, room metadata, or collaborative state.