内容简介:这一篇教程我们直接以首先我们来看一些扩展包自带的系统事件,这些系统事件又可以进一步划分为 Laravel 应用级别的系统事件以及 Swoole 底层 Worker 进程级别的系统事件。注:在基于 Swoole HTTP 服务器的系统中,Worker 进程相当于 Nginx + PHP-FPM 组合中的 PHP-FPM,关于 Swoole 的底层实现细节后面我们会详细介绍。
这一篇教程我们直接以 hhxsv5/laravel-s 扩展包为例,演示如何在 Laravel 项目中基于 Swoole 实现事件监听。
系统自带事件
首先我们来看一些扩展包自带的系统事件,这些系统事件又可以进一步划分为 Laravel 应用级别的系统事件以及 Swoole 底层 Worker 进程级别的系统事件。
注:在基于 Swoole HTTP 服务器的系统中,Worker 进程相当于 Nginx + PHP-FPM 组合中的 PHP-FPM,关于 Swoole 的底层实现细节后面我们会详细介绍。
应用级别系统事件
首先我们来看扩展包自带的 Laravel 应用请求生命周期中的两个系统事件,分别是 laravels.received_request
和 laravels.generated_response
,我们可以通过监听这两个事件来重置或销毁一些全局( global
)或静态( static
)变量,或者修改当前的请求或响应对象。
laravels.received_request
laravels.received_request
事件会在 LaravelS 扩展包将 Swoole\Http\Request
请求实例转化为 Illuminate\Http\Request
时触发(源码位于 vendor/hhxsv5/laravel-s/src/LaravelS.php
):
public function onRequest(SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) { try { parent::onRequest($swooleRequest, $swooleResponse); $laravelRequest = $this->convertRequest($this->laravel, $swooleRequest); $this->laravel->bindRequest($laravelRequest); $this->laravel->fireEvent('laravels.received_request', [$laravelRequest]); ...
由于请求已经转化为 Laravel 请求实例,也将相应的实例信息绑定到 Laravel 容器,并且该事件是通过 Laravel 框架内置的事件分发机制触发的,所以我们可以基于 Laravel 的事件监听机制监听该事件并进行处理,比如,在 app/Providers/EventServiceProvider.php
服务提供者的 boot
方法中添加如下事件监听处理代码:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Event; Event::listen('laravels.received_request', function (Request $request, $app) { $request->query->set('get_key', 'swoole-get-param');// 修改 GET 请求参数 $request->request->set('post_key', 'swoole-post-param'); // 修改 POST 请求参数 });
这个时候我们重新加载一下 Swoole HTTP 服务器,就可以从请求实例中获取到 get_key
和 post_key
参数的值了。
laravels.generated_response
laravels.generated_response
事件会在 Laravel Kernel 处理完请求,扩展包将 Illuminate\Http\Response
响应实例转化为 Swoole\Http\Response
前触发(源码位于 vendor/hhxsv5/laravel-s/src/LaravelS.php
,感兴趣的同学自己看下,在处理静态资源和动态资源时都会触发),因此仍然在 Laravel 请求生命周期之内,由于该事件也是通过 Laravel 内置的事件分发机制触发的,所以可以按照 Laravel 监听事件的方式对其进行处理,还是在 app/Providers/EventServiceProvider.php
服务提供者的 boot
方法最后添加如下事件监听处理代码如下:
use Illuminate\Http\Response; Event::listen('laravels.generated_response', function (Request $request, Response $response, $app) { $response->headers->set('header-key', 'swoole-header'); });
重新加载 Swoole HTTP 服务器,通过域名 todo-s.test
请求任意路由,就可以看到响应头中包含 header-key
字段了:
进程级别系统事件
此外扩展包还提供了几个 Worker 进程级别的系统事件:
事件名 | 事件监听器接口 | 触发时间 |
---|---|---|
WorkerStart |
Hhxsv5\LaravelS\Swoole\Events\WorkerStartInterface |
当 Worker/Task 进程启动时触发,此时 Laravel 初始化已经完成 |
WorkerStop |
Hhxsv5\LaravelS\Swoole\Events\WorkerStopInterface |
当 Worker/Task 进程正常退出时触发 |
WorkerError |
Hhxsv5\LaravelS\Swoole\Events\WorkerErrorInterface |
当 Worker/Task 进程出现异常或错误时触发 |
由于这几个事件不是通过 Laravel 框架内置的事件分发机制触发,所以需要通过额外的监听机制来实现事件的监听和处理,在 LaravelS 扩展包支持的体系中,我们需要创建实现该事件对应事件监听器接口的事件监听器类,以 WorkerStart
事件为例,对应要实现的接口是 Hhxsv5\LaravelS\Swoole\Events\WorkerStartInterface
,我们在 app/Events
目录下创建实现该接口的对应事件监听器类 WorkerStartEventListener
,并编写事件处理代码如下:
<?php namespace App\Listeners; use Hhxsv5\LaravelS\Swoole\Events\WorkerStartInterface; use Illuminate\Support\Facades\Log; use Swoole\Http\Server; class WorkerStartEventListener implements WorkerStartInterface { public function __construct() { } public function handle(Server $server, $workerId) { Log::info('Worker/Task Process Started'); } }
然后在配置文件 config/laravels.php
的 event_handlers
配置项中添加事件与事件监听器的映射关系:
'event_handlers' => [ 'WorkerStart' => \App\Listeners\WorkerStartEventListener::class, ],
重新启动 Swoole HTTP 服务器,就可以在 storage/logs
目录下最新的 Laravel 日志中看到 Worker/Task Process Started
日志。
自定义异步事件监听及处理
除了扩展包自带的系统事件外,还可以编写自定义的异步事件,该特性基于 Swoole 的异步任务,首先需要在配置文件 config/laravels.php
中设置 swoole.task_worker_num
(我们在上一篇教程中已经设置过)。
要实现异步事件监听,需要创建一个继承自 Hhxsv5\LaravelS\Swoole\Task\Event
基类的事件类,我们在 app/Events
目录下创建这个类,类名为 TestEvent
,初始化该事件类的代码如下:
<?php namespace App\Events; use Hhxsv5\LaravelS\Swoole\Task\Event; class TestEvent extends Event { private $data; public function __construct($data) { $this->data = $data; } public function getData() { return $this->data; } }
然后在 app/Listeners
目录下创建一个监听该事件的监听器类 TestEventListener
,该监听器继承自 Hhxsv5\LaravelS\Swoole\Task\Listener
基类,初始化监听器代码如下:
<?php namespace App\Listeners; use App\Events\TestEvent; use Hhxsv5\LaravelS\Swoole\Task\Event; use Hhxsv5\LaravelS\Swoole\Task\Listener; use Illuminate\Support\Facades\Log; class TestEventListener extends Listener { public function __construct() { } public function handle(Event $event) { Log::info(__CLASS__ . ': 开始处理', [$event->getData()]); sleep(3);// 模拟耗时代码的执行 Log::info(__CLASS__ . ': 处理完毕'); } }
接下来,我们需要在配置文件 config/laravels.php
的 events
配置项中配置自定义事件与事件监听器的映射关系(一个事件可以绑定多个监听器):
'events' => [ \App\Events\TestEvent::class => [ \App\Listeners\TestEventListener::class, ] ],
最后,我们在 routes/web.php
中编写一段测试代码来测试事件的触发:
Route::get('/event/test', function () { $event = new \App\Events\TestEvent('测试异步事件监听及处理'); $success = \Hhxsv5\LaravelS\Swoole\Task\Event::fire($event); var_dump($success); });
重新启动 Swoole HTTP 服务器,在浏览器中访问 http://todo-s.test/event/test
,页面会立即返回,对应的事件处理则会异步执行,你可以在 storage/logs
目录下最新的 Laravel 日志中看到相应的事件处理日志。
以上就是 Laravel 中基于 Swoole 实现异步事件监听及处理的简单示例,相较于原生 Laravel 自带的那套推送任务/事件到队列再通过 PHP CLI 启动新进程异步消费队列任务的逻辑,Swoole 原生支持异步任务,极大简化了异步任务和异步事件监听和处理的实现流程。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Robotgo v0.80.0 发布, 增加异步事件和多组合键监听 hook 支持
- Laravel 给生产环境添加监听事件 - SQL日志监听
- Flutter事件监听
- 初始化监听端口
- Vue简便监听事件
- react源码-事件监听
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
父与子的编程之旅
桑德 (Warren Sande)、桑德 (Carter Sande) / 苏金国、易郑超 / 人民邮电出版社 / 2014-10-1 / CNY 69.00
本书是一本家长与孩子共同学习编程的入门书。作者是一对父子,他们以Python语言为例,详尽细致地介绍了Python如何安装、字符串和操作符等程序设计的基本概念,介绍了条件语句、函数、模块等进阶内容,最后讲解了用Python实现游戏编程。书中的语言生动活泼,叙述简单明了。 为了让学习者觉得编程有趣,本书编排了很多卡通人物及场景对话,让学习者在轻松愉快之中跨入计算机编程的大门。 第 2 版新增内......一起来看看 《父与子的编程之旅》 这本书的介绍吧!