不必自己跑 Reverb 的 Laravel Echo
改幾個 .env 值,事件、頻道、whisper 與 toOthers() 照常運作。
Laravel Broadcasting 本來就使用 Pusher 協定,所以 Laravel 應用程式用內建的 pusher 連線就能把廣播送到 Hibira。事件、頻道路由與 Echo 程式碼都不用改。省下的是原本要自己跑的 WebSocket 伺服器:長時間執行的 Reverb 行程、超過一台機器時用來擴展的 Redis、黏性負載平衡,以及半夜得有人盯著它。
使用者得到什麼
- 訂單狀態、通知與儀表板不必重新整理就會更新。
- 透過 Echo 的
join與whisper,做出有「輸入中…」提示與上線名單的聊天。 - 頁面一打開就是最新狀態,不會在下一個事件到來前一片空白。
用到的功能
- Laravel Broadcasting,使用
pusher連線與pusher/pusher-php-server。 - 瀏覽器端的 Laravel Echo 搭配
pusher-js。 - 私有頻道與 presence 頻道,由你自己的
routes/channels.php授權。 - 用戶端事件(Echo
whisper)與排除發送者(toOthers())。 - 快取頻道(
cache-),把最後一則事件交給每位新訂閱者。
步驟 1:把 Broadcasting 指向 Hibira
Laravel 11 以後,安裝 broadcasting,詢問時選擇 Pusher:
php artisan install:broadcasting
composer require pusher/pusher-php-server
npm install --save-dev laravel-echo pusher-js接著在 .env 設定連線,數值來自你的應用程式頁面:
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=YOUR_APP_ID
PUSHER_APP_KEY=YOUR_APP_KEY
PUSHER_APP_SECRET=YOUR_APP_SECRET
PUSHER_HOST=ws.hibira.io
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=ap
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"Laravel 10 以前請用 BROADCAST_DRIVER=pusher 取代 BROADCAST_CONNECTION。預設的 config/broadcasting.php 已經會把 host、port 與 scheme 傳給 Pusher 函式庫;如果你的設定檔是手寫的,請確認 options 有讀取這些值,才不會連到 pusher.com。
步驟 2:設定 Echo
// resources/js/echo.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: 'ap',
wsHost: import.meta.env.VITE_PUSHER_HOST,
wsPort: import.meta.env.VITE_PUSHER_PORT,
wssPort: import.meta.env.VITE_PUSHER_PORT,
forceTLS: import.meta.env.VITE_PUSHER_SCHEME === 'https',
enabledTransports: ['ws', 'wss'],
});步驟 3:把事件廣播給單一顧客
class OrderShipped implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(public Order $order) {}
public function broadcastOn(): array
{
return [new PrivateChannel('orders.'.$this->order->id)];
}
}
// routes/channels.php
Broadcast::channel('orders.{id}', fn ($user, $id) => $user->orders()->whereKey($id)->exists());
// Wherever the order ships
OrderShipped::dispatch($order);Echo.private(`orders.${orderId}`)
.listen('OrderShipped', (e) => showStatus(e.order));ShouldBroadcast 事件會經過你的佇列,所以必須有 worker(php artisan queue:work)在跑。專案沒有佇列時,改用 ShouldBroadcastNow 在請求當下發布。
步驟 4:presence、whisper 與 toOthers()
Echo.join(`room.${roomId}`)
.here((users) => online.set(users))
.joining((user) => online.add(user))
.leaving((user) => online.remove(user))
.listen('MessageSent', (e) => messages.append(e.message))
.listenForWhisper('typing', (e) => typing.show(e.name, 3000));broadcast(new MessageSent($message))->toOthers();Whisper 是用戶端事件:請在應用程式設定中開啟 Allow client events。toOthers() 透過 X-Socket-ID 標頭跳過發送者自己的分頁,Echo 會自動把它加到 Axios 請求;用 fetch 的話,請自己送出 'X-Socket-ID': Echo.socketId()。完整的聊天室請看聊天使用情境。
步驟 5:每個新頁面都拿到最新狀態
在名稱以 cache- 開頭的頻道上廣播,之後才訂閱的人會立刻收到最後一則事件(保留 30 分鐘):
public function broadcastOn(): array
{
return [new Channel('cache-scoreboard')];
}Echo.channel('cache-scoreboard')
.listen('ScoreUpdated', (e) => board.render(e.scores));Echo.private('cache-orders.1') 也一樣,會變成 private-cache-orders.1 頻道。
從 Reverb 或其他相容 Pusher 的服務換過來
只有 .env 的值會變:事件、頻道路由與 Echo 程式碼都不變,所以可以一次切換一個環境,要換回去也一樣簡單。遷移頁面列出要檢查的項目,登入後 Laravel 指南會用你的應用程式數值填好同樣的設定。
小提醒
- 每個環境(本機、測試、正式)各建一個應用程式,測試事件就不會送到真正的使用者。
- presence 頻道最多 100 位成員。更大的房間請看大量觀眾。
- 每次廣播不論有多少瀏覽器收到,都只算一則訊息;送達與 presence 更新不另計費。