Swoole, PHP
git clone https://github.com/Watish/WatishWEBcomposer create-project watish/watishweb:dev-masterLe fichier d'entrée du projet est Project /bin/coserver.php
swoole-cli ./bin/CoServer.php php ./bin/CoServer.php
Créez une nouvelle classe dans le répertoire SRC / Controller , nous le définissons ici comme HelloController
<?php
namespace Watish WatishWEB Controller ;
use Watish Components Attribute Path ;
use Watish Components Struct Request ;
class HelloController
{
#[Path( ' / ' )]
public function index ( Request $ request ) : array
{
return [
" msg " => " hello world "
];
}
}Après enregistrer, démarrez le projet et visitez http://127.0.0.1:9502/ pour voir
{ "msg" : " hello world " }N'est-ce pas très simple?
Contrairement à la forme PHP-FPM traditionnelle, il existe une isolation de la mémoire entre plusieurs processus , ce qui signifie que le processus variable B définis par le processus A ne peut pas être récupéré. De plus, la demande n'est pas isolée . C'est-à-dire que deux demandes dans le même processus, bien que la logique de traitement dans différentes coroutines soit traitée, si les deux variables globales a sont modifiées, alors la variable globale sera modifiée deux fois.
Pour plus de détails, veuillez consulter les instructions de programmation dans le document Swoole #Critical Errers
Utilisez des composants Watsish inclut contexte pour éviter efficacement les problèmes ci-dessus
Le contexte est une classe statique qui fournit non seulement des méthodes de Get and Set , mais fournit également GlobalSet, GlobalGet et d'autres méthodes de variables globales de processus multi-travailleurs grâce à la communication de processus.
Remarque: le paramètre de variable global de processus multi-travailleurs (contextuel :: global_set, etc.) est implémenté de manière asynchrone basée sur UnixSocket. Il ne peut garantir la cohérence des données à un certain moment. Ici, vous pouvez utiliser Watsish Components Utils Table , une table de mémoire KV encapsulée pour Swoole Table , qui peut utiliser pleinement chaque ligne de ressources et la sérialisation de fermeture de support.
Lorsque le navigateur envoie une demande au serveur, le serveur appellera la méthode de poignée, puis jugera si la route demandée existe via le planificateur de routage. Les paramètres de routage existent, les encapsuler sur des composants struct struct demandes et les transmettre dans le middleware mondial-> middleware local-> contrôleur
Deux façons d'enregistrer le routage
Remarque: vous devez modifier le ** registre_route_auto ** à true dans ** / config / server.php **
. . .
" register_route_auto " => true
...Prefix est une annotation de classe qui définit le préfixe de l'itinéraire dans cette classe.
#[Prefix(string $ prefix )]Le chemin est une annotation de méthode qui définit le chemin de routage
#[Path(string $ path ,array $ methods )]Prenez un châtaignier:
<?php
namespace Watish WatishWEB Controller ;
use Watish Components Attribute Middleware ;
use Watish Components Attribute Path ;
use Watish Components Attribute Prefix ;
use Watish Components Struct Request ;
use Watish WatishWEB Middleware TestMiddleware ;
#[Prefix( ' /hello ' )]
class HelloController
{
#[Path( ' /index ' )]
public function index ( Request $ request ) : array
{
return [
" msg " => " hello world "
];
}
#[Path( ' /user/{name} ' ,[ ' GET ' , ' POST ' ])]
#[Middleware([TestMiddleware::class])]
public function msg ( Request $ request ) : array
{
return [
" msg " => " hello " . $ request -> route ( ' name ' )
];
}
}Le code ci-dessus est acheminé comme suit
| chemin | Contrôleur | méthode | middleware |
|---|---|---|---|
| / Hello / index | HelloController @ index | N'IMPORTE LEQUEL | aucun |
| / Bonjour / utilisateur / {nom} | HelloController @ msg | Obtenir, poster | TestMiddleware |
Le chemin d'accès vers le fichier de configuration de routage est: project / config / root.php
Réutiliser les châtaignes ci-dessus, alors la configuration de routage ci-dessus doit être la suivante
<?php
use Watish Components Includes Route ;
use Watish WatishWEB Controller HelloController ;
function do_register_global_middleware ( Route $ route ): void
{
/**
$route->register_global_middleware(CorsMiddleware::class);
*/
}
function do_register_routes ( Route $ route ): void
{
$ route -> register ( ' /hello/index ' ,[HelloController::class, ' index ' ],[],[]);
$ route -> register ( ' /hello/user/{name} ' ,[HelloController::class, ' msg ' ],[TestMiddleware: class ],[ ' GET ' , ' POST ' ]);
}Enregistrer les paramètres de transfert de méthode comme suit
Watish Components Includes Route-> register (string $ path , array $ callback , array $ before_middlewares , array $ methods )Remarque: le middleware doit implémenter l'interface middleware
Inscrivez-vous par annotation
Vous pouvez implémenter l'enregistrement mondial du middleware en utilisant des annotations de classe GlobalMiddleware
Par exemple:
<?php
namespace Watish WatishWEB Middleware ;
use Watish Components Attribute GlobalMiddleware ;
use Watish Components Struct Request ;
use Watish Components Struct Response ;
#[GlobalMiddleware]
class CorsMiddleware implements MiddlewareInterface
{
public function handle ( Request $ request , Response $ response ): void
{
$ response -> header ( " Access-Control-Allow-Origin " , " * " );
$ response -> header ( " Access-Control-Allow-Credentials " , true );
}
}Inscrivez-vous par itinéraire
Le chemin du fichier de configuration est: project / config / root.php
<?php
use Watish Components Includes Route ;
use Watish WatishWEB Controller HelloController ;
use Watish WatishWEB Middleware CorsMiddleware ;
function do_register_global_middleware ( Route $ route ): void
{
$ route -> register_global_middleware (CorsMiddleware::class);
}
function do_register_routes ( Route $ route ): void
{
$ route -> register ( ' /hello/index ' ,[HelloController::class, ' index ' ],[],[]);
$ route -> register ( ' /hello/user/{name} ' ,[HelloController::class, ' msg ' ],[],[ ' GET ' , ' POST ' ]);
}Inscrivez-vous par annotation
Vous pouvez utiliser middleware pour annoter un contrôleur ou une méthode
#[Middleware(array $ middlewares )]Créez d'abord un TestMiddleware
<?php
namespace Watish WatishWEB Middleware ;
use Watish Components Struct Request ;
use Watish Components Struct Response ;
class TestMiddleware implements MiddlewareInterface
{
public function handle ( Request $ request , Response $ response )
{
$ response -> header ( " test " , " test " );
}
}Puis modifiez HelloController
<?php
namespace Watish WatishWEB Controller ;
use Watish Components Attribute Middleware ;
use Watish Components Attribute Path ;
use Watish Components Attribute Prefix ;
use Watish Components Struct Request ;
use Watish WatishWEB Middleware TestMiddleware ;
#[Prefix( ' /hello ' )]
class HelloController
{
#[Path( ' /index ' )]
#[Middleware([TestMiddleware::class])]
public function index ( Request $ request ) : array
{
return [
" msg " => " hello world "
];
}
#[Path( ' /user/{name} ' ,[ ' GET ' , ' POST ' ])]
#[Middleware([TestMiddleware::class])]
public function msg ( Request $ request ) : array
{
return [
" msg " => " hello " . $ request -> route ( ' name ' )
];
}
}Comme mentionné ci-dessus, la méthode d'index et la méthode MSG ont un middleware testmware local TestMiddleware
Bien sûr, le code ci-dessus peut être écrit comme celui-ci, et ajouter directement des annotations de middleware à HelloController
<?php
namespace Watish WatishWEB Controller ;
use Watish Components Attribute Middleware ;
use Watish Components Attribute Path ;
use Watish Components Attribute Prefix ;
use Watish Components Struct Request ;
use Watish WatishWEB Middleware TestMiddleware ;
#[Prefix( ' /hello ' )]
#[Middleware([TestMiddleware::class])]
class HelloController
{
#[Path( ' /index ' )]
public function index ( Request $ request ) : array
{
return [
" msg " => " hello world "
];
}
#[Path( ' /user/{name} ' ,[ ' GET ' , ' POST ' ])]
public function msg ( Request $ request ) : array
{
return [
" msg " => " hello " . $ request -> route ( ' name ' )
];
}
}Inscrivez-vous via le fichier de configuration
Reportez-vous à la méthode d'enregistrement de routage des fichiers de configuration dans le paramètre de registre de la section de routage, pas les détails ici
Le contrôleur est au cœur de l'ensemble du projet commercial, responsable du traitement des demandes, de l'appel des services et du rendement des données
Simple, pas de description
Avec l'injection de dépendance , donnez-moi un châtaignier:
<?php
namespace Watish WatishWEB Controller ;
use Watish Components Attribute Inject ;
use Watish Components Attribute Middleware ;
use Watish Components Attribute Path ;
use Watish Components Attribute Prefix ;
use Watish Components Struct Request ;
use Watish WatishWEB Middleware TestMiddleware ;
use Watish WatishWEB Service BaseService ;
#[Prefix( ' /hello ' )]
#[Middleware([TestMiddleware::class])]
class HelloController
{
#[Inject(BaseService::class)]
public BaseService $ baseService ;
#[Path( ' /index ' )]
public function index ( Request $ request ) : array
{
return [
" msg " => $ this -> baseService -> toArray ([ " Hello " , ' World ' ])
];
}
#[Path( ' /user/{name} ' ,[ ' GET ' , ' POST ' ])]
public function msg ( Request $ request ) : array
{
return [
" msg " => " hello " . $ request -> route ( ' name ' )
];
}
}Remarque: L'injection de méthode de construction n'est pas prise en charge pour le moment, et elle sera améliorée à l'avenir (trous creusant)
Code postal directement
<?php
namespace Watish WatishWEB Service ;
use Watish Components Attribute Async ;
use Watish Components Attribute Inject ;
use Watish Components Utils Logger ;
class TestService
{
#[Inject(BaseService::class)]
public BaseService $ baseService ;
#[Async]
public function asyncHello (): void
{
Logger:: info ( " Hello " );
}
public function hello ( string $ name ) : string
{
return " hello { $ name }" ;
}
}En service, l'injection de dépendance peut encore être effectuée. De plus, la méthode peut être annotée asynchrone (notez que la méthode annotée par async
Les fichiers de classe de commande sont stockés dans project / src / commande /
Remarque: la classe de commande nécessite l'interface d'implémentation CommandInterface
Les classes de commande ne peuvent enregistrer que des commandes en utilisant des annotations
L'exemple de code est le suivant:
<?php
namespace Watish WatishWEB Command ;
use Watish Components Attribute Command ;
use Watish Components Utils Logger ;
#[Command( " hello " , " command " )]
class HelloCommand implements CommandInterface
{
public function handle (): void
{
Logger:: info ( " Hello " );
}
}Le code ci-dessus peut être exécuté de la manière suivante
swoole-Cli
swoole-cli ./bin/CoServer.php command:helloPhp
php ./bin/CoServer.php command:hello
Annotation de l'utilisation du commandement
Command (string $ command , string $ prefix = " command " )La classe de tâches est stockée dans Project / Src / Task /
Remarque: toutes les classes de tâches doivent implémenter TaskInterface
La classe de tâches ne prend en charge que l'enregistrement des tâches chronométrées en utilisant l'annotation Crontab .
L'exemple de code est le suivant:
<?php
namespace Watish WatishWEB Task ;
use Watish Components Attribute Crontab ;
use Watish Components Utils Logger ;
#[Crontab( " * * * * * " )]
class HelloTask implements TaskInterface
{
public function execute (): void
{
Logger:: info ( " Hello " , " HelloTask " );
}
}Ceci est une tâche chronométrée qui produit bonjour à chaque seconde
Comment utiliser l'annotation crontab
Crontab (string $ rule )où la règle est une expression de crontab standard
Remarque: il n'y a que mysql pour le moment, redis (peut l'ajouter vous-même)
Ce framework utilise des pools de connexions pour maintenir les connexions MySQL et Redis, et complète la création du pool de connexions au début du démarrage. Maintenant, il suffit d'être utilisé dans la logique des affaires.
** watsish Components inclut database :: mysql () ** renvoie une encapsulation du constructeur de la requête Laravel (modifiant principalement la logique PDO sous-jacente, pas de différence d'utilisation normale)
Watsish Components inclut database :: redis () renvoie un client Predis
Veuillez d'abord configurer la base de données! Fichier de configuration: project / config / database.php
Le cadre utilise les composants suivants et résume certains composants
Sous l'espace de noms de constructeurs Watsish Components , une construction rapide de certains composants est fournie
AsynctaskConstructor :: make () livraison de tâches asynchrones
LocalFileSystemConstructor :: getFileSystem () Constructeur de système de fichiers local
ValidatorConstructor :: Make (Array $ DATA, Array $ règles) Constructeur de validateur
Merci aux excellents développeurs de composants
Environnement de test: Ubuntu22.0.4 LTS
TEST MATÉRIEL: Virtual Machine (VirtualBox) 6C6T, 8192M, Activer la prise en charge de la virtualisation
Outil de test: apachebench
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Server Software: swoole-http-server
Server Hostname: 127.0.0.1
Server Port: 9502
Document Path: /hello/user/test
Document Length: 20 bytes
Concurrency Level: 3000
Time taken for tests: 2.040 seconds
Complete requests: 30000
Failed requests: 0
Total transferred: 7680000 bytes
HTML transferred: 600000 bytes
Requests per second: 14708.19 [#/sec] (mean)
Time per request: 203.968 [ms] (mean)
Time per request: 0.068 [ms] (mean, across all concurrent requests)
Transfer rate: 3677.05 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 83 17.3 85 125
Processing: 32 109 41.6 102 380
Waiting: 0 79 40.0 71 362
Total: 107 193 37.8 189 457
Percentage of the requests served within a certain time (ms)
50% 189
66% 200
75% 205
80% 208
90% 224
95% 236
98% 344
99% 389
100% 457 (longest request)
Remarque: ne faites pas trop attention aux performances. La vraie logique commerciale est souvent compliquée. Les tests de pression sur la démo ne peuvent rien indiquer (images)
S'il est facile à utiliser, vous pouvez cliquer sur une étoile. Si vous avez des questions, veuillez mentionner le problème. L'auteur le maintiendra activement.
Mis à jour le 2022-12-28 16:01
Veuillez exécuter l'installation du compositeur en premier