站長資訊網
最全最豐富的資訊網站

Think-Swoole之Task 異步任務

Think-Swoole之Task 異步任務

使用場景

在 Server 程序中如果需要執行很耗時的操作,比如一個聊天服務器發送廣播,Web服務器中發送郵件。如果直接去執行這些函數就會阻塞當前進程,導致服務器響應變慢。例如:用戶注冊場景,完成注冊并發送激活郵件的功能,需要以下幾步:

客戶端提交 POST 數據 -> 服務器獲取到數據 -> 完成注冊將用戶數據寫入數據庫 -> 發送賬號激活郵件 -> 返回客戶端提示注冊成功。

這個業務邏輯是沒有問題的,但是由于發送郵件是一個耗時操作(比如2-3s)并且會同步阻塞程序的執行,直到發送成功以后響應到客戶端提示注冊成功。這個過程中用戶從提交到最后得到注冊成功的提示估計需要4s左右,一次請求響應需要4s這肯定是不合理的!

現在使用 Task 異步任務投遞可以大大提升用戶體驗,大致流程:

客戶端提交 POST 數據 -> 服務器獲取到數據 -> 完成注冊將用戶數據寫入數據庫 -> 馬上返回客戶端提示注冊成功。

在注冊成功同時投遞一個 Task 任務 -> 異步完成郵件發送的耗時操作 (這部分時間用戶是無感知的,因為很早已經響應回客戶端了)。

如何使用 Think-Swoole 的 Task 異步任務的步驟

定義事件監聽類(php think make:listener 類名)。

app/event.php 文件中定義 swoole.task 的事件監聽。

獲取到 Swoole/Server 對象調用 task 方法(參數中傳遞剛剛定義的監聽類)。

在剛剛定義的事件監聽類的 handle 方法中定義觸發回調邏輯代碼。

調用觸發 task swoole.finish任務完成后的 finish 方法(需要才調用,非必須)。

進行演示

首先,項目根目錄創建郵件發送事件:

php think make:listener EmailTask

然后定義創建的郵件發送事件:

app/event.php 'listen'    => [     'AppInit'  => [],     'HttpRun'  => [],     'HttpEnd'  => [],     'LogLevel' => [],     'LogWrite' => [],     'swoole.task' => [         applistenerEmailTask::class,     ], //  'swoole.finish' => [ //      applistenerEmailTaskFinish::class, //  ], ],

其中 swoole.task 這個鍵名是 Task 任務固定寫法不能隨意命名。

接著,我們在負責用戶注冊的控制器內,通過 Swoole/Server 類來調用 Task 異步任務,當然,我們要先完善 EmailTask.php 的邏輯代碼:

app/listener/EmailTask.php

<?php declare (strict_types = 1); namespace applistener; class EmailTask {     /**      * 事件監聽處理      *      * @return mixed      */     public function handle($event) {         echo "開始發送郵件:".time();         //模擬耗時 3 秒,測試是否在響應事件內         sleep(3);         echo "郵件發送成功:".time();         // 可以調用 finish 方法通知其他事件類,通知當前異步任務已經完成了(非必須調用)         // 參數 $event 是 SwooleServerTask 類的一個對象 可以調用 finish 方法觸發 task 任務的 onFinish 事件         // $event -> finish(applistenerEmailTaskFinish::class);     } }

注冊方法 app/controller/Register.php

<?php namespace appcontroller; use appBaseController; class Register extends BaseController {     public function register(SwooleServer $server) {         if($this -> request -> isPost()){             $data = $this -> request -> post();             //TODO 調用驗證類驗證數據             //TODO 將注冊信息插入數據庫             // 這里調用 Task 異步任務             $server -> task(applistenerEmailTask::class);             // 方式二 //            $manager = app('thinkswooleManager'); //            $manager -> getServer() -> task(applistenerEmailTask::class);             return "注冊成功!".time();         }     } }

注冊業務中,插入數據庫后,調用了發送郵件異步任務,在 EmailTask.php 模擬發送郵件需要 3 秒鐘。

開啟 Think-Swoole 服務,訪問注冊的方法,測試一下發送郵件的時間是否計入用戶注冊方法內:

Think-Swoole之Task 異步任務

可見,郵件發送的 3 秒鐘是異步進行的,用戶并無感知。

另外,還有個 swoole.finish 事件,用來通知其他事件當前異步任務已經完成了,同樣需要創建事件,在 app/event.php 中定義 swoole.finish,上述示例代碼已經演示了。

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
亚洲精品久久无码av片俺去也| 99精品热线在线观看免费视频| 亚洲精品日韩中文字幕久久久| 久草热8精品视频在线观看 | 国产精品久久久久aaaa| 久久精品免费电影| 国产精品一久久香蕉国产线看观看| 国产成人精品免费视频大全| 日韩精品电影一区| 中文字幕日韩在线| 日韩精品在线免费观看| 一区二区日韩国产精品| 国产成人精品男人免费| 国产精品视频公开费视频| 精品国产呦系列在线看| 思思99re66在线精品免费观看| 亚洲精品色播一区二区| 国产99久久久国产精品小说| 一级一级特黄女人精品毛片视频| 精品亚洲成a人片在线观看少妇| 日韩av无码久久精品免费| 久久国产精品99久久久久久牛牛 | 四虎精品影院在线观看视频| 亚洲精品无播放器在线播放| 亚洲高清国产拍精品熟女| 国内精品久久久久影院老司| 亚洲色精品VR一区区三区| 亚洲精品天堂无码中文字幕| 久草热8精品视频在线观看| 另类ts人妖精品影院| 热久久精品免费视频| 老司机亚洲精品影院在线观看| 精品久久久久国产| 国产精品免费播放| 中文字幕无码日韩专区| 日韩精品亚洲人成在线观看 | 色妞www精品视频| 在线观看国产精品日韩av| 久久免费精品视频| 久久99精品久久久久麻豆| 久久国产热精品波多野结衣AV|