You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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无响应。


排查与修复建议

  1. 统一广播驱动与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
        });
        
  2. 验证广播链路完整性

    • 执行php artisan queue:work后,查看Redis是否有广播消息被消费(laravel-echo-server运行时会读取Redis中的广播数据)
    • 打开浏览器开发者工具的Network面板,查看WebSocket连接是否成功建立,有无报错信息
  3. 确认事件监听格式
    前端用.chat-event监听自定义事件名的写法是正确的,但要确保broadcastAs()返回的名称与前端完全一致,无拼写或大小写错误

  4. 检查跨域配置
    如果前端与Laravel应用不在同一域名,需要在Laravel的config/cors.php中允许WebSocket相关的请求,或者在laravel-echo-server配置中设置corsOrigin为前端地址

内容的提问来源于stack exchange,提问作者Isyraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:04:55