shunhua's blog

Laravel 事件系统

2019-04-22

生成一个事件类

php artisan make:event UserLogin

app/Events 中就会自动生成一个 UserLogin.php 文件,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class UserLogin
{
use InteractsWithSockets, SerializesModels;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}

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

定义监听器
一个事件可以被一个或多个监听器监听,也就是观察者模式,我们可以定义多个监听器,当这个事件发生,执行一系列逻辑。

在 app/Providers/EventServiceProvider 的 $listen 中可以定义事件和监听器,如下:

1
2
3
4
5
6
protected $listen = [
'App\Events\UserLogin' => [
'App\Lisenter\DoSomething1',
'App\Lisenter\Dosomething2',
],
];

然后执行 artisan 命令,就可以自动在 app/Lisenter 目录生成监听器。

php artisan event:generate

可以看到 app/Lisenter 目录多了 DoSomething1.php 和 DoSomething2.php 两个文件,我们看看其中一个内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class DoSomething1
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Handle the event.
*
* @param UserLogin $event
* @return void
*/
public function handle(UserLogin $event)
{
info('do something1');
}
}

在两个监听器的 handle 方法中我们打印一个日志来测试一下,如代码 handle 方法所示。
分发和触发事件
我们在路由中来分发事件,也就是触发事件,看监听器是否正常工作 :

1
2
3
4
use App\Events\UserLogin;
Route::get('/', function () {
event(new UserLogin());
});

然后我们请求这个路由,观察日志,发现打印了日志:

[2019-04-22 10:04:29] local.INFO: do something1
[2019-04-22 10:04:29] local.INFO: do something2

队列异步处理
确认redis 连接正常 编辑env

1
2
3
4
5
QUEUE_CONNECTION=redis

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

比如把上面的 DoSomething1 改成需要放入队列的,只需要 implements ShoulQueue 接口。

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

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

我们再次执行路由。
日志里没有打印 do something1,只有 do something2,但是在 redis 队列里发现了一个名为 queues:default 的列表。

php artisan queue:work –queue=listeners

ico原来的样子

使用支付宝打赏
使用微信打赏

欢迎点击上方按钮对我打赏,谢谢你给我吃糖果