Swoole, PHP
git clone https://github.com/Watish/WatishWEBcomposer create-project watish/watishweb:dev-masterEl archivo de entrada del proyecto es Project /Bin/Coserver.php
swoole-cli ./bin/CoServer.php php ./bin/CoServer.php
Cree una nueva clase en el directorio SRC/controlador , aquí la definimos como 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 "
];
}
}Después de guardar, comience el proyecto y visite http://127.0.0.1:9502/ para ver
{ "msg" : " hello world " }¿No es muy simple?
A diferencia de la forma tradicional de PHP-FPM, existe un aislamiento de memoria entre múltiples procesos , lo que significa que el proceso variable B establecido por el proceso A no puede recuperarse. Además, la solicitud no está aislada . Es decir, dos solicitudes en el mismo proceso, aunque se procesa la lógica de procesamiento en diferentes coroutinas, si se modifican ambas variables globales A, entonces la variable global se modificará dos veces.
Para obtener más detalles, consulte las instrucciones de programación en el documento Swoole #Errores críticos
Use Watish componentes incluye contexto para evitar efectivamente los problemas anteriores
El contexto es una clase estática que no solo proporciona métodos simples de get y establecidos , sino que también proporciona globalset, globalget y otros métodos de variables globales de procesos múltiples a través de la comunicación de procesos.
Nota: la configuración de variables globales del proceso múltiple (context :: Global_set, etc.) se implementa asincrónicamente en función de Unixsocket. No puede garantizar la consistencia de los datos en un momento determinado. Aquí, puede usar Watish Components Utils Table , una tabla de memoria KV encapsulada para Swoole Table , que puede hacer uso completo de cada fila de recursos y soportar la serialización de cierre.
Cuando el navegador envía una solicitud al servidor, el servidor llamará al método de identificación y luego juzgará si la ruta solicitada existe a través del programador de enrutamiento. Existen los parámetros de enrutamiento, los encapsulan a Watish componentes struct solicitud , y los pasan al middleware global-> Middleware local-> controlador
Dos formas de registrar el enrutamiento
Nota: debe modificar el ** Registro_route_auto ** a True en **/config/server.php **
. . .
" register_route_auto " => true
...El prefijo es una anotación de clase que define el prefijo de la ruta bajo esta clase.
#[Prefix(string $ prefix )]La ruta es una anotación del método que define la ruta de enrutamiento
#[Path(string $ path ,array $ methods )]Toma una castaña:
<?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 ' )
];
}
}El código anterior se enruta de la siguiente manera
| camino | Controlador | método | middleware |
|---|---|---|---|
| /hola/índice | HELOCONTROLLER@índice | CUALQUIER | ninguno |
| /hola/user/{nombre} | HELOCONTROLLER@msg | Conseguir, publicar | TestMiddleware |
La ruta al archivo de configuración de enrutamiento es: Project/config/ruta.php
Reutilizar las castañas anteriores, entonces la configuración de enrutamiento anterior debe ser la siguiente
<?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 ' ]);
}Registro de parámetros de transferencia de métodos de la siguiente manera
Watish Components Includes Route-> register (string $ path , array $ callback , array $ before_middlewares , array $ methods )Nota: el middleware debe implementar la interfaz de middleware
Registrarse por anotación
Puede implementar el registro global de middleware utilizando anotaciones de clase GlobalMiddleware
Por ejemplo:
<?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 );
}
}Registrarse por ruta
La ruta del archivo de configuración es: Project/config/ruta.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 ' ]);
}Registrarse por anotación
Puede usar el middleware para anotar un controlador o un método
#[Middleware(array $ middlewares )]Cree un testMiddleware primero
<?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 " );
}
}Luego modifique el 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 ' )
];
}
}Como se mencionó anteriormente, el método de índice y el método MSG tienen middleware testMiddleware local
Por supuesto, el código anterior se puede escribir así y agregar directamente anotaciones de middleware a 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 ' )
];
}
}Regístrese a través del archivo de configuración
Consulte el método de registro de enrutamiento del archivo de configuración en el parámetro de registro de la sección de enrutamiento, no los detalles aquí
El controlador es el núcleo de todo el proyecto comercial, responsable de las solicitudes de procesamiento, los servicios de llamadas y los datos de devolución
Simple, sin descripción
Junto con la inyección de dependencia , dame una castaña:
<?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 ' )
];
}
}Nota: La inyección del método de construcción no es compatible con el momento, y se mejorará en el futuro (agujeros de excavación)
Código de publicación directamente
<?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 el servicio, la inyección de dependencia aún se puede realizar. Además, el método puede ser anotado por Async (tenga en cuenta que el método anotado por async debe ser de tipo nulo) para que sea un método asíncrono
Los archivos de clase de comandos se almacenan en Project/SRC/Command/
Nota: La clase de comando requiere la interfaz de Insteming Commandinterface
Las clases de comandos solo pueden registrar comandos usando anotaciones
El código de muestra es el siguiente:
<?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 " );
}
}El código anterior se puede ejecutar de las siguientes maneras
cli de agua
swoole-cli ./bin/CoServer.php command:helloPhp
php ./bin/CoServer.php command:hello
Anotación del uso del mando
Command (string $ command , string $ prefix = " command " )La clase de tareas se almacena en Project/SRC/Task/
Nota: Todas las clases de tareas deben implementar TaskInterface
La clase de tareas solo admite el registro de tareas cronometradas utilizando la anotación CRONTAB .
El código de muestra es el siguiente:
<?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 " );
}
}Esta es una tarea cronometrada que genera hola cada segundo
Cómo usar la anotación crontab
Crontab (string $ rule )donde la regla es una expresión de crontab estándar
Nota: Solo hay mysql por el momento, Redis (puede agregarlo usted mismo)
Este marco utiliza grupos de conexión para mantener las conexiones MySQL y Redis, y completa la creación del grupo de conexión al comienzo de la inicio. Ahora solo necesita ser utilizado en la lógica de negocios.
** watish componentes Incluye database :: mysql () ** Devuelve una encapsulación del constructor de consultas Laravel (principalmente cambiando la lógica PDO subyacente, sin diferencias en el uso normal)
Watish componentes Incluye database :: redis () Devuelve un cliente Predis
¡Configure primero la base de datos! Archivo de configuración: Project/config/database.php
El marco utiliza los siguientes componentes y encapsula algunos componentes
Bajo el espacio de nombres Watish Component Constructor , se proporciona una construcción rápida de algunos componentes
AsyncTaskConstructor :: Make () Entrega de tareas asíncronas
LocalFilesystemConstructor :: GetFilesystem () Constructor del sistema de archivos local
ValidatorConstructor :: Make (matriz $ datos, matriz $ reglas) Constructor de validador
Gracias a los excelentes desarrolladores de componentes
Entorno de prueba: Ubuntu22.0.4 LTS
Hardware de prueba: Virtual Machine (Virtualbox) 6C6T, 8192m, habilita el soporte de virtualización
Herramienta de prueba: 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)
Nota: No preste demasiada atención al rendimiento. La lógica comercial real a menudo es complicada. Las pruebas de presión en la demostración no pueden indicar nada (imágenes)
Si es fácil de usar, puede hacer clic en una estrella. Si tiene alguna pregunta, mencione el problema. El autor lo mantendrá activamente.
Actualizado el 2022-12-28 16:01
Ejecute la instalación del compositor primero