Was ist Broadcasting?
Mit WebSockets können Daten in Echtzeit vom Server zum Client gesendet werden.
Das Broadcasting von Laravel ist ein Mechanismus, der serverseitige Events per WebSocket an das JavaScript im Frontend ausliefert.
Wenn sich zum Beispiel der Status einer Bestellung ändert, kann die Änderung im Browser sofort dargestellt werden, ohne dass die Seite neu geladen werden muss.
Die Stärke von Laravels Broadcasting liegt darin, dass Sie den Event-Namen und die Daten der Serverseite unverändert mit der Clientseite teilen können.
Broadcasting baut auf dem Event-System von Laravel auf.
Wir empfehlen, zunächst die Grundlagen zu Events und Listenern zu verstehen.
Einrichtung
In neuen Laravel-Anwendungen ist Broadcasting standardmäßig deaktiviert.
Aktivieren Sie es mit dem Artisan-Befehl install:broadcasting.
php artisan install:broadcasting
Dieser Befehl fragt Sie nach dem gewünschten Broadcast-Dienst.
Zudem werden config/broadcasting.php und routes/channels.php erzeugt.
Laravel Reverb
Ab Laravel 11 wird der offizielle WebSocket-Server Laravel Reverb empfohlen.
Reverb ist selbst gehostet und ermöglicht Echtzeitkommunikation, ohne dass zusätzliche externe Dienste erforderlich sind.
Installation
Wird der Befehl install:broadcasting mit der Option --reverb aufgerufen, werden die notwendigen Composer- und NPM-Pakete für Reverb installiert und die .env in einem Schritt konfiguriert.
php artisan install:broadcasting --reverb
Für eine manuelle Installation fügen Sie das Paket zunächst über Composer hinzu und führen dann den Installationsbefehl aus.
composer require laravel/reverb
php artisan reverb:install
Wichtige Einstellungen in der .env
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
Reverb-Server starten
In der Produktion verwalten Sie den Server als Daemon über einen Prozessmanager wie Supervisor.
Broadcast-Events werden über die Queue verarbeitet.
Sie müssen daher zusätzlich zum Reverb-Server auch einen Queue-Worker starten.
Broadcast-Event erstellen
Event-Klasse erzeugen
php artisan make:event OrderShipmentStatusUpdated
Lassen Sie die erzeugte Event-Klasse das Interface ShouldBroadcast implementieren.
<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class OrderShipmentStatusUpdated implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public function __construct(
public Order $order,
) {}
/**
* Liefert die Channels zurück, über die das Event broadcastet werden soll.
*/
public function broadcastOn(): Channel
{
return new PrivateChannel('orders.' . $this->order->id);
}
}
Durch die Implementierung von ShouldBroadcast wird das Event beim Auslösen automatisch über die Queue broadcastet.
Broadcast-Daten anpassen
Standardmäßig werden alle public-Eigenschaften der Event-Klasse in den Broadcast-Payload aufgenommen.
Definieren Sie die Methode broadcastWith, um die gesendeten Daten einzuschränken.
public function broadcastWith(): array
{
return [
'order_id' => $this->order->id,
'status' => $this->order->status,
];
}
Broadcast-Namen anpassen
Standardmäßig ist der Klassenname zugleich der Event-Name.
Mit broadcastAs können Sie einen eigenen Namen festlegen.
public function broadcastAs(): string
{
return 'order.status.updated';
}
Wenn Sie im Frontend darauf hören, setzen Sie einen führenden ., um das Namespace-Präfix der Anwendung zu unterdrücken.
Echo.private(`orders.${orderId}`)
.listen('.order.status.updated', (e) => {
console.log(e);
});
Channel-Typen
| Channel | Klasse | Beschreibung |
|---|
| Public | Channel | Keine Authentifizierung erforderlich; jeder kann abonnieren |
| Private | PrivateChannel | Nur authentifizierte Benutzer; Autorisierungslogik notwendig |
| Presence | PresenceChannel | Erweiterung von Private; Liste der Teilnehmer im Channel abrufbar |
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
// Public-Channel
public function broadcastOn(): Channel
{
return new Channel('posts');
}
// Private-Channel
public function broadcastOn(): Channel
{
return new PrivateChannel('orders.' . $this->order->id);
}
// Presence-Channel
public function broadcastOn(): Channel
{
return new PresenceChannel('rooms.' . $this->room->id);
}
Um auf mehreren Channels zu broadcasten, geben Sie ein Array zurück.
public function broadcastOn(): array
{
return [
new PrivateChannel('orders.' . $this->order->id),
new Channel('admin.orders'),
];
}
Channel-Autorisierung
Für Private- und Presence-Channels findet vor dem Abonnieren eine serverseitige Autorisierungsprüfung statt.
routes/channels.php
Definieren Sie den Autorisierungs-Callback in der Datei routes/channels.php, die vom Befehl install:broadcasting erzeugt wird.
use App\Models\Order;
use App\Models\User;
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('orders.{orderId}', function (User $user, int $orderId) {
return $user->id === Order::findOrNew($orderId)->user_id;
});
Der erste Parameter des Callbacks ist der authentifizierte Benutzer, die weiteren Parameter entsprechen den Platzhaltern im Channel-Namen.
Bei einer Rückgabe von true oder einem truthy-Wert ist die Autorisierung erfolgreich, false führt zur Ablehnung.
Auch Route Model Binding lässt sich verwenden.
Verwenden Sie den Channel-Namen orders.{order}, erhalten Sie eine Order-Modellinstanz.
Broadcast::channel('orders.{order}', function (User $user, Order $order) {
return $user->id === $order->user_id;
});
Autorisierung über eine Channel-Klasse
Wenn die Anzahl der Channels wächst, können Sie diese über Channel-Klassen strukturieren.
php artisan make:channel OrderChannel
<?php
namespace App\Broadcasting;
use App\Models\Order;
use App\Models\User;
class OrderChannel
{
public function join(User $user, Order $order): bool
{
return $user->id === $order->user_id;
}
}
Registrieren Sie die Klasse in routes/channels.php.
use App\Broadcasting\OrderChannel;
Broadcast::channel('orders.{order}', OrderChannel::class);
Events auslösen
Events, die ShouldBroadcast implementieren, werden wie gewöhnliche Events ausgelöst.
use App\Events\OrderShipmentStatusUpdated;
OrderShipmentStatusUpdated::dispatch($order);
Um das Event allen anderen Benutzern außer dem auslösenden zu senden, verwenden Sie toOthers.
broadcast(new OrderShipmentStatusUpdated($order))->toOthers();
Für toOthers muss die Event-Klasse das Trait InteractsWithSockets verwenden.
Empfang im Frontend
Laravel Echo einrichten
Wenn Sie Reverb verwenden, konfigurieren Sie in resources/js/bootstrap.js die Echo-Instanz.
npm install --save-dev laravel-echo pusher-js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
Auf Events hören
// Public-Channel
Echo.channel('posts')
.listen('PostPublished', (e) => {
console.log(e.post);
});
// Private-Channel
Echo.private(`orders.${orderId}`)
.listen('OrderShipmentStatusUpdated', (e) => {
console.log(e.order);
});
// Presence-Channel
Echo.join(`rooms.${roomId}`)
.here((users) => {
console.log('Aktuelle Mitglieder:', users);
})
.joining((user) => {
console.log(user.name, 'ist beigetreten');
})
.leaving((user) => {
console.log(user.name, 'hat den Channel verlassen');
})
.listen('MessagePosted', (e) => {
console.log(e.message);
});
React- und Vue-Hooks nutzen
Bei den React- und Vue-Starter-Kits stehen spezielle Hooks zur Verfügung, mit denen der Code kompakter ausfällt.
import { useEcho } from "@laravel/echo-react";
// Private-Channel
useEcho(
`orders.${orderId}`,
"OrderShipmentStatusUpdated",
(e) => {
console.log(e.order);
},
);
// Public-Channel
import { useEchoPublic } from "@laravel/echo-react";
useEchoPublic("posts", "PostPublished", (e) => {
console.log(e.post);
});
Der Hook useEcho verlässt den Channel beim Unmounten der Komponente automatisch.
Stellen Sie vor dem Build der Frontend-Assets sicher, dass die Variablen VITE_REVERB_* in Ihrer .env korrekt gesetzt sind.
Praxisbeispiel: Bestellstatus in Echtzeit aktualisieren
Broadcasting aktivieren
php artisan install:broadcasting --reverb
Starten Sie den Reverb-Server und einen Queue-Worker.php artisan reverb:start
php artisan queue:work
Event-Klasse erstellen
php artisan make:event OrderShipmentStatusUpdated
Bearbeiten Sie app/Events/OrderShipmentStatusUpdated.php.<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class OrderShipmentStatusUpdated implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public function __construct(
public Order $order,
) {}
public function broadcastOn(): Channel
{
return new PrivateChannel('orders.' . $this->order->id);
}
public function broadcastWith(): array
{
return [
'order_id' => $this->order->id,
'status' => $this->order->status,
];
}
}
Channel-Autorisierung definieren
Ergänzen Sie in routes/channels.php die Autorisierungslogik.use App\Models\Order;
use App\Models\User;
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('orders.{order}', function (User $user, Order $order) {
return $user->id === $order->user_id;
});
Event auslösen
Lösen Sie das Event in einem Controller oder Job aus, der den Bestellstatus aktualisiert.use App\Events\OrderShipmentStatusUpdated;
$order->update(['status' => 'shipped']);
OrderShipmentStatusUpdated::dispatch($order);
Im Frontend darauf hören
Empfangen Sie das Event über ein Inline-Script in einem Blade-Template oder in einer React-/Vue-Komponente.Echo.private(`orders.${orderId}`)
.listen('OrderShipmentStatusUpdated', (e) => {
document.getElementById('status').textContent = e.status;
});
Nächste Schritte
Laravel Reverb
Erfahren Sie mehr über die Einrichtung des Reverb-Servers, den Betrieb in der Produktion und Skalierung.
Queues und Jobs
Broadcasting wird über die Queue verarbeitet. Erfahren Sie, wie Sie Queues konfigurieren und betreiben.
Events und Listener
Vertiefen Sie sich in das Event-System von Laravel, das die Grundlage für Broadcasting bildet.
Zuletzt geändert am 13. Juli 2026