Laravel+Vue 前后分离实现实时消息推送

2,692 阅读2分钟

基于websocket和redis来实现前后的实时消息推送  

使用工具与技术栈

前端

  • Vue
  • Laravel-echo
  • socket.io-client

后端

  • Laravel
  • Laravel-echo-server
  • redis

前端部分

准备

npm install --save socket.io-client
npm install --save laravel-echo

// 设置websocket链接
  window.io = require("socket.io-client")
  let echo  = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'    // 链接对应的后端 Laravel-echo-server服务器
  })

使用

这里只写了基础语法,详细的请看Laravel-echo 文档

 // 订阅频道
echo.channel(`broadcasting-name`)
.listen('broadcasting-event', (e) => {
    console.log(e);
});

连接正常就是控制器没有红色出现!!

后端部分

准备

1 安装关于redis的依赖

composer require predis/predis

2 搭建laravel-echo-server,这个其实算是另外运行的一个服务,当然你要直接在项目里面弄也是没有问题的

// 安装
npm install -g laravel-echo-server

// 初始化
laravel-echo-server init

//启动服务
laravel-echo-server start

// 停止服务
laravel-echo-server stop

3 安装redis,我这使用的是ubuntu,安装方法

4 修改相关配置

  • 打开config/app.php,放开App\Providers\BroadcastServiceProvider::class
  • 注释掉config/database.php里面的redis下面的optingPrefix
  • 在.env中添加QUEUE_DRIVER=redisBROADCAST_DRIVER=redis
# 打开config

编写相关逻辑

1 启动服务

按顺序开启最好,不然总有一个会报错

// 开启队列
 php artisan queue:listen --tries=1
// 开启redis服务
./src/redis-server redis.conf &
// 开启 laravel-echo-server
laravel-echo-server start

2 添加事件类

php artisan make:event TestEvent
# 之后会在app/Event中添加一个TestEvent,他需要实现 ShouldBroadcast 接口 ,具体的代码如下
class ShippingStatusUpdated implements ShouldBroadcast
{
    use  Dispatchable,InteractsWithSockets,SerializesModels;
    public $broadcastQueue = 'redis';
    /**
     * 有关更新的信息。
     * @var string
     */
    public $message;
    /**
     * Create a new event instance.
     * @return void
     */
    public function __construct($message)
    {
        $this->message = $message;
    }
    
    /**
     * 指定广播数据。
     * @return array
     */
    public function broadcastWith()
    {
        // 返回当前时间
        return ['message' => $this->message];
    }

    /**
     * 获取事件应该广播的频道。
     * @return array
     */
    public function broadcastOn()
    {
        return new Channel('user');
    }
}

然后在routes/channels.php添加频道

Broadcast::channel('name', function ($user, $id) {
    # 这里返回必须是返回true才可以通过,验证时需要
    return (int) $user->id === (int) $id;
});

之后只要前端正常接入,触发事件就了

测试方法

我这里是直接添加了一个命令来测试,麻烦的地方就自己开一个页面来接收
routes/console.php中添加测试命令

Artisan::command('bindEvent', function () {
    broadcast(new \App\Events\ShippingStatusUpdated('触发到了'));
})->describe('测试广播是否正常');

正常情况下,前端页面控制台会收到传入的数据