无需自己运行 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 更新不另计费。