Maison > cadre php > PensezPHP > Tâche asynchrone Think-Swoole Task

Tâche asynchrone Think-Swoole Task

Libérer: 2020-10-27 13:39:09
avant
3944 Les gens l'ont consulté

Tâche asynchrone Think-Swoole Task

Scénarios d'utilisation

Si vous devez effectuer une opération fastidieuse dans le programme serveur, telle qu'une serveur de chat envoyant Broadcast, envoyez des e-mails depuis le serveur Web. Si vous exécutez ces fonctions directement, le processus en cours sera bloqué, ce qui entraînera une réponse lente du serveur. Par exemple : Scénario d'enregistrement de l'utilisateur, la fonction de finalisation de l'enregistrement et d'envoi d'e-mails d'activation nécessite les étapes suivantes :

Le client soumet les données POST -> Le serveur obtient les données -> ; Envoyer un e-mail d'activation du compte-> Retourner au client pour lui indiquer que l'enregistrement a réussi.

Il n'y a aucun problème avec cette logique métier, mais comme l'envoi d'un e-mail est une opération qui prend du temps (comme 2-3 s) et bloquera de manière synchrone l'exécution du programme jusqu'à ce que le client reçoive une réponse réussie l'inscription une fois l'envoi réussi. Dans ce processus, on estime qu'il faut environ 4 secondes entre la soumission et la notification finale d'enregistrement réussi. Une réponse à une demande prend 4 secondes, ce qui est définitivement déraisonnable !

Désormais, l'utilisation de la livraison de tâches asynchrones peut améliorer considérablement l'expérience utilisateur. Le processus général est le suivant :

Le client soumet les données POST-> Le serveur obtient les données-> écrit les données utilisateur dans la base de données -> Retourne immédiatement au client pour lui indiquer que l'enregistrement a réussi.

Livrer une tâche lorsque l'inscription est réussie -> Terminer l'opération fastidieuse d'envoi de l'e-mail de manière asynchrone (l'utilisateur ignore cette partie du temps car la réponse a été renvoyée au client très tôt).

Étapes pour utiliser la tâche asynchrone Task de Think-Swoole

Définir la classe d'écoute d'événements (php think make:listener class name).

L'écouteur d'événement de swoole.task est défini dans le fichier app/event.php.

Récupérez l'objet Swoole/Server et appelez la méthode task (passez la classe d'écoute qui vient d'être définie dans le paramètre).

Définissez le code logique de rappel du déclencheur dans la méthode handle de la classe d'écoute d'événement qui vient d'être définie.

Appelez la méthode finish qui déclenche la tâche swoole.finish une fois la tâche terminée (appelée uniquement en cas de besoin, pas obligatoire).

Démo

Tout d'abord, créez un événement d'envoi d'e-mail dans le répertoire racine du projet :

php think make:listener EmailTask
Copier après la connexion

Définissez ensuite l'événement d'envoi d'e-mail créé :

app/event.php
'listen'    => [
    'AppInit'  => [],
    'HttpRun'  => [],
    'HttpEnd'  => [],
    'LogLevel' => [],
    'LogWrite' => [],
    'swoole.task' => [
        app\listener\EmailTask::class,
    ],
//  'swoole.finish' => [
//      app\listener\EmailTaskFinish::class,
//  ],
],
Copier après la connexion

Le nom clé de swoole.task est Task. Les tâches sont écrites de manière fixe et ne peuvent pas être nommées arbitrairement.

Ensuite, nous appelons la tâche asynchrone Task via la classe Swoole/Server dans le contrôleur responsable de l'enregistrement des utilisateurs. Bien sûr, nous devons d'abord améliorer le code logique d'EmailTask.php :

app. /lister/EmailTask.php

<?php
declare (strict_types = 1);
namespace app\listener;
class EmailTask
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event)
{
        echo "开始发送邮件:".time();
        //模拟耗时 3 秒,测试是否在响应事件内
        sleep(3);
        echo "邮件发送成功:".time();
        // 可以调用 finish 方法通知其他事件类,通知当前异步任务已经完成了(非必须调用)
        // 参数 $event 是 Swoole\Server\Task 类的一个对象 可以调用 finish 方法触发 task 任务的 onFinish 事件
        // $event -> finish(\app\listener\EmailTaskFinish::class);
    }
}
Copier après la connexion

Méthode d'enregistrement app/controller/Register.php

<?php
namespace app\controller;
use app\BaseController;
class Register extends BaseController
{
    public function register(\Swoole\Server $server)
{
        if($this -> request -> isPost()){
            $data = $this -> request -> post();
            //TODO 调用验证类验证数据
            //TODO 将注册信息插入数据库
            // 这里调用 Task 异步任务
            $server -> task(\app\listener\EmailTask::class);
            // 方式二
//            $manager = app(&#39;\think\swoole\Manager&#39;);
//            $manager -> getServer() -> task(\app\listener\EmailTask::class);
            return "注册成功!".time();
        }
    }
}
Copier après la connexion

Dans le domaine de l'enregistrement, après insertion dans la base de données, la tâche asynchrone d'envoi d'e-mails est appelée, et l'email est simulé dans EmailTask.php Cela prend 3 secondes.

Ouvrez le service Think-Swoole, accédez à la méthode d'inscription et testez si le temps d'envoi des emails est inclus dans la méthode d'inscription de l'utilisateur :

Tâche asynchrone Think-Swoole Task

Vous peut voir que l'email est envoyé. Les 3 secondes sont effectuées de manière asynchrone et l'utilisateur n'en a pas conscience.

De plus, il existe un événement swoole.finish, qui est utilisé pour informer d'autres événements que la tâche asynchrone en cours est terminée. Vous devez également créer un événement et définir swoole.finish dans app/event. php. L'exemple de code ci - dessus a été démontré .

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:阿dai哥
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal