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.
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.
| 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 |
| 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. |
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 Pusher PHP Server:
composer require pusher/pusher-php-server
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
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 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');
}
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 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"
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'),
],
],
Khởi chạy WebSockets server với lệnh:
php artisan websockets:serve
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.
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
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=local
PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_APP_CLUSTER=mt1
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 Ably PHP SDK:
composer require ably/ably-php
BROADCAST_DRIVER=ably
ABLY_KEY=your-ably-key
'connections' => [
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
],
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 Redis:
composer require predis/predis
BROADCAST_DRIVER=redis
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.
Đảm bảo Redis đang chạy trên hệ thống của bạn.
Để sử dụng broadcasting với Laravel Echo ở phía frontend, bạn cần cài đặt các gói sau:
npm install --save laravel-echo pusher-js
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);
});
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.
queue:work:Để 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.
Laravel hỗ trợ nhiều loại kênh cho việc chat realtime, bao gồm:
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');
}
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);
}
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');
});
.env và config/broadcasting.php cho từng
loại kênh.