Laravel5.6使用redis队列实现系统通知

一、数据库

1、.env文件中修改 QUEUE_DRIVER=syncQUEUE_DRIVER=database

2、创建通知模型和通知数据表迁移文件:php artisan make:model Models/Notice -m

数据表迁移文件 create_notices_table 中的up方法中修改内容如下:

Schema::create('notices', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title', 50);
    $table->text('content');
    $table->timestamps();
});

Schema::create('user_notice', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('user_id')->default(0);
    $table->integer('notice_id')->default(0);
    $table->timestamps();
});
复制代码

down方法中

public function down()
{
    Schema::dropIfExists('notices');
    Schema::dropIfExists('user_notice');
}
复制代码

解析:notices表是用户通知表,user_notice是中间表,因为用户和通知之间的关系是多对多。

接着执行数据库迁移:php artisan migrate

后台

1、在 web.php中设置通知路由:

Route::middleware('auth.admin:admin')->name('admin.')->group(function () {
    $this->get('/', 'AdminController@index');

    $this->resource('notices', 'NoticeController')->except(['show', 'edit', 'update']);
});
复制代码

2、创建对应控制器:php artisan make:controller Admin/NoticeController -r

3、在User.php模型中,定义关联关系如下:

//用户和通知之间是多对多
public function notices()
{
    return $this->belongsToMany('App\Models\Notice', 'user_notice', 'user_id', 'notice_id')->withPivot(['user_id', 'notice_id']);
}

//给用户增加通知
public function addNotice($notice)
{
    return $this->notices()->save($notice);
}
复制代码

4、后台实现新增通知和通知列表即可。样式参考如下,代码省略...

5、注意:功能实现后,新增一个用户,此时notices表是有数据的,但是中间表是没有数据的。

前端

1、在web.php中设置前端路由,用于显示所有通知。

Route::namespace('home')->group(function(){

      $this->get('/','HomeController@index');

     //前端通知显示
     $this->get('/notice', 'HomeController@notice')->name('notice');
})
复制代码

2、在前端Home控制器中创建 notice方法,代码如下:

/***
 * 前端通知页面
 * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 */
public function notice()
{
    //获取当前用户的notice
    $user = \Auth::user();
    $notices = $user->notices;
    return view('notice.index', compact('notices'));
}
复制代码

3、加载页面,在resources/views/home/notice创建index模板,并循环加载通知内容。此时,访问前端通知的路由地址,你会发现数据库里的通知并没有渲染出来,如图:

接下来我们要按需求实现消息的分发。

队列的使用

1、打开终端执行命令:php artisan queue:table,打开迁移文件,代码如下:

Schema::create('jobs', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('queue')->index()->comment('队列名称');
    $table->longText('payload')->comment('队列数据');
    $table->unsignedTinyInteger('attempts')->comment('尝试次数');
    $table->unsignedInteger('reserved_at')->nullable()->comment('保留时间');
    $table->unsignedInteger('available_at')->comment('可运行时间');
    $table->unsignedInteger('created_at')->comment('队列创建时间');
});
复制代码

2、执行迁移命令:php artisan migrate,会在数据库中生成jobs

3、生成任务类,执行命令:php artisan make:job SendMessage,这个命令会在你的项目目录结构App\Jobs中生成一个任务类文件SendMessage.php。打开文件,写上如下代码:

$notice;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($notice)
    {
        $this->notice = $notice;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //通知每个用户的 系统消息
        $users = User::all();
        foreach ($users as $user) {
            $user->addNotice($this->notice);
        }
    }
}
复制代码

4、打开后台NoticeController 通知控制器,在执行新增通知方法中加上如下代码:

// use App\Jobs\SendMessage;

public function store(Request $request)
{
    $request->validate([
        'title' => 'bail|required|unique:notices|max:255',
        'content' => 'required',
    ]);

    $notice = Notice::create($request->all());

     //执行消息分发
    dispatch(new \App\Jobs\SendMessage($notice));
    //SendMessage::dispatch($notice)

    return redirect(route('admin.notices.index'))->with('success', '新增通知成功');
}
复制代码

5、启动队列:php artisan queue:work,注意:不要关闭了。
6、测试:浏览器访问前端地址:http://queue.test/notice,你会看到如下页面,即为消息分发成功:

Well Done !!!

二、Redis队列

1、修改.env文件中的 QUEUE_DRIVER=syncQUEUE_DRIVER=redis

2、启动队列,终端执行命令:redis-server,你会发现predis的扩展没装

执行命令:composer require predis/predis 安装即可。安装完成后,重新启动redis。


你可能感兴趣的:(Laravel5.6使用redis队列实现系统通知)