Laravel5.6使用redis佇列實現系統通知

listenon發表於2018-09-01

一、資料庫

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。開啟檔案,寫上如下程式碼:

<?php

namespace App\Jobs;

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SendMessage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    private $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。


相關文章