Laravel 13 WebSocket 与实时通信详解
摘要
Laravel 的广播系统允许实时推送事件到前端。本文将深入讲解 Laravel 13 的 WebSocket 与实时通信,包括:
- 广播配置
- 事件广播
- 私有频道
- Laravel Echo
- 实战案例与最佳实践
本文适合希望构建实时应用的 Laravel 开发者。
1. 配置
1.1 广播配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| '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, ], ], 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], ],
|
1.2 启用广播
1 2 3 4
| 'providers' => [ App\Providers\BroadcastServiceProvider::class, ],
|
2. 定义广播事件
2.1 创建广播事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?php
namespace App\Events;
use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels;
class OrderShipped implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public function __construct( public Order $order ) {} public function broadcastOn(): array { return [ new PrivateChannel('orders.' . $this->order->user_id), ]; } public function broadcastWith(): array { return [ 'id' => $this->order->id, 'status' => $this->order->status, ]; } }
|
2.2 广播队列
1 2 3 4 5 6 7
| class OrderShipped implements ShouldBroadcast { use InteractsWithSockets, SerializesModels; public $connection = 'redis'; public $queue = 'broadcasts'; }
|
3. 频道
3.1 公共频道
1 2 3 4 5 6
| public function broadcastOn(): array { return [ new Channel('orders'), ]; }
|
3.2 私有频道
1 2 3 4 5 6
| public function broadcastOn(): array { return [ new PrivateChannel('orders.' . $this->order->user_id), ]; }
|
3.3 存在频道
1 2 3 4 5 6
| public function broadcastOn(): array { return [ new PresenceChannel('chat.' . $this->chat->id), ]; }
|
4. 频道授权
4.1 定义路由
1 2 3 4 5 6
| use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('orders.{userId}', function ($user, $userId) { return (int) $user->id === (int) $userId; });
|
4.2 模型绑定
1 2 3
| Broadcast::channel('orders.{order}', function ($user, Order $order) { return $user->id === $order->user_id; });
|
5. 前端集成
5.1 安装 Laravel Echo
1
| npm install --save-dev laravel-echo pusher-js
|
5.2 配置 Echo
1 2 3 4 5 6 7 8 9 10 11 12
| 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 });
|
5.3 监听公共频道
1 2 3 4
| Echo.channel('orders') .listen('OrderShipped', (e) => { console.log(e.order); });
|
5.4 监听私有频道
1 2 3 4
| Echo.private(`orders.${userId}`) .listen('OrderShipped', (e) => { console.log(e.order); });
|
5.5 监听存在频道
1 2 3 4 5 6 7 8 9 10 11 12 13
| Echo.join(`chat.${chatId}`) .here((users) => { console.log('Users in chat:', users); }) .joining((user) => { console.log('User joined:', user); }) .leaving((user) => { console.log('User left:', user); }) .listen('MessageSent', (e) => { console.log(e.message); });
|
6. 实战案例
6.1 实时聊天
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?php
namespace App\Events;
use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use App\Models\Message;
class MessageSent implements ShouldBroadcast { public function __construct( public Message $message ) {} public function broadcastOn(): array { return [ new PresenceChannel('chat.' . $this->message->chat_id), ]; } }
|
1 2 3 4
| Echo.join(`chat.${chatId}`) .listen('MessageSent', (e) => { this.messages.push(e.message); });
|
6.2 通知广播
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
namespace App\Notifications;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Messages\BroadcastMessage;
class OrderUpdated extends Notification { public function toBroadcast($notifiable): BroadcastMessage { return new BroadcastMessage([ 'order_id' => $this->order->id, 'status' => $this->order->status, ]); } public function broadcastOn() { return ['user.' . $this->order->user_id]; } }
|
7. 最佳实践
7.1 使用队列
1 2 3 4 5
| class OrderShipped implements ShouldBroadcast { use InteractsWithSockets, SerializesModels; }
|
7.2 限制广播数据
1 2 3 4 5 6 7
| public function broadcastWith(): array { return [ 'id' => $this->order->id, 'status' => $this->order->status, ]; }
|
8. 总结
Laravel 的广播系统提供了强大的实时通信能力:
- 事件广播:自动推送事件
- 频道授权:安全的频道访问
- 多种驱动:Pusher、Ably、Redis
- 前端集成:Laravel Echo 支持
参考资料