Laravel 9中Laravel-Echo无法监听广播事件求助
Laravel 9实时聊天功能中Laravel-Echo无法监听广播事件问题
我正在使用Laravel 9开发实时聊天功能,但Laravel-Echo无法监听我的广播事件。事件已触发,执行queue:work命令时可看到相关记录,我采用数据库驱动运行队列任务。
以下是我的相关代码与配置:
ChatEvent.php
class ChatEvent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $data; /** * Create a new event instance. * * @return void */ public function __construct($data) { $this->data = $data; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn(): Channel { return new Channel('chat.1'); } public function broadcastAs(): string { return 'chat-event'; } }
channels.php
Broadcast::channel('chat.1', function () { return true; });
ChatController.php
class ChatController extends Controller { public function sendMessage(Request $request) { $data = $this->storeMessage($request); event(new ChatEvent($data)); return response()->json(['success' => true, 'message'=>$data->contents, 'created_by'=> carbon($data->created_by)->format('g:i A')]); } }
chat.blade.php中的监听代码
<script> window.Echo.channel('chat.1') .listen('.chat-event', (e) => { console.log(e) //code for html }); $("#send-message").on('click', function(e){ e.preventDefault(); var _token = $("input[name='_token']").val(); var sender = $("input[name='sender']").val(); var receiver = $("input[name='receiver']").val(); var task = $("input[name='task']").val(); var message = $("#chat").val(); if(message != ''){ $.ajax({ type: "POST", url: '{!! route("sendMessage") !!}', dataType: "json", data: {'_token':_token, 'message':message, 'sender':sender, 'receiver':receiver, 'task':task}, success:function(data) { //code in html } }); } }) </script>
bootstrap.js
import Echo from 'laravel-echo'; import PusherJS from 'pusher-js'; // import io from 'socket.io-client'; let client = new PusherJS('app-key', { key: import.meta.env.VITE_PUSHER_APP_KEY, wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', encrypted: true, disableStats: true, enabledTransports: ['ws', 'wss'], cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER, wssPort: import.meta.env.VITE_PUSHER_PORT }); window.PUSHERClient = client; window.Echo = new Echo({ // broadcaster: "socket.io", // host: import.meta.env.MIX_APP_URL + ":6001", broadcaster: "pusher", client: window.PUSHERClient, });
.env配置
PUSHER_APP_ID=secret-id PUSHER_APP_KEY=secret-key PUSHER_APP_SECRET=secret-secret PUSHER_HOST= PUSHER_PORT=443 PUSHER_SCHEME=https PUSHER_APP_CLUSTER=ap1 VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" VITE_PUSHER_HOST="${PUSHER_HOST}" VITE_PUSHER_PORT="${PUSHER_PORT}" VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
附加信息
- laravel-echo-server已正常启动
- redis-cli监控显示有数据写入
- database.php中redis配置:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), // 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), 'prefix' => '', ],
我期望监听器能触发并执行对应脚本,但目前仅事件触发,Laravel-Echo无响应。
排查与修复建议
统一广播驱动与Echo服务
当前配置存在矛盾:代码中用Pusher作为广播器,但启动了laravel-echo-server(通常对应socket.io驱动),两者无法兼容,必须二选一:- 选择laravel-echo-server:
- 修改
.env:BROADCAST_DRIVER=redis(需安装predis/predis依赖) - 调整bootstrap.js启用socket.io配置:
import io from 'socket.io-client'; window.Echo = new Echo({ broadcaster: "socket.io", host: import.meta.env.VITE_APP_URL + ":6001", }); - 确保laravel-echo-server配置文件(
laravel-echo-server.json)中database为redis,且Redis参数与Laravel一致。
- 修改
- 选择Pusher官方服务:
- 停止laravel-echo-server,确保
.env中BROADCAST_DRIVER=pusher - 修正PusherJS初始化错误:去掉第一个冗余的
'app-key'参数,避免覆盖配置中的key:let client = new PusherJS({ key: import.meta.env.VITE_PUSHER_APP_KEY, wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', encrypted: true, disableStats: true, enabledTransports: ['ws', 'wss'], cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER, wssPort: import.meta.env.VITE_PUSHER_PORT });
- 停止laravel-echo-server,确保
- 选择laravel-echo-server:
验证广播链路完整性
- 执行
php artisan queue:work后,查看Redis是否有广播消息被消费(laravel-echo-server运行时会读取Redis中的广播数据) - 打开浏览器开发者工具的Network面板,查看WebSocket连接是否成功建立,有无报错信息
- 执行
确认事件监听格式
前端用.chat-event监听自定义事件名的写法是正确的,但要确保broadcastAs()返回的名称与前端完全一致,无拼写或大小写错误检查跨域配置
如果前端与Laravel应用不在同一域名,需要在Laravel的config/cors.php中允许WebSocket相关的请求,或者在laravel-echo-server配置中设置corsOrigin为前端地址
内容的提问来源于stack exchange,提问作者Isyraf
相关产品推荐
相关产品推荐

