在 Laravel 12 中实现 WebSocket 通信主要有两种主流方案:官方推荐的 Laravel Reverb 和 第三方库(如 Soketi/Pusher 或 Workerman/Swoole)。以下是详细实现步骤:
一、官方方案:Laravel Reverb(推荐)
Laravel Reverb 是 Laravel 官方推出的高性能 WebSocket 服务,完全集成到框架中,适合标准实时场景(如聊天、通知)。
1. 安装 Laravel Reverb
composer require laravel/reverb
php artisan reverb:install
2. 配置环境变量(.env)
BROADCAST_DRIVER=reverb # 设置广播驱动为 Reverb
REVERB_SERVER_HOST=0.0.0.0 # 监听地址
REVERB_SERVER_PORT=8080 # 监听端口
REVERB_APP_ID=your_app_id # 应用唯一标识
REVERB_APP_KEY=your_app_key # 与前端 Echo 配置一致
REVERB_APP_SECRET=your_app_secret # 安全密钥
3. 启动 Reverb 服务
php artisan reverb:start
# 生产环境建议使用守护进程模式
php artisan reverb:start --daemon
4. 创建广播事件
php artisan make:event NewMessage
编辑 app/Events/NewMessage.php:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class NewMessage implements ShouldBroadcast {
public $message;
public function __construct($message) {
$this->message = $message;
}
public function broadcastOn() {
// 广播到频道 "chat"
return new Channel('chat');
}
}
5. 前端订阅(Laravel Echo)
安装 Laravel Echo 和 WebSocket 客户端:
npm install --save laravel-echo pusher-js
配置 resources/js/bootstrap.js:
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'reverb',
key: process.env.MIX_REVERB_APP_KEY,
wsHost: window.location.hostname,
wsPort: process.env.MIX_REVERB_PORT || 8080,
forceTLS: false, // 本地开发禁用 HTTPS
enabledTransports: ['ws', 'wss'],
});
订阅频道并监听事件:
// 订阅公共频道
Echo.channel('chat')
.listen('NewMessage', (data) => {
console.log('收到消息:', data.message);
});
// 订阅私有频道(需要认证)
Echo.private('chat.${userId}')
.listen('NewMessage', (data) => { /* ... */ });
6. 触发广播事件
use App\Events\NewMessage;
// 在控制器或任何地方触发事件
event(new NewMessage('Hello, WebSocket!'));
二、备选方案:Soketi(轻量级 Pusher 替代)
如果你需要更轻量级的解决方案,可以使用 Soketi(兼容 Pusher 协议)。
1. 安装 Soketi
npm install -g @soketi/soketi
soketi start --config=soketi.json
2. 配置 Laravel
修改 .env:
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your_app_id
PUSHER_APP_KEY=your_app_key
PUSHER_APP_SECRET=your_app_secret
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http # 生产环境改为 https
3. 前端 Echo 配置
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
wsHost: process.env.MIX_PUSHER_HOST || window.location.hostname,
wsPort: process.env.MIX_PUSHER_PORT || 6001,
forceTLS: false,
enabledTransports: ['ws', 'wss'],
});
三、高级场景:私有频道与认证
1. 频道认证路由
在 routes/channels.php 中定义私有频道授权:
Broadcast::channel('chat.{userId}', function ($user, $userId) {
return $user->id === (int) $userId; // 验证用户权限
});
2. 前端订阅私有频道
Echo.private('chat.' + userId)
.listen('NewMessage', (data) => { /* ... */ });
四、生产环境部署
HTTPS 配置:
必须使用 SSL 证书加密 WebSocket(wss://)。
修改前端 Echo 配置中的 forceTLS: true。
window.Echo = new Echo({
// ...
forceTLS: true,
disableStats: true, // 禁用统计
});
Supervisor 守护进程(Reverb):
[program:reverb]
command=php /path/to/artisan reverb:start --daemon
autostart=true
autorestart=true
stderr_logfile=/var/log/reverb.err.log
stdout_logfile=/var/log/reverb.out.log
五、常见问题排查
连接失败:
检查防火墙是否开放端口(8080/6001)。
确认服务正在运行:php artisan reverb:status。
查看日志:tail -f storage/logs/laravel.log。
跨域问题:
在 config/cors.php 中允许 WebSocket 域名:
'paths' => ['api/*', 'broadcasting/*'],
'allowed_origins' => ['https://your-domain.com'],
六、性能优化
Reverb 集群:多节点部署时使用 Redis 共享连接状态。
Swoole/Workerman:如需更高性能(10万+并发),可集成 Swoole:
composer require swooletw/laravel-swoole
php artisan swoole:http start
以上方案覆盖了从开发到生产的完整流程。对于大多数项目,Laravel Reverb 是最简单直接的方案;若需要更高灵活性或兼容 Pusher 生态,则选择 Soketi。