Laravel Reverb is the official first-party WebSocket server, released with Laravel 11. It replaces Pusher, runs on your infrastructure, and handles 10,000+ concurrent connections.
Installation
composer require laravel/reverb
php artisan reverb:install
php artisan reverb:start --port=8080Broadcasting Events
class MessageSent implements ShouldBroadcast
{
public function __construct(
public User $user,
public Message $message,
) {}
public function broadcastOn(): array
{
return [new PrivateChannel("chat.{$this->message->room_id}")];
}
public function broadcastWith(): array
{
return [
'user' => ['id' => $this->user->id, 'name' => $this->user->name],
'message' => [
'id' => $this->message->id,
'body' => $this->message->body,
'sent_at' => $this->message->created_at->toISOString(),
],
];
}
}
MessageSent::dispatch($user, $message);Frontend Listening (Laravel Echo)
Echo.private(`chat.${roomId}`)
.listen('MessageSent', (event) => {
messages.push(event.message);
});
// Presence channel — who's online
Echo.join(`room.${roomId}`)
.here((users) => { onlineUsers = users; })
.joining((user) => { onlineUsers.push(user); })
.leaving((user) => {
onlineUsers = onlineUsers.filter(u => u.id !== user.id);
});Channel Authorization
Broadcast::channel('chat.{roomId}', function (User $user, int $roomId) {
return $user->rooms()->where('id', $roomId)->exists();
});Real-Time Notifications
class OrderShipped extends Notification implements ShouldBroadcast
{
public function via($notifiable): array
{
return ['database', 'broadcast'];
}
public function toBroadcast($notifiable): BroadcastMessage
{
return new BroadcastMessage([
'title' => 'Order Shipped!',
'body' => "Order #{$this->order->id} has been shipped.",
]);
}
}Reverb gives you Pusher-like functionality for free, on your own server, with zero external dependencies.