Swoole, Php
git clone https://github.com/Watish/WatishWEBcomposer create-project watish/watishweb:dev-masterO arquivo de entrada do projeto é o Project /bin/coserver.php
swoole-cli ./bin/CoServer.php php ./bin/CoServer.php
Crie uma nova classe no diretório SRC/Controller , aqui a 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 "
];
}
}Depois de salvar, inicie o projeto e visite http://127.0.0.1:9502/ para ver
{ "msg" : " hello world " }Não é muito simples?
Diferentemente da forma tradicional PHP-FPM, há isolamento de memória entre vários processos , o que significa que o processo variável B definido pelo processo A não pode ser recuperado. Além disso, a solicitação não está isolada . Ou seja, duas solicitações sob o mesmo processo, embora a lógica de processamento em diferentes coroutinas seja processada, se ambas as variáveis globais A forem modificadas, a variável global será modificada duas vezes.
Para detalhes, consulte as instruções de programação no documento SWOOOLE #Erros Críticos
Use Watish Components Inclui Context para evitar efetivamente os problemas acima
O contexto é uma classe estática que não apenas fornece métodos simples de obter e definir , mas também fornece globalset, globalget e outros métodos de variáveis globais de processo de vários trabalhadores por meio da comunicação do processo.
Nota: O processo de variável global do processo de vários trabalhadores (contexto :: global_set, etc.) é implementado de forma assíncrona baseada no UnixSocket. Não pode garantir a consistência dos dados em um determinado momento. Aqui, você pode usar a tabela Watish Components Utils , uma tabela de memória KV encapsulada para a tabela Swoole , que pode fazer pleno uso de cada linha de recursos e serialização de fechamento de suporte.
Quando o navegador envia uma solicitação para o servidor, o servidor chama o método Handle e, em seguida, julgará se a rota solicitada existe através do agendador de roteamento. Os parâmetros de roteamento existem, encapsulam-os para os componentes struct struct e passam para o middleware global-> Middleware local-> controlador
Duas maneiras de registrar o roteamento
Nota: Você precisa modificar o ** registr_route_auto ** para true em **/config/server.php **
. . .
" register_route_auto " => true
...O prefixo é uma anotação de classe que define o prefixo da rota nesta classe.
#[Prefix(string $ prefix )]O caminho é uma anotação de método que define o caminho de roteamento
#[Path(string $ path ,array $ methods )]Pegue uma castanha:
<?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 ' )
];
}
}O código acima é roteado da seguinte forma
| caminho | Controlador | método | middleware |
|---|---|---|---|
| /olá/índice | Hellocontroller@index | QUALQUER | nenhum |
| /hello/user/{name} | Hellocontroller@msg | Obtenha, poste | Testmiddleware |
O caminho para o arquivo de configuração de roteamento é: Project/config/route.php
Reutilizar as castanhas acima, então a configuração de roteamento acima deve ser a seguinte
<?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 ' ]);
}Registrar o método de transferência de parâmetros da seguinte maneira
Watish Components Includes Route-> register (string $ path , array $ callback , array $ before_middlewares , array $ methods )Nota: o middleware deve implementar a interface do middleware
Registre -se por anotação
Você pode implementar o registro global de middleware usando anotações da classe GlobalMiddleware
Por exemplo:
<?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 );
}
}Registre -se via rota
O caminho do arquivo de configuração é: Project/config/route.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 ' ]);
}Registre -se por anotação
Você pode usar o middleware para anotar um controlador ou um método
#[Middleware(array $ middlewares )]Crie um testmiddleware primeiro
<?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 " );
}
}Em seguida, modifique o 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 mencionado acima, o método do índice e o método MSG têm middleware local testmiddleware
Obviamente, o código acima pode ser escrito assim e adicione diretamente anotações de middleware ao 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 ' )
];
}
}Registre -se via arquivo de configuração
Consulte o método de registro de roteamento de arquivos de configuração no parâmetro Registro da seção de roteamento, não detalhes aqui
O controlador é o núcleo de todo o projeto de negócios, responsável por processar solicitações, serviços de chamada e dados de retorno
Simples, sem descrição
Juntamente com a injeção de dependência , me dê uma castanha:
<?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: A injeção do método de construção não é suportada por enquanto, e será melhorada no futuro (cavando orifícios)
Código de postagem diretamente
<?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 }" ;
}
}Em serviço, a injeção de dependência ainda pode ser realizada. Além disso, o método pode ser anotado assíncrono (observe que o método anotado pelo assíncrono deve ser do tipo vazio) para torná -lo um método assíncrono
Os arquivos da classe de comando são armazenados no projeto/src/comando/
Nota: A classe de comando requer a interface de comando de comando implementar
As classes de comando podem apenas registrar comandos usando anotações
O código de amostra é o seguinte:
<?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 " );
}
}O código acima pode ser executado das seguintes maneiras
Swoole-cli
swoole-cli ./bin/CoServer.php command:helloPhp
php ./bin/CoServer.php command:hello
Anotação do uso do comando
Command (string $ command , string $ prefix = " command " )A classe de tarefas é armazenada no projeto/src/tarefa/
NOTA: Todas as classes de tarefas precisam implementar o TaskInterface
A classe de tarefas suporta apenas o registro de tarefas cronometradas usando a anotação Crontab .
O código de amostra é o seguinte:
<?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 é uma tarefa cronometrada que gera olá a cada segundo
Como usar a anotação de Crontab
Crontab (string $ rule )Onde a regra é uma expressão padrão de Crontab
Nota: Existe apenas o MySQL por enquanto, Redis (pode adicioná -lo)
Essa estrutura usa pools de conexão para manter as conexões MySQL e Redis e conclui a criação do pool de conexões no início da startup. Agora ele só precisa ser usado na lógica de negócios.
** watish componentes inclui database :: mysql () ** retorna um encapsulamento do construtor de consultas do Laravel (principalmente alterando a lógica de PDO subjacente, sem diferença no uso normal)
Watish componentes inclui database :: redis () retorna um cliente predis
Configure o banco de dados primeiro! Arquivo de configuração: Project/config/database.php
A estrutura usa os seguintes componentes e encapsula alguns componentes
Sob o espaço para nome do construtor componentes de Watish , uma construção rápida de alguns componentes é fornecida
AsyncTaskConstructor :: make () entrega de tarefas assíncronas
LocalFilesystemConstructor :: GetFilesystem () Construtor de sistema de arquivos local
ValidatorConstructor :: Make (Array $ Data, Array $ Regras) Construtor de validador
Graças aos excelentes desenvolvedores de componentes
Ambiente de teste: Ubuntu22.0.4 LTS
Hardware de teste: Máquina Virtual (VirtualBox) 6C6T, 8192M, Ativar suporte à virtualização
Ferramenta de teste: 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: Não preste muita atenção ao desempenho. A verdadeira lógica de negócios é frequentemente complicada. O teste de pressão na demonstração não pode indicar nada (imagens)
Se for fácil de usar, você pode clicar em uma estrela. Se você tiver alguma dúvida, mencione o problema. O autor o manterá ativamente.
Atualizado em 2022-12-28 16:01
Por favor, execute o compositor de instalação primeiro