LARAVEL

Laravel WebSockets & Real-Time Chat

April 20, 2024 20 min read

Introduction

Laravel broadcasting enables real-time features using WebSockets. This guide covers implementing real-time applications, chat systems, and live updates in Laravel.

Broadcasting Setup

Installation

composer require pusher/pusher-php-server

# Configure .env
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=us2

BROADCAST_DRIVER=pusher

Configuration

// config/broadcasting.php
return [
    'default' => env('BROADCAST_DRIVER', 'pusher'),
    
    'connections' => [
        '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,
            ],
        ],
    ],
];

Broadcasting Events

Create Event

php artisan make:event OrderStatusUpdated

// app/Events/OrderStatusUpdated.php
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class OrderStatusUpdated implements ShouldBroadcast
{
    use InteractsWithSockets;

    public $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    public function broadcastOn(): array
    {
        return [
            new Channel('orders'),
        ];
    }

    public function broadcastWith(): array
    {
        return [
            'order_id' => $this->order->id,
            'status' => $this->order->status,
        ];
    }
}

Channels

Public Channels

// Public channel
Route::get('/chat', function () {
    return view('chat');
});

// Broadcast on public channel
public function broadcastOn(): array
{
    return [new Channel('public-chat')];
}

Private Channels

// Authorization
Broadcast::channel('orders.{orderId}', function ($user, $orderId) {
    return $user->id === $order->user_id;
});

// Private channel
public function broadcastOn(): array
{
    return [new PrivateChannel('orders.'.$this->order->id)];
}

Presence Channels

// Presence channel
Broadcast::channel('chat.{roomId}', function ($user, $roomId) {
    if ($user->canJoinRoom($roomId)) {
        return ['id' => $user->id, 'name' => $user->name];
    }
});

public function broadcastOn(): array
{
    return [new PresenceChannel('chat.'.$this->roomId)];
}

Real-Time Chat

Frontend Setup

// Install Echo
npm install laravel-echo pusher-js

// resources/js/bootstrap.js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    cluster: 'us2',
    forceTLS: true
});

Listen for Events

// Listen to public channel
Echo.channel('public-chat')
    .listen('MessageSent', (e) => {
        console.log(e.message);
    });

// Listen to private channel
Echo.private('orders.' + orderId)
    .listen('OrderStatusUpdated', (e) => {
        console.log('Order status:', e.status);
    });

// Presence channel
Echo.join('chat.1')
    .here((users) => {
        console.log('Online users:', users);
    })
    .joining((user) => {
        console.log(user.name + ' joined');
    })
    .leaving((user) => {
        console.log(user.name + ' left');
    });

Pusher Integration

Trigger Events

// Direct trigger
$pusher = new Pusher\Pusher(
    'key',
    'secret',
    'app-id'
);

$pusher->trigger('chat-room', 'message', [
    'text' => 'Hello World'
]);

Client Events

// Enable client events in Pusher dashboard
// Then in JavaScript:
Echo.channel('chat-room')
    .whisper('typing', {
        user: 'John'
    });

Summary

Laravel broadcasting provides powerful real-time capabilities. Using Pusher or other drivers, you can build interactive applications with real-time updates and chat functionality.

For more Laravel tutorials, check out Laravel Queues and Laravel API Authentication.