WebSockets & Real-Time Apps

Real-Time with Laravel (Pusher & Broadcasting)

18 min Lesson 31 of 35

Real-Time with Laravel (Pusher & Broadcasting)

Laravel provides a powerful broadcasting system that makes it easy to build real-time applications. In this lesson, we'll explore how to use Laravel's broadcasting features with Pusher and Laravel Echo.

Understanding Laravel Broadcasting

Laravel's broadcasting system allows you to broadcast server-side events to client-side JavaScript applications using WebSockets.

Note: Laravel Broadcasting abstracts away the complexity of WebSocket implementations, allowing you to focus on your application logic.

Setting Up Pusher

First, install the Pusher PHP SDK:

composer require pusher/pusher-php-server

Configure your broadcasting driver in .env:

BROADCAST_DRIVER=pusher PUSHER_APP_ID=your-app-id PUSHER_APP_KEY=your-app-key PUSHER_APP_SECRET=your-app-secret PUSHER_APP_CLUSTER=mt1

Update config/broadcasting.php to ensure Pusher is configured:

'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'useTLS' => true, ], ],

Creating Broadcast Events

Generate a new broadcast event:

php artisan make:event MessageSent

Implement the event class:

<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class MessageSent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $message; public $user; public function __construct($message, $user) { $this->message = $message; $this->user = $user; } public function broadcastOn() { return new Channel('chat'); } public function broadcastAs() { return 'message.sent'; } public function broadcastWith() { return [ 'message' => $this->message, 'user' => $this->user->name, 'timestamp' => now()->toDateTimeString(), ]; } }
Tip: Use broadcastAs() to customize the event name that clients listen for, and broadcastWith() to control what data is sent.

Broadcasting Events

Dispatch the event from your controller:

use App\Events\MessageSent; public function sendMessage(Request $request) { $message = $request->input('message'); $user = auth()->user(); // Save message to database $chat = Chat::create([ 'user_id' => $user->id, 'message' => $message, ]); // Broadcast the event broadcast(new MessageSent($message, $user)); return response()->json(['success' => true]); }

Private Channels

For user-specific broadcasts, use private channels:

public function broadcastOn() { return new PrivateChannel('user.' . $this->user->id); }

Define authorization logic in routes/channels.php:

Broadcast::channel('user.{userId}', function ($user, $userId) { return (int) $user->id === (int) $userId; });

Presence Channels

Presence channels are perfect for showing who's online:

use Illuminate\Broadcasting\PresenceChannel; public function broadcastOn() { return new PresenceChannel('chat.room'); }

Authorize presence channels:

Broadcast::channel('chat.room', function ($user) { return [ 'id' => $user->id, 'name' => $user->name, 'avatar' => $user->avatar_url, ]; });

Setting Up Laravel Echo

Install Laravel Echo and Pusher JS on the frontend:

npm install --save laravel-echo pusher-js

Configure Echo in resources/js/bootstrap.js:

import Echo from 'laravel-echo'; import Pusher from 'pusher-js'; window.Pusher = Pusher; window.Echo = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, cluster: process.env.MIX_PUSHER_APP_CLUSTER, forceTLS: true });

Listening to Events with Echo

Listen for public channel events:

Echo.channel('chat') .listen('.message.sent', (e) => { console.log('New message:', e.message); console.log('From:', e.user); // Update UI with new message appendMessage(e.user, e.message, e.timestamp); });

Listen to private channels:

Echo.private('user.' + userId) .listen('NotificationSent', (e) => { showNotification(e.title, e.message); });
Warning: Private channels require authentication. Make sure your user is logged in and the /broadcasting/auth route is accessible.

Working with Presence Channels

Join a presence channel and track users:

Echo.join('chat.room') .here((users) => { console.log('Currently online:', users); updateOnlineUsersList(users); }) .joining((user) => { console.log(user.name + ' joined'); addUserToList(user); }) .leaving((user) => { console.log(user.name + ' left'); removeUserFromList(user); }) .listen('.message.sent', (e) => { appendMessage(e.user, e.message, e.timestamp); });

Client Events

Send client-to-client events (only on presence/private channels):

// Send typing indicator Echo.join('chat.room') .whisper('typing', { name: currentUser.name }); // Listen for typing indicators Echo.join('chat.room') .listenForWhisper('typing', (e) => { showTypingIndicator(e.name); });
Tip: Client events (whispers) don't hit your server, making them perfect for ephemeral states like typing indicators or cursor positions.

Broadcasting Notifications

Laravel notifications can be broadcast automatically:

<?php namespace App\Notifications; use Illuminate\Notifications\Notification; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class NewFollower extends Notification implements ShouldBroadcast { public function via($notifiable) { return ['broadcast', 'database']; } public function toBroadcast($notifiable) { return [ 'follower_name' => $this->follower->name, 'follower_avatar' => $this->follower->avatar_url, ]; } }

Listen for notifications:

Echo.private('App.Models.User.' + userId) .notification((notification) => { console.log('Notification received:', notification); showToast(notification.follower_name + ' followed you!'); });

Queue Broadcasts for Better Performance

Use ShouldBroadcastNow for immediate broadcasts or queue them:

// Immediate broadcast class MessageSent implements ShouldBroadcastNow { // ... } // Queued broadcast (better for high traffic) class MessageSent implements ShouldBroadcast { // ... }
Exercise: Create a Laravel application with real-time notifications. When a user creates a new post, broadcast a notification to all followers. Use presence channels to show which followers are currently online. Implement a "typing" indicator for comments using client events.