(解决)Laravel 广播 (Redis + socket.io) 前端监听不到后端事件,Echo.listen 不起作用

遇到的问题:前端Echo.listen不起作用,并且广播返回的数据也不是我想要的。

config/app.php 开启了 App\Providers\BroadcastServiceProvider::class,

事件类 LineStatusUpdated

namespace App\Events;
use App\Line;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class ShippingStatusUpdated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $line;
    public $broadcastQueue = 'redis';
    public function __construct(Line $line)
    {
        $this->line = $line;
    }

    /**
     * 频道名称
     * @return \Illuminate\Broadcasting\Channel|\Illuminate\Broadcasting\Channel[]|PrivateChannel
     */
    public function broadcastOn()
    {
        // 创建隐私频道
        return new PrivateChannel('line.' . $this->line->id);
    }

    /**
     * 播报数据
     * @return array
     */
    public function broadcastWith()
    {
        return ['line_id'=>$this->line->id];
    }

}

广播事件授权 routes/channels.php

Broadcast::channel('line.{line}', function (\App\User $user, \App\Line $line){
    return $line->user_id === $user->id;
});

然后自定义了一个Artisan命令用于触发ShippingStatusUpdated事件
routes/console.php

Artisan::command('bindevent {line}', function ($line){
    broadcast(new \App\Events\ShippingStatusUpdated(\App\Line::find($line)));
})->describe('test bindevent');

通过laravel-echo-server 检测到ShippingStatusUpdated事件可以正常触发。

但是在前端JS页面里监听不到ShippingStatusUpdated事件,ps: Laravel-echosocket.io-client都引进来了,前端打包没出现报错。

resources/js/app.js

import Echo from "laravel-echo"
window.io = require('socket.io-client');
window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: 'http://at.test:6001'
});
window.Vue = require('vue');
//这里省略其他代码.....

const app = new Vue({
    el: '#app',
    created(){
        window.Echo.private('line.'+ window.Laravel.line).listen('ShippingStatusUpdated', (e) => {
            //按正常来讲这里应该会监听到ShippingStatusUpdated事件的,可惜没有。问题就出在这里
            console.log(e);
        });
    },
});

经过测试,用horizon检测了队列也都没问题。 前后端也保持着Websocket 连接,但是奇怪的是数据既然是纯数字的。我明明在ShippingStatusUpdated事件里定义了broadcastWith方法并且返回['line_id'=>$this->line->id] 这样的数据。

Laravel 广播(Redis + socket.io) 前端监听不到后端事件,Echo.listen不起作用

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

@ahkxhyl 解决了,是因为laravel默认给redis添加了前缀,导致在前端Echo里监听的广播少了前缀。 解决办法修改config/databases.php 在 redis 的 options 去掉prefix那一行。 然后重启laravel-echo-server和队列即可

3周前 评论
ahkxhyl 3周前
讨论数量: 4
Epona

前端加入这个 私有频道的时候 laravel-echo-server 会正常显示 有人加入么?

3个月前 评论
Geekc (楼主) 3个月前
Epona (作者) 3个月前
Geekc (楼主) 3个月前
Epona (作者) 3个月前
Geekc (楼主) 3个月前
Epona (作者) 3个月前
Geekc (楼主) 3个月前
Epona (作者) 3个月前
Geekc (楼主) 3个月前
Epona

你可以先检测一下公开的 channel 前端是否能够接收到,如果可以,那么说明是私有频道的问题,不清楚你前端使用了什么验证,如果是jwt 那么需要在前端的 echo 里面加入对应的header

3个月前 评论

我也遇到这个情况,前端messages只显示数字,打印不出来事件相关,请问你的问题解决了吗

3周前 评论

@ahkxhyl 解决了,是因为laravel默认给redis添加了前缀,导致在前端Echo里监听的广播少了前缀。 解决办法修改config/databases.php 在 redis 的 options 去掉prefix那一行。 然后重启laravel-echo-server和队列即可

3周前 评论
ahkxhyl 3周前

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!