Changes on the web, in the open windows
Freddy's colleague edits a team note in the browser. On Freddy's desktop the open list changes a moment later, without a refresh and without polling. Laravel announced the change; Elyra listened, the way Echo does in a browser.
Follow a channel
App::new().backend(
Backend::new("https://notes.example.com")
.broadcasting(Broadcasting::pusher("app-key")) // REVERB_APP_KEY
.follow("notes", "/api/notes"), // private-notes: re-run what read /api/notes
)
follow ties a Laravel channel to a resource. When an event arrives on
private-notes, every live query that read /api/notes
re-runs, coalesced, and is pushed only if the result changed, which is chapter 7's
machinery fed from the network. A resource generated with --backend
already follows its channel; follow_all(resources::follows()) wires
them all at once.
The connection
- The protocol is Pusher's, which Askr (with
--pusher), Reverb and Pusher speak. It goes to the backend's own host, and.host(),.port()and.scheme()point it at a Reverb on its own port. It iswssonly, except to loopback. - It opens once the user is signed in and closes on sign-out. A dropped connection reconnects, backing off from one second up to thirty, and then re-runs everything followed, because events sent in the meantime are lost.
- Private channels are authorized by the backend, as the
signed-in user, at
/api/broadcasting/auth. The app secret stays on the server. - Laravel's
->toOthers()works: while connected,BackendsendsX-Socket-ID, so Laravel can skip the app whose own write already re-ran its queries.
What each event does
- It re-runs the live queries that read the followed resource.
- It is a domain event,
BackendEvent { channel, event, data }, so chapter 4'sApp::listencan log it or raise a notification. - It reaches the windows:
import { onBackendEvent, broadcasting } from "@elyra/runtime";
onBackendEvent("notes", "NoteUpdated", (data) => toast(`${data.model.title} was updated`));
// $broadcasting.state: "connecting" | "connected" | "offline"
Freddy shows a small dot in the corner from $broadcasting.state. One
caution from the guide: the data is the server's, untrusted like any input.
Re-running a query does not read it at all, only the fact that something changed.
Presence channels are not supported yet.
On the Laravel side
php artisan install:broadcasting --reverb # or Askr: askr serve --pusher
// app/Models/Note.php
class Note extends Model
{
use BroadcastsEvents;
public function broadcastOn(string $event): array
{
return [new PrivateChannel('notes')];
}
}
// routes/channels.php
Broadcast::channel('notes', fn ($user) => true);
// bootstrap/app.php: channel auth under /api, with the Sanctum token
->withBroadcasting(__DIR__.'/../routes/channels.php', [
'prefix' => 'api', 'middleware' => ['api', 'auth:sanctum'],
])
Broadcast events are queued by default, so the Laravel app needs a queue worker, or
QUEUE_CONNECTION=sync. Freddy's channel rule lets every signed-in user
listen, because the whole team shares the notes; a stricter app returns a real
check there. The guide is the broadcasting section of
A Laravel backend, and the design is
RFC 0006.
What you learned
.broadcasting(Broadcasting::pusher(key)).follow(channel, path)listens like Echo, over the protocol Askr, Reverb and Pusher speak.- The connection follows sign-in, reconnects with backoff and re-runs everything followed afterwards.
- Each event re-runs live queries, is a
BackendEventin Rust, and reaches the page throughonBackendEvent. - The event's data is untrusted, and presence channels are not supported yet.