Laravel 事件处理(event)+ 队列使用(queue)

2023-09-05 16:03:41 浏览数 (1)

步骤

  • 修改appProvidersEventServiceProvider.php加入测试事件
代码语言:javascript复制
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        // passport 移除失效令牌事件
        'LaravelPassportEventsAccessTokenCreated' => [
            'AppListenersRevokeOldTokens',
        ],
        'LaravelPassportEventsRefreshTokenCreated' => [
            'AppListenersPruneOldTokens',
        ],

        // 测试事件
        'AppEventsTest' => [
            'AppListenersTestListener',
        ],
    ];
  • 执行php artisan event:generate生成事件和监听器 使用命令生成的监听器会自动帮你引入ShouldQueue(队列接口),接下来你要在刚刚生成的TestListener中implements该接口。
代码语言:javascript复制
<?php

namespace AppListeners;

use AppEventsTest;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;

class TestListener implements ShouldQueue
{
    /**
     * 任务应该发送到的队列的连接的名称
     *
     * @var string|null
     */
    public $connection = 'redis';

    /**
     * 任务应该发送到的队列的名称
     *
     * @var string|null
     */
    public $queue = 'FMock';
}
  • 添加事件和监听器具体方法 这里我们以修改用户头像为例子,Test.php中传入User实例:
代码语言:javascript复制
<?php

namespace AppEvents;

use AppModelsUser;
use IlluminateBroadcastingChannel;
use IlluminateQueueSerializesModels;
use IlluminateBroadcastingPrivateChannel;
use IlluminateBroadcastingPresenceChannel;
use IlluminateFoundationEventsDispatchable;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateContractsBroadcastingShouldBroadcast;

class Test
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user;

    /**
     * Create a new event instance.
     *
     * @param $user
     *
     * @return void
     */
    public function __construct(User $user)
    {
        //
        $this->user = $user;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return IlluminateBroadcastingChannel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('test');
    }
}

TestListener.php中传入做具体修改操作:

代码语言:javascript复制
<?php

namespace AppListeners;

use AppEventsTest;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;

class TestListener implements ShouldQueue
{
    /**
     * 任务应该发送到的队列的连接的名称
     *
     * @var string|null
     */
    public $connection = 'redis';

    /**
     * 任务应该发送到的队列的名称
     *
     * @var string|null
     */
    public $queue = 'FMock';

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  Test  $event
     * @return void
     */
    public function handle(Test $event)
    {
        //
        $event->user->avatar = 'test' . rand();
        $event->user->save();
    }
}
  • 在任意控制器调用该事件
代码语言:javascript复制
<?php
/**
 * @Author huaixiu.zhen
 * http://litblc.com
 * User: z00455118
 * Date: 2018/12/19
 * Time: 15:59
 */

namespace AppHttpControllersWeb;


use AppEventsTest;
use AppRepositoriesEloquentUserRepository;

class IndexController
{
    public function index()
    {
        return 'hello web';
    }

    public function event(UserRepository $userRepository)
    {
        $user = $userRepository->find(14);
        event(new Test($user));
        return '事件测试';
    }
}
  • 执行队列脚本 执行php artisan queue:work redis --queue=FMock --daemon --quiet --delay=3 --sleep=3 --tries=3

该脚本定义了一下优化参数,执行redis中名字为FMock的队列,不输出任何信息,3秒一次,失败后3秒重新执行,最多执行3次。

  • 忘了,记得修改配置文件 刚刚我们在监听器中定义的队列名称是public $queue = 'FMock';,所以要在配置文件中增加:
代码语言:javascript复制
        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'FMock',
            'retry_after' => 90,
        ],

搞定!

执行一下我们的控制器方法,快速(3s内)查看redis,就可以看到queues:FMock的键值,队列执行完毕则被删除。

注意事项

  • queue配置文件中,无论用哪个连接,队列的名称都要与Listener中相互对应。
  • 配置完要执行执行队列命令,记得加上相应的优化参数。

代码查阅

这段测试代码可以在我的gayhub找到并执行。

0 人点赞