Reverb
A generic WebSocket pub/sub server - Larust’s port of
Laravel Reverb. For anything that
isn’t “swap this HTML fragment” - a typing indicator, appending one new
comment via your own JS rather than re-rendering a whole list, any event
your client-side code wants to react to directly. For HTML-fragment
swaps instead, see @live(...) in
Realtime & Broadcasting.
- Adding this feature
- Broadcasting an event
- Private channels
@livevs.larust-reverb- which one?- Next
Adding this feature
# At scaffold time
xr new myapp --features reverb
# Or retrofit onto an existing app
xr add reverb
Both are equivalent to adding "reverb" to larust-support’s
features = [...] list in your app’s own Cargo.toml by hand.
Broadcasting an event
larust_support::reverb::broadcast_event(
&format!("post.{}", post_id),
"CommentAdded",
&comment, // any Serialize payload
)?;
LarustReverb.channel(`post.${postId}`).listen("CommentAdded", (comment) => {
appendCommentToDom(comment);
});
An app that uses it registers the runtime script + WebSocket route once:
route.plugin(larust_support::reverb::ReverbPlugin)
Private channels
A channel name starting with private- requires authorization -
register one callback, checked at WebSocket-upgrade time (the browser
already carries the session cookie to this same-origin connection, so
there’s no separate Pusher-style /broadcasting/auth round trip to
implement):
larust_support::reverb::authorize(|session, channel| async move {
let Ok(Some(user)) = larust_support::auth::user::<User>(&session).await else {
return false;
};
channel == format!("private-orders.{}", user.id)
});
@live vs. larust-reverb - which one?
@live (larust-live::push) |
larust-reverb |
|
|---|---|---|
| Payload | Pre-rendered HTML, replaces a fixed DOM element | Arbitrary JSON, tagged with an event name |
| Client handling | Automatic (the vendored patcher) | Your own JS .listen(...) callback |
| Best for | A block that’s naturally “just render this again” | Anything needing custom client-side behavior on arrival |
| Private channels | Not yet | Yes (private-* + authorize(...)) |
They’re deliberately separate route namespaces and separate channel
registries, on purpose - pointing both at the same channel name would mix
incompatible payload shapes (raw HTML vs. a {event, data} envelope).
See Realtime & Broadcasting
for @live itself and SPA-style navigation.
Next
Back to Optional Features for the full
list, or Realtime & Broadcasting
for @live(...) and @spa.