<?php
namespace App\Events;
use App\Models\Message;
use App\Models\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
public Message $message
) {}
public function broadcastOn(): array
{
return [
new PrivateChannel('chat.' . $this->message->chat_id),
];
}
public function broadcastWith(): array
{
return [
'id' => $this->message->id,
'body' => $this->message->body,
'user' => [
'id' => $this->message->user->id,
'name' => $this->message->user->name,
],
'created_at' => $this->message->created_at,
];
}
public function broadcastAs(): string
{
return 'message.sent';
}
}
<?php
use Illuminate\Support\Facades\Broadcast;
// Private channel authorization
Broadcast::channel('chat.{chatId}', function ($user, $chatId) {
return $user->chats()->where('id', $chatId)->exists();
});
// Presence channel - returns user data
Broadcast::channel('online', function ($user) {
return [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar_url,
];
});
// Model binding
Broadcast::channel('post.{post}', function ($user, \App\Models\Post $post) {
return $user->can('view', $post);
});
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true,
authEndpoint: '/broadcasting/auth',
auth: {
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
},
});
// Subscribe to private channel
Echo.private('chat.1')
.listen('.message.sent', (e) => {
console.log('Message received:', e.message);
});
// Presence channel
Echo.join('online')
.here((users) => {
console.log('Online users:', users);
})
.joining((user) => {
console.log(user.name + ' joined');
})
.leaving((user) => {
console.log(user.name + ' left');
});
Broadcasting enables real-time features by pushing server events to connected clients via WebSockets. I implement ShouldBroadcast on events to automatically broadcast them when fired. The broadcastOn() method defines channels—public, private, or presence. Private channels require authentication via channels.php routes. Laravel integrates with Pusher, Ably, or Laravel Echo Server. Frontend clients subscribe with Laravel Echo—Echo.channel().listen(). The broadcast() helper manually broadcasts to specific channels. Broadcasting model events keeps dashboards live—new comments appear instantly. Presence channels track online users. This real-time layer transforms static applications into collaborative, responsive experiences without polling.