<?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.
Related snips
<?php
namespace App\Providers;
use App\Contracts\PaymentGateway;
use App\Services\StripePaymentGateway;
Laravel service container and dependency injection
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
Laravel mix/Vite for asset compilation
class Comment < ApplicationRecord
belongs_to :article
belongs_to :author, class_name: "User"
validates :body, presence: true, length: { maximum: 2_000 }
Live comments with model broadcasts + turbo_stream_from
<%# private stream: turbo signs the serialized record name %>
<%= turbo_stream_from current_user %>
<section class="notifications">
<h1>Notifications</h1>
Turbo Streams + authorization: signed per-user stream name
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Laravel database migrations for schema management
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
# Subscribe to a specific room
room = Room.find(params[:room_id])
ActionCable for real-time WebSocket communication
Share this code
Here's the card — post it anywhere.