Patrocinador
Você precisa garantir que o ambiente operacional atenda aos seguintes requisitos:
composer create-project api-swoole/skeleton
Suporta serviço HTTP, serviço WebSocket, serviço tcp e executa comandos no diretório raiz do projeto ./apiswoole.php
.
php apiswoole.php
Na estrutura api-swoole, o código comercial principal está no diretório app. Cada namespace dentro corresponde a um subdiretório. O namespace padrão do projeto é App. Depois que o projeto é criado, o diretório app contém três subdiretórios: Common, Sample e Ext. e Ext geralmente coloca ferramentas, etc. A estrutura do diretório é a seguinte:
./
└── app
├── Example # 放置接口源代码,相当于控制器层
├── Common # 公共代码目录,
└── Ext# 放置工具等
Quando o projeto precisar adicionar uma nova interface, primeiro crie um novo arquivo hello.php
no diretório ./app/Example
e edite o código com um editor.
<?php
namespace AppExample;
use SapiApi;
class Hello extends Api
{
public function index()
{
return [
'code' => 200,
'data' => [
'name' => 'api-swoole',
'version' => DI()->config->get('conf.version'),
],
];
}
}
Defina a rota do projeto no arquivo de roteamento route/http.php
@
primeiro parâmetro é o endereço de acesso do navegador definido. A primeira metade do segundo parâmetro @
é o namespace completo do arquivo. no método de classe.
return [
HttpRouter("/hello", "AppExampleHello@index"),
];
Execute o seguinte comando no diretório raiz do projeto para iniciar no modo não daemon.
php apiswoole.php
Por padrão, ele escuta o HTTP local e a porta websocket 9501. As informações de saída a seguir aparecem no cmd para indicar que o projeto foi iniciado com sucesso.
[Success] Swoole: 4.5.9, PHP: 7.4.13, Port: 9501
[Success] Swoole Http Server running:http://0.0.0.0:9501
[Success] Swoole websocket Server running:ws://0.0.0.0:9501
[Success] Swoole tcp Server running:0.0.0.0:9500
[Success] Swoole udp Server running:0.0.0.0:9502
Insira o endereço de roteamento definido na barra de endereço do navegador e o endereço consiste em http://ip网址:端口/定义的路由
.
http://127.0.0.1:9501/hello
Os dados retornados após uma solicitação bem-sucedida são retornados no formato JSON por padrão, incluindo o código padrão, a mensagem e os campos de dados. Os dados em data são os dados retornados no método.
{
"code" : 200 ,
"msg" : " success " ,
"data" : {
"code" : 200 ,
"data" : {
"name" : " api-swoole " ,
"version" : " 1.0.2 "
}
},
"debug" : []
}
Como o suporte do HttpServer
para o protocolo HTTP
é incompleto, é recomendado usá-lo apenas como um servidor de aplicativos para lidar com solicitações dinâmicas e adicionar Nginx
como proxy no front-end. (endereço de referência)
server {
listen 80;
server_name swoole.test;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:9501;
}
}
Você pode obter o IP
real do cliente lendo $request->header['x-real-ip']
A pasta de configuração padrão contém três arquivos: conf.php, db.php e events.php. conf.php coloca as informações de configuração do projeto, incluindo http, tcp, udp, websocket e outras configurações. db.php é responsável por configurar conexões MySQL e Redis, e events.php é responsável por definir e personalizar o registro e monitoramento de eventos específicos. Ele agora oferece suporte ao registro de eventos workerStart、open、close、task、finish
. As informações de configuração podem ser lidas por meio de DI()->config->get('conf.ws')
ou SapiDi::one()->config->get('conf.ws')
.
./config/
├── conf.php #http、tcp、udp、websocket等配置
├── db.php #数据库配置
└── events.php #定制特定事件注册监听
<?php
return [
'version' => '1.0.2',
'debug' => true,//调试模式
'log' => [
'displayConsole' => true,//true控制台打印日志
'saveLog' => true,//保存日志
],
'udp' => [
'host' => '0.0.0.0',
'port' => 9502,
'sockType' => SWOOLE_SOCK_UDP,
'events' => [
['packet', AppExampleUdpServe::class, 'onPacket'],
],
'settings' => [],
],
'tcp' => [
'host' => '0.0.0.0',
'port' => 9501,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['Receive', AppExampleTcpServe::class, 'onReceive'],
['connect', AppExampleTcpServe::class, 'onConnect'],
['close', AppExampleTcpServe::class, 'onClose'],
],
'settings' => [],
],
'ws' => [
'host' => '0.0.0.0',
'port' => 9500,
'events' => [
['open', SapiEvents::class, 'onOpen'],
['message', SapiEvents::class, 'onMessage'],
['close', SapiEvents::class, 'onClose'],
['request', SapiEvents::class, 'onRequest'],
['Task', SapiEvents::class, 'onTask'],
['Finish', SapiEvents::class, 'onFinish'],
['workerStart', SapiEvents::class, 'onWorkerStart'],
['start', SapiEvents::class, 'onStart'],
],
'settings' => [
'daemonize' => false,//设置 daemonize => true 时,程序将转入后台作为守护进程运行。长时间运行的服务器端程序必须启用此项。如果不启用守护进程,当 ssh 终端退出后,程序将被终止运行
// 'dispatch_mode' => 2,//数据包分发策略。【默认值:2】
'worker_num' => swoole_cpu_num(),
'log_file' => 'storage/swoole',
'log_rotation' => SWOOLE_LOG_ROTATION_DAILY,
'log_date_format' => '%Y-%m-%d %H:%M:%S',
'log_level' => SWOOLE_LOG_DEBUG,
'task_worker_num' => 10,
'enable_coroutine' => true,//是否启用异步风格服务器的协程支持
// 'buffer_output_size' => 32 * 1024 * 1024, //配置发送输出缓存区内存尺寸。【默认值:2M】
// 'document_root' => ROOT_PATH,
// 'enable_static_handler' => true,//开启静态文件请求处理功能
// 'static_handler_locations' => ['/chatroom', '/app/images'],//设置静态处理器的路径。类型为数组,默认不启用。
],
// SWOOLE_LOG_DEBUG 调试日志,仅作为内核开发调试使用
// SWOOLE_LOG_TRACE 跟踪日志,可用于跟踪系统问题,调试日志是经过精心设置的,会携带关键性信息
// SWOOLE_LOG_INFO 普通信息,仅作为信息展示
// SWOOLE_LOG_NOTICE 提示信息,系统可能存在某些行为,如重启、关闭
// SWOOLE_LOG_WARNING 警告信息,系统可能存在某些问题
// SWOOLE_LOG_ERROR 错误信息,系统发生了某些关键性的错误,需要即时解决
// SWOOLE_LOG_NONE 相当于关闭日志信息,日志信息不会抛出
],
'process' => [
[AppExampleProcess::class, 'addProcess']
],//添加用户自定义的工作进程
];
O serviço foi registrado por padrão em apiswoole.php
quando o projeto é iniciado.
$di = DI();
$di->config = new Config("./config");
Por exemplo, as informações de configuração são conf.php e a estrutura é:
return [
'debug' => true,//调试模式
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', AppControllerTcpServe::class, 'onReceive'],
],
'settings' => [],
],
]
Você pode usar DI()->config->get('conf.tcp')
para ler o arquivo de configuração
DI()->config->get('conf.tcp') #返回数组
Retorna uma estrutura de dados de array:
{
"host" : " 0.0.0.0 " ,
"port" : 9500 ,
"sockType" : 1 ,
"events" : [
[
" receive " ,
" App \ Controller \ TcpServe " ,
" onReceive "
]
],
"settings" : []
}
A interface de log é definida detalhadamente de acordo com a especificação PSR. Os logs são registrados no diretório ./storage/log
e日期.log
são gerados diariamente. Atualmente, os seguintes tipos de registro são suportados:
O sistema de registro usa:
DI()->logger->debug("日志测试debug"); #开发调试类日记
DI()->logger->info("日志测试info"); #业务纪录类日记
DI()->logger->notice("日志测试notice");#系统提示类日记
DI()->logger->waring("日志测试waring");#系统致命类日记
DI()->logger->error("日志测试error"); #系统异常类日记
O log correspondente no diretório ./storage/log/20220906.log
:
[swoole] | [2022-09-06 01:32:05] | debug | 日志测试debug
[swoole] | [2022-09-06 01:32:05] | info | 日志测试info
[swoole] | [2022-09-06 01:32:05] | notice | 日志测试notice
[swoole] | [2022-09-06 01:32:05] | warning | 日志测试waring
[swoole] | [2022-09-06 01:32:05] | error | 日志测试error
WebSocketServer
herda de HttpServer, portanto, todas API
e itens de configuração fornecidos por HttpServer
podem ser usados. Consulte o capítulo HttpServer.
WebSocketServer
também pode servir como um servidor HTTP
ao mesmo tempo.WebSocketServer
retornará uma página de erro HTTP 400
após receber a solicitação HTTP
. Se você deseja apenas implementar o servidor websocket, exclua ['request', SapiEvents::class, 'onRequest']
na configuração ./config/conf.php
.
As opções de configuração do servidor HTTP/websocket estão em ./config/conf.php
. Para obter informações de configuração específicas, consulte as opções de configuração do documento Swoole.
<?php
return [
'ws' => [
'host' => '0.0.0.0',//监听地址
'port' => 9501,//监听端口
'events' => [
['open', SapiEvents::class, 'onOpen'],
['message', SapiEvents::class, 'onMessage'],
['close', SapiEvents::class, 'onClose'],
['request', SapiEvents::class, 'onRequest'],//HTTP服务器回调
['Task', SapiEvents::class, 'onTask'],
['Finish', SapiEvents::class, 'onFinish'],
['workerStart', SapiEvents::class, 'onWorkerStart'],
['start', SapiEvents::class, 'onStart'],
],//回调函数
'settings' => [
'daemonize' => false,//设置 daemonize => true 时,程序将转入后台作为守护进程运行。长时间运行的服务器端程序必须启用此项。如果不启用守护进程,当 ssh 终端退出后,程序将被终止运行
'worker_num' => swoole_cpu_num(),
'log_file' => 'storage/swoole',
'log_rotation' => SWOOLE_LOG_ROTATION_DAILY,
'log_date_format' => '%Y-%m-%d %H:%M:%S',
'log_level' => SWOOLE_LOG_DEBUG,
'task_worker_num' => 10,
],
],
];
O arquivo de construção de rota para o servidor HTTP está localizado em ./route/http.php
. Declare regras de roteamento específicas. O primeiro parâmetro é o endereço de acesso do navegador definido. A primeira metade do @
parâmetro @
é o namespace completo do arquivo.
return [
HttpRouter("/", "AppExampleApp@Index"),
HttpRouter("/hello", "AppExampleHello@index"),
HttpRouter("声明浏览器地址", "命名空间+类@类中的方法"),
];
O endereço URL completo consiste em http://ip网址:端口/定义的路由
.
Construir uma rota básica requer apenas um URI e um闭包
, fornecendo uma maneira muito simples de definir rotas:
return [
HttpRouter("/", function (SwooleHttpRequest $request, SwooleHttpResponse $response) {
return [
"code" => 200,
"msg" => "hello World!",
'tm' => date('Y-m-d H:i:s'),
"data" => [
'name' => 'api-swoole',
'version' => DI()->config->get('conf.version'),
],
];
}),
];
O método do controlador correspondente tem dois parâmetros, $request
e $reponse
, por padrão. Para uma introdução completa aos objetos Request e Response, consulte a documentação do Swoole: HttpRequest, HttpResponse.
<?php
namespace AppController;
use SapiApi;
class Hello extends Api
{
public function index()
{
return [
'code' => 200,
'data' => 'hello world'
];
}
}
As regras de parâmetros de interface são implementadas herdando a classe Api
, e regras de definição específicas são implementadas por meio rule()
.
name
corresponde ao valor passado pelo clienterequire
indica que o valor é passado como uma opção, true
deve ser passado false
deve ser passado.type
, suporta int
, string
, float
, bool
, array
, file
source
é passado para o local e suporta get
, post
e header
message
<?php
namespace AppExample;
use SapiApi;
//字段验证
class App extends Api
{
public function rule()
{
return [
'Index' => [
'intValue' => ['name' => 'intValue', 'require' => true, 'type' => 'int', 'source' => 'post', 'message' => 'intValue必须携带'],
'stringValue' => ['name' => 'stringValue', 'require' => true, 'type' => 'string', 'source' => 'post', 'message' => 'stringValue必须携带'],
'floatValue' => ['name' => 'floatValue', 'require' => true, 'type' => 'float', 'source' => 'post', 'message' => 'floatValue是必须的'],
'boolValue' => ['name' => 'boolValue', 'require' => true, 'type' => 'bool', 'source' => 'post', 'message' => 'boolValue是必须的'],
'arrayValue' => ['name' => 'arrayValue', 'require' => true, 'type' => 'array', 'source' => 'post', 'message' => 'arrayValue是必须的'],
'file' => ['name' => 'file', 'require' => false, 'type' => 'file', 'ext' => 'jpeg,png,txt', 'source' => 'post', 'message' => 'file文件是必须的'],
'x-token' => ['name' => 'x-token', 'require' => true, 'type' => 'string', 'source' => 'header', 'message' => '缺少请求头x-token'],
]
];
}
public function Index(SwooleHttpRequest $request, SwooleHttpResponse $response): array
{
return [
"code" => 200,
"msg" => "hello World!",
'tm' => date('Y-m-d H:i:s'),
"data" => [
'name' => 'api-swoole',
'version' => DI()->config->get('conf.version'),
'intValue' => $request->post['intValue'],
'stringValue' => $request->post['stringValue'],
'floatValue' => $request->post['floatValue'],
'boolValue' => $request->post['boolValue'],
'arrayValue' => $request->post['arrayValue'],
'x-token' => $request->header['x-token'],
'file' => saveFile($request, './tmp/')
],
];
}
}
O arquivo de definição de rota do servidor websocket está localizado em ./route/websocket.php
. Declare regras de roteamento específicas. O primeiro parâmetro é o endereço de acesso do navegador definido. A primeira metade do @
parâmetro @
é o namespace completo do arquivo.
return [
WsRouter("/", "AppExampleWebsocket@index"),
WsRouter("/login", "AppExampleWebsocket@login"),
];
O endereço URL completo consiste em ws://ip网址:端口
.
O método do controlador correspondente possui dois parâmetros $server
e $msg
, por padrão. Para uma introdução completa ao objeto $server
, consulte a documentação do Swoole: WebSocketServer. $msg
são as informações de dados enviadas pelo cliente.
As informações de dados enviadas pelo cliente precisam ser transmitidas em formato json por padrão e devem conter os três campos id, caminho e dados.
id
é o identificador exclusivo do corpo da mensagem.path
é o endereço de acesso declarado pela rota ./route/websocket.php
.data
é o parâmetro de mensagem específico do projeto e o método de controle padrão é $msg
. {
"id" : " 918wsEMQDrj0RXxm " ,
"path" : " / " ,
"data" : {
"username" : " api-swoole "
}
}
Exemplo de seção de código do controlador:
<?php
namespace AppExample;
use SapiApi;
class WebsocketHello extends Api
{
public function hello(SwooleWebSocketServer $server, array $msg): array
{
return [
'err' => 200,
'data' => [
'name' => 'api-swoole',
'version' => DI()->config->get('conf.version'),
]
];
}
}
As regras de parâmetros de interface são implementadas herdando a classe Api
, e regras de definição específicas são implementadas por meio rule()
.
name
corresponde ao valor passado pelo clienterequire
indica que o valor é passado como uma opção, true
deve ser passado false
deve ser passado.type
tipo, suporta int
, string
, float
, bool
, array
message
<?php
namespace AppExample;
class Websocket extends WsBase
{
public function rule()
{
return [
'Index' => [
'intValue' => ['name' => 'intValue', 'require' => true, 'type' => 'int', 'message' => 'intValue必须携带'],
'stringValue' => ['name' => 'stringValue', 'require' => true, 'type' => 'string', 'message' => 'stringValue必须携带'],
'floatValue' => ['name' => 'floatValue', 'require' => true, 'type' => 'float', 'message' => 'floatValue是必须的'],
'boolValue' => ['name' => 'boolValue', 'require' => true, 'type' => 'bool', 'message' => 'boolValue是必须的'],
'arrayValue' => ['name' => 'arrayValue', 'require' => true, 'type' => 'array', 'message' => 'arrayValue是必须的'],
'x-token' => ['name' => 'x-token', 'require' => true, 'type' => 'string', 'message' => '缺少请求头x-token'],
]
];
}
public function Index(SwooleWebSocketServer $server, array $msg): array
{
return [
'err' => 200,
'data' => [
'intValue' => $msg['intValue'],
'stringValue' => $msg['stringValue'],
'floatValue' => $msg['floatValue'],
'boolValue' => $msg['boolValue'],
'arrayValue' => $msg['arrayValue'],
'x-token' => $msg['x-token'],
]
];
}
}
A classe Api
possui uma função de gancho integrada userCheck
e todos os controladores HTTP podem herdar a sobrecarga da classe Api
. Por exemplo, a autenticação do usuário pode ser realizada.
Primeiro defina o arquivo de declaração HttpBase.php
.
<?php
namespace AppExample;
use SapiApi;
class HttpBase extends Api
{
//用户权限验证
public function userCheck(SwooleHttpRequest $request): string
{
if ($request->header["x-token"] != "123123") {
return "token过期";
}
return "";
}
}
Em seguida, herde HttpBase.php
para implementar a sobrecarga de classe.
<?php
namespace AppExample;
class Auth extends HttpBase
{
public function rule()
{
return [
'login' => [
'username' => ['name' => 'username', 'require' => true, 'type' => 'string', 'source' => 'post', 'message' => '必须携带username'],
]
];
}
public function login(SwooleHttpRequest $request, SwooleHttpResponse $response): array
{
return [
"code" => 200,
"msg" => "login",
"data" => [
'username' => $request->post['username']
]
];
}
}
A classe Api
possui uma função de gancho integrada userWsCheck
e todos os controladores de websocket podem herdar Api
. Por exemplo, a autenticação do usuário pode ser realizada.
Primeiro defina o arquivo de declaração WsBase.php
.
<?php
namespace AppExample;
use SapiApi;
class WsBase extends Api
{
public function userWsCheck(SwooleWebSocketFrame $frame): string
{
$res = json_decode($frame->data, true);
if (!isset($res['data']["x-token"]) || $res['data']["x-token"] != "123123") {
return "token expired";
}
return "";
}
}
Em seguida, herde WsBase.php
para implementar a sobrecarga de classe.
<?php
namespace AppExample;
class Websocket extends WsBase
{
public function rule()
{
return [
'Index' => [
'intValue' => ['name' => 'intValue', 'require' => true, 'type' => 'int', 'message' => 'intValue必须携带'],
'stringValue' => ['name' => 'stringValue', 'require' => true, 'type' => 'string', 'message' => 'stringValue必须携带'],
'floatValue' => ['name' => 'floatValue', 'require' => true, 'type' => 'float', 'message' => 'floatValue是必须的'],
'boolValue' => ['name' => 'boolValue', 'require' => true, 'type' => 'bool', 'message' => 'boolValue是必须的'],
'arrayValue' => ['name' => 'arrayValue', 'require' => true, 'type' => 'array', 'message' => 'arrayValue是必须的'],
'x-token' => ['name' => 'x-token', 'require' => true, 'type' => 'string', 'message' => '缺少请求头x-token'],
]
];
}
public function Index(SwooleWebSocketServer $server, array $msg): array
{
return [
'err' => 200,
'data' => [
'intValue' => $msg['intValue'],
'stringValue' => $msg['stringValue'],
'floatValue' => $msg['floatValue'],
'boolValue' => $msg['boolValue'],
'arrayValue' => $msg['arrayValue'],
'x-token' => $msg['x-token'],
]
];
}
}
Server
pode escutar várias portas e cada porta pode ser configurada para lidar com protocolos diferentes. Por exemplo, a porta 80 lida com o protocolo HTTP, a porta 9500 lida com o protocolo TCP e a porta 9502 lida com o protocolo UDP. A criptografia de transporte SSL/TLS
também pode ser habilitada apenas para portas específicas. Consulte a documentação oficial do Swoole (monitoramento multiporta)
As opções de configuração do servidor TCP adicionam o campo tcp em ./config/conf.php
. Para obter informações de configuração específicas, consulte o documento Swoole Configuração TCP.
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', AppControllerTcpServe::class, 'onReceive'],//TCP服务器回调
],
'settings' => [],
],
As opções de configuração do servidor UDP adicionam o campo udp em ./config/conf.php
. Para obter informações de configuração específicas, consulte o documento Swoole Configuração UDP.
'udp' => [
'host' => '0.0.0.0',
'port' => 9502,
'sockType' => SWOOLE_SOCK_UDP,
'events' => [
['packet', AppControllerUdpServe::class, 'onPacket'],//UDP服务器回调
],
'settings' => [],
],
A equipe de desenvolvimento do Swoole usa a função PHP nativa do Hook para implementar o cliente da corrotina. Com uma linha de código, o código IO síncrono original pode ser transformado em IO assíncrono que pode ser agendado pela corrotina, ou seja, corrotinação com um clique. Os clusters da classe SwooleServer fornecidos pelo Swoole
são criados automaticamente e não precisam ser feitos manualmente. Consulte enable_coroutine. Para conteúdo específico, consulte o site oficial do Swoole para corrotinização com um clique.
O banco de dados da estrutura apresenta o pacote de expansão de terceiros simple-swoole
. Para obter detalhes, consulte simple-swoole/db.
As opções de configuração do servidor Redis estão em ./config/db.php
.
<?php
return [
'redis' => [
'host' => '192.168.0.105',//Redis服务器地址
'port' => 6379,//指定 Redis 监听端口
'auth' => '',//登录密码
'db_index' => 2,//指定数据库
'time_out' => 1,//
'size' => 64,//连接池数量
],
];
Usando Redis no projeto
<?php
namespace AppController;
use AppExtRedis;
class RedisDemo
{
public function setData(SwooleHttpRequest $request, SwooleHttpResponse $response)
{
$redis = new SimpsDBBaseRedis();
$res = $redis->set('我是key', '我是value');
return [
"code" => 200,
"msg" => "hello World!",
"data" => [
'res' => $res,
'key' => $request->get['key'],
'val' => $request->get['val'],
],
];
}
}
As opções de configuração do servidor MySQL estão em ./config/db.php
.
<?php
return [
'mysql' => [
'host' => '',//连接地址
'port' => ,//连接端口
'database' => '',//数据库名称
'username' => 'root',//用户
'password' => '',//密码
'charset' => 'utf8',//字符集
'unixSocket' => null,//
'options' => [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
'size' => 64 // 连接池数量
],
];
./app/Ext/Pool.php
configura o pool de conexões:
<?php
namespace AppExt;
use SapiSingleton;
use SimpsDBPDO;
use SimpsDBRedis;
class Pool
{
use Singleton;
public function startPool(...$args)
{
$mysql_config = DI()->config->get('db.mysql');
if (!empty($mysql_config)) {
PDO::getInstance($mysql_config);
}
$redis_config = DI()->config->get('db.redis');
if (!empty($redis_config)) {
Redis::getInstance($redis_config);
}
}
}
simple-swoole
integra a estrutura de banco de dados PHP leve Medoo. Você precisa herdar SimpsDBBaseModel
ao usá-lo, então o método de uso é basicamente o mesmo do Medoo.
A única diferença são as operações relacionadas à transação. No Medoo, action( $callback )
é usado, mas nesta estrutura, action( $callback )
também pode ser usado.
beginTransaction(); // 开启事务
commit(); // 提交事务
rollBack(); // 回滚事务
Exemplo de transação
$this->beginTransaction();
$this->insert("user", [
"name" => "luffy",
"gender" => "1"
]);
$this->delete("user", [
"id" => 2
]);
if ($this->has("user", ["id" => 23]))
{
$this->rollBack();
} else {
$this->commit();
}
Usado no projeto, estrutura da tabela do banco de dados:
CREATE TABLE `user_info` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`nick` varchar(15) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8;
<?php
namespace AppController;
class MysqlDemo
{
public function getOne(SwooleHttpRequest $request, SwooleHttpResponse $response)
{
$uid = $request->post['uid'];
$database = new SimpsDBBaseModel();
$res = $database->select("user_info", [
"uid",
"nick",
], [
"uid" => $uid
]);
return [
"code" => 200,
"msg" => "MysqlDemo getOne",
"data" => [
'res' => $res,
'uid' => $uid,
],
];
}
public function save(SwooleHttpRequest $request, SwooleHttpResponse $response)
{
$username = $request->post['username'];
$database = new SimpsDBBaseModel();
$last_user_id = $database->insert("user_info", [
"uid" => time(),
"nick" => $username,
]);
return [
"code" => 200,
"msg" => "MysqlDemo save",
"data" => [
'last_user_id' => $last_user_id,
'username' => $username,
],
];
}
public function del(SwooleHttpRequest $request, SwooleHttpResponse $response)
{
$uid = $request->post['uid'];
$database = new SimpsDBBaseModel();
$res = $database->delete("user_info", [
"uid" => $uid
]);
return [
"code" => 200,
"msg" => "MysqlDemo del",
"data" => [
'res' => $res,
'uid' => $uid,
],
];
}
public function update(SwooleHttpRequest $request, SwooleHttpResponse $response)
{
$uid = $request->post['uid'];
$username = $request->post['username'];
$database = new SimpsDBBaseModel();
$res = $database->update("user_info", [
"nick" => $username
], [
"uid" => $uid
]);
return [
"code" => 200,
"msg" => "MysqlDemo update",
"data" => [
'res' => $res,
'uid' => $uid,
'username' => $username,
],
];
}
}
Adicione um processo de trabalho definido pelo usuário. Esta função geralmente é usada para criar um processo de trabalho especial para monitoramento, geração de relatórios ou outras tarefas especiais. Para conteúdo específico, consulte o site oficial do Swoole addProcess
Coisas a serem observadas:
$server
, como getClientList/getClientInfo/stats
Worker/Task
, você pode chamar o método fornecido por $process
para se comunicar com o processo filho.$server->sendMessage
para se comunicar com o processo Worker/Task
.Server->task/taskwait
não pode ser usada no processo do usuário.Server->send/close
while(true)
(conforme mostrado no exemplo abaixo) ou loop EventLoop (como criar um timer), caso contrário, o processo do usuário continuará a sair e reiniciar.Exemplo de uso
Adicione um processo de trabalho definido pelo usuário e adicione a configuração process
em ./config/conf.php
da seguinte maneira:
'process' => [
[AppControllerProcess::class, 'addProcess']
],
Exemplo de controlador:
<?php
namespace AppController;
class Process
{
//添加用户自定义的工作进程
public function addProcess($server)
{
return new SwooleProcess(function ($process) use ($server) {
while (true) {
Co::sleep(1);
echo "Hello, api-swoole!rn";
}
}, false, 2, 1);
}
}
A estrutura registrou, por padrão, cinco eventos customizados: workerStart、open、close、task、finish
. O código comercial de processamento pode ser adicionado ao retorno de chamada do evento correspondente de acordo com características comerciais específicas. ./confg/events.php
, cada evento permite vários retornos de chamada
<?php
return [
'workerStart' => [
[AppExtPool::class, 'startPool'],//启动连接池
// [AppControllerEventsDemo::class, 'workerStart'],
],
'open' => [
[AppControllerEventsDemo::class, 'open'],
],
'close' => [
[AppControllerEventsDemo::class, 'close'],
],
'task' => [
[AppControllerEventsDemo::class, 'task'],
],
'finish' => [
[AppControllerEventsDemo::class, 'finish'],
],
];