Hướng Dẫn Laravel Broadcasting

🔰 Giới thiệu chung

Laravel Broadcasting là hệ thống giúp bạn gửi dữ liệu real-time từ backend đến frontend một cách tự động, thường dùng trong các ứng dụng như:

Broadcasting kết hợp giữa sự kiện Laravel và WebSockets hoặc dịch vụ push để truyền dữ liệu.

📜 Ngày xưa trước khi có Broadcasting

Trước khi Broadcasting phổ biến, các hệ thống realtime thường phải:

Laravel Broadcasting giúp mọi thứ trở nên đơn giản, tích hợp luôn với hệ thống Event của Laravel.

🔁 So sánh với các phương pháp khác

Phương pháp Đặc điểm Nhược điểm
AJAX Polling Gọi API liên tục để kiểm tra tin nhắn mới Tốn băng thông, tăng tải server, độ trễ cao
Long Polling Giữ kết nối mở và phản hồi khi có dữ liệu mới Trễ thấp hơn polling nhưng khó scale, tiêu tốn tài nguyên
Viết tay bằng Socket.IO Dùng Node.js để tạo WebSocket server riêng Mạnh mẽ nhưng cần hệ thống riêng, khó tích hợp với Laravel
Laravel Broadcasting Tích hợp sẵn với Laravel, sử dụng WebSocket driver như Soketi Tối ưu cho Laravel, dễ triển khai, nhưng cần queue và WebSocket server

⚙️ Luồng hoạt động của Laravel Broadcasting

  1. Client đăng ký kênh thông qua Laravel Echo (WebSocket).
  2. Server phát sinh event (ví dụ: gửi tin nhắn).
  3. Laravel sử dụng driver Broadcasting (Pusher, Soketi...) để đẩy sự kiện real-time.
  4. Client nhận dữ liệu ngay lập tức qua WebSocket, không cần hỏi lại server.

📊 Bảng So Sánh Các Dịch Vụ Broadcasting

Dịch Vụ Cài Đặt Chi Phí Đặc Điểm Dự Án Phù Hợp
Pusher Dễ cài đặt qua Composer và NPM, hỗ trợ Laravel Echo. Miễn phí với giới hạn, có các gói trả phí theo mức độ sử dụng. Dịch vụ bên thứ ba, dễ tích hợp, nhưng có giới hạn miễn phí và yêu cầu kết nối internet. Dự án nhỏ và vừa, ứng dụng cần nhanh chóng triển khai mà không cần quản lý hạ tầng.
Laravel WebSockets Cài đặt qua Composer, cần cấu hình server riêng. Miễn phí, nhưng cần tự host và bảo trì server. Self-hosted, không phụ thuộc vào dịch vụ bên ngoài, nhưng yêu cầu tài nguyên hệ thống để duy trì. Dự án trung bình và lớn, nơi mà bạn muốn kiểm soát hoàn toàn hạ tầng và cần tính linh hoạt.
Soketi Cài đặt qua Docker, sử dụng cấu hình giống Pusher. Miễn phí, cần host riêng. Nhẹ, nhanh, dễ dàng triển khai và sử dụng ít tài nguyên hơn, tương thích với Pusher API. Dự án lớn, cần hiệu suất cao và khả năng mở rộng, yêu cầu ít tài nguyên hơn.
Ably Cài đặt PHP SDK qua Composer, sử dụng Laravel Echo. Có gói miễn phí giới hạn, gói trả phí theo nhu cầu sử dụng. Dịch vụ đám mây, cung cấp tốc độ cao và hỗ trợ nhiều khu vực, dễ dàng mở rộng. Dự án nhỏ đến lớn, đặc biệt là ứng dụng di động hoặc toàn cầu cần hỗ trợ nhiều khu vực.
Redis Cài đặt Redis server, cấu hình với Laravel Echo. Miễn phí, nhưng cần tự host Redis server. Phù hợp với các dự án có yêu cầu tùy chỉnh cao, cần cấu hình Redis và các công cụ khác như Socket.IO. Dự án lớn, yêu cầu tính tùy chỉnh cao và không phụ thuộc vào dịch vụ đám mây bên ngoài.

🚀 1. Pusher – Dịch vụ bên thứ ba

Pusher là một dịch vụ bên thứ ba giúp bạn dễ dàng gửi dữ liệu real-time đến frontend qua WebSockets. Tuy nhiên, nó có giới hạn miễn phí và yêu cầu có kết nối internet.

Cài đặt:

Cài đặt Pusher PHP Server:

composer require pusher/pusher-php-server

Cấu hình .env:

Trong tệp .env, cấu hình các thông tin liên quan đến Pusher:


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
    

Cài đặt cấu hình trong config/broadcasting.php:

Laravel sẽ tự động đọc thông tin từ .env để cấu hình Pusher. Bạn có thể tìm và chỉnh sửa phần sau trong tệp config/broadcasting.php:


'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,
        ],
    ],
],
    

Tạo Event và Broadcast:

Tạo một Event và broadcast nó:

php artisan make:event MessageSent

Trong MessageSent, bạn sẽ thực hiện việc broadcast như sau:


public function broadcastOn()
{
    return new Channel('chat');
}
    

🧩 2. Laravel WebSockets – Tự host như Pusher

Laravel WebSockets là một gói tự host WebSocket như Pusher, cho phép bạn sử dụng WebSockets mà không cần phải dựa vào dịch vụ bên ngoài.

Cài đặt:

Cài đặt Laravel WebSockets:

composer require beyondcode/laravel-websockets

Publish cấu hình và migration:

php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan migrate

Publish cấu hình WebSockets:

php artisan vendor:publish --tag="websockets-config"

Cấu hình WebSockets trong config/websockets.php:

Chỉnh sửa tệp config/websockets.php để phù hợp với yêu cầu của bạn:


'apps' => [
    [
        'id' => env('APP_ID'),
        'name' => env('APP_NAME'),
        'key' => env('APP_KEY'),
        'secret' => env('APP_SECRET'),
        'path' => env('APP_PATH'),
    ],
],
    

Chạy WebSockets Server:

Khởi chạy WebSockets server với lệnh:

php artisan websockets:serve

⚡ 3. Soketi – Tự host, nhẹ, siêu nhanh

Soketi là một WebSocket server nhẹ, cực kỳ nhanh và tương thích với API của Pusher. Nó được thiết kế để sử dụng ít tài nguyên hơn và dễ dàng triển khai.

Cài đặt:

Tạo Docker container cho Soketi:


soketi:
  image: 'quay.io/soketi/soketi:1.5-16-debian'
  ports:
    - "6001:6001"
  environment:
    SOKETI_DEBUG: '1'
    SOKETI_METRICS_ENABLED: '1'
    SOKETI_DEFAULT_APP_ID: 'local'
    SOKETI_DEFAULT_APP_KEY: 'local'
    SOKETI_DEFAULT_APP_SECRET: 'local'
    

Chạy Docker container:

docker-compose up -d

Cấu hình .env:


BROADCAST_DRIVER=pusher
PUSHER_APP_ID=local
PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_APP_CLUSTER=mt1
    

☁️ 4. Ably – Cloud Broadcaster

Ably là một dịch vụ đám mây cung cấp khả năng phát sóng dữ liệu real-time. Đây là một giải pháp đám mây mạnh mẽ với tốc độ cao và hỗ trợ nhiều khu vực.

Cài đặt:

Cài đặt Ably PHP SDK:

composer require ably/ably-php

Cấu hình .env:


BROADCAST_DRIVER=ably
ABLY_KEY=your-ably-key
    

Cấu hình trong config/broadcasting.php:


'connections' => [
    'ably' => [
        'driver' => 'ably',
        'key' => env('ABLY_KEY'),
    ],
],
    

🔁 5. Redis – Custom WebSocket Broadcaster

Redis có thể được sử dụng như một công cụ để truyền tải sự kiện qua WebSockets, kết hợp với các thư viện như Socket.IO.

Cài đặt:

Cài đặt Redis:

composer require predis/predis

Cấu hình .env:


BROADCAST_DRIVER=redis
    

Cấu hình Redis trong config/database.php:

Kiểm tra lại phần cấu hình Redis trong tệp này để đảm bảo rằng Redis được cài đặt đúng.

Chạy Redis Server:

Đảm bảo Redis đang chạy trên hệ thống của bạn.

🧰 Chuẩn bị phía Frontend

Để sử dụng broadcasting với Laravel Echo ở phía frontend, bạn cần cài đặt các gói sau:

Cài đặt Laravel Echo và Pusher JS:

npm install --save laravel-echo pusher-js

Khởi tạo trong JavaScript:

Trong tệp JS chính, ví dụ resources/js/app.js:


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,
});

Sau đó bạn có thể lắng nghe các sự kiện như sau:


Echo.channel('chat')
    .listen('MessageSent', (e) => {
        console.log(e.message);
    });

🔔 Lưu Ý Khi Sử Dụng Queue Trong Broadcasting

Trong Laravel Broadcasting, nếu bạn sử dụng queue để xử lý các sự kiện, bạn cần chắc chắn rằng các queue worker đang chạy để xử lý các job (sự kiện) và gửi dữ liệu qua WebSockets. Nếu bạn không chạy queue worker, các sự kiện broadcasting có thể không được xử lý và phát đi.

Các trường hợp cần chạy queue:work:

Cách chạy queue worker:

Để chạy queue worker, sử dụng lệnh sau trong terminal:

php artisan queue:work

Lệnh này sẽ bắt đầu xử lý các job trong queue, bao gồm cả các sự kiện broadcasting.

Đảm bảo rằng queue worker của bạn đang chạy liên tục (hoặc sử dụng queue:listen nếu cần), để các sự kiện được gửi đi ngay khi có sự thay đổi.

💬 Các Loại Chat Trong Laravel Broadcasting

Laravel hỗ trợ nhiều loại kênh cho việc chat realtime, bao gồm:

1. Public Channel

Kênh công khai, mọi người đều có thể tham gia mà không cần xác thực. Đây là lựa chọn phù hợp khi bạn muốn gửi thông tin cho tất cả người dùng.

broadcast(new MessageSent($message));

Ví dụ: Gửi một thông điệp lên kênh công khai:


public function broadcastOn()
{
    return new Channel('chat');
}

2. Private Channel

Kênh riêng tư, chỉ những người đã được xác thực mới có thể tham gia. Đây là lựa chọn phù hợp khi bạn muốn gửi thông tin cho một nhóm người dùng cụ thể, ví dụ như chat giữa các người dùng đã đăng nhập.

broadcast(new MessageSent($message))->to('private-chat.'.$userId);

Ví dụ: Gửi một thông điệp lên kênh riêng tư cho một người dùng:


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

3. Presence Channel

Kênh cho phép theo dõi người dùng online và offline. Thông qua Presence Channel, bạn có thể theo dõi được trạng thái của người dùng, xem ai đang online hoặc offline. Đây là lựa chọn tuyệt vời cho các ứng dụng yêu cầu hiển thị trạng thái người dùng trong thời gian thực.

broadcast(new MessageSent($message))->toPresence('presence-chat');

Ví dụ: Gửi thông điệp lên kênh Presence và kiểm tra ai đang online:


public function broadcastOn()
{
    return new PresenceChannel('presence-chat');
}

Để theo dõi người dùng online và offline, bạn cần sử dụng các sự kiện như `PresenceChannel` để lắng nghe trạng thái của người dùng:


Echo.join('presence-chat')
    .here((users) => {
        console.log(users);
    })
    .joining((user) => {
        console.log(user.name + ' đã tham gia');
    })
    .leaving((user) => {
        console.log(user.name + ' đã rời');
    });

4. Một Số Mẹo Và Lưu Ý