스폰서
운영 환경이 다음 요구 사항을 충족하는지 확인해야 합니다.
composer create-project api-swoole/skeleton
HTTP 서비스, WebSocket 서비스, tcp 서비스를 지원하고 프로젝트 루트 디렉터리 ./apiswoole.php
에서 명령을 실행합니다.
php apiswoole.php
api-swoole 프레임워크에서 주요 비즈니스 코드는 앱 디렉터리에 있습니다. 내부의 각 네임스페이스는 하위 디렉터리에 해당합니다. 프로젝트의 기본 네임스페이스는 App입니다. 프로젝트가 생성된 후 app 디렉터리에는 Common, example 및 Ext라는 세 개의 하위 디렉터리가 포함됩니다. Ext는 일반적으로 도구 등을 배치합니다. 디렉토리 구조는 다음과 같습니다.
./
└── app
├── Example # 放置接口源代码,相当于控制器层
├── Common # 公共代码目录,
└── Ext# 放置工具等
프로젝트에 새 인터페이스를 추가해야 하는 경우 먼저 ./app/Example
디렉터리에 새 hello.php
파일을 만들고 편집기로 코드를 편집하세요.
<?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'),
],
];
}
}
route/http.php
라우팅 파일에 프로젝트 @
를 정의합니다. 첫 번째 매개변수는 정의된 브라우저 액세스 주소입니다. 두 번째 매개변수 @
의 전반부는 파일의 전체 네임스페이스입니다. 수업 방식에서.
return [
HttpRouter("/hello", "AppExampleHello@index"),
];
비데몬 모드로 시작하려면 프로젝트 루트 디렉터리에서 다음 명령을 실행합니다.
php apiswoole.php
기본적으로 로컬 HTTP 및 websocket 포트 9501을 수신합니다. cmd에 다음 출력 정보가 나타나 프로젝트가 성공적으로 시작되었음을 나타냅니다.
[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
브라우저 주소 표시줄에 정의된 라우팅 주소를 입력하면 주소는 http://ip网址:端口/定义的路由
로 구성됩니다.
http://127.0.0.1:9501/hello
성공적인 요청 후 반환되는 데이터는 기본 코드, msg 및 데이터 필드를 포함하여 기본적으로 json 형식으로 반환됩니다.
{
"code" : 200 ,
"msg" : " success " ,
"data" : {
"code" : 200 ,
"data" : {
"name" : " api-swoole " ,
"version" : " 1.0.2 "
}
},
"debug" : []
}
HttpServer
의 HTTP
프로토콜 지원은 불완전하므로 동적 요청을 처리하는 애플리케이션 서버로만 사용하고 프런트엔드에 Nginx
프록시로 추가하는 것이 좋습니다. (참조 주소)
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;
}
}
$request->header['x-real-ip']
읽으면 클라이언트의 실제 IP
얻을 수 있습니다.
기본 구성 폴더에는 conf.php, db.php 및 events.php의 세 가지 파일이 포함되어 있습니다. conf.php는 http, tcp, udp, websocket 및 기타 구성을 포함한 프로젝트의 구성 정보를 저장합니다. db.php는 MySQL 및 Redis 연결 구성을 담당하고 events.php는 특정 이벤트 등록 및 모니터링을 정의하고 사용자 정의하는 역할을 담당합니다. 이제 workerStart、open、close、task、finish
지원합니다. 구성 정보는 DI()->config->get('conf.ws')
또는 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']
],//添加用户自定义的工作进程
];
해당 서비스는 프로젝트 시작 시 apiswoole.php
에 기본적으로 등록되어 있습니다.
$di = DI();
$di->config = new Config("./config");
예를 들어 구성 정보는 conf.php이고 구조는 다음과 같습니다.
return [
'debug' => true,//调试模式
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', AppControllerTcpServe::class, 'onReceive'],
],
'settings' => [],
],
]
DI()->config->get('conf.tcp')
사용하여 구성 파일을 읽을 수 있습니다.
DI()->config->get('conf.tcp') #返回数组
배열 데이터 구조를 반환합니다.
{
"host" : " 0.0.0.0 " ,
"port" : 9500 ,
"sockType" : 1 ,
"events" : [
[
" receive " ,
" App \ Controller \ TcpServe " ,
" onReceive "
]
],
"settings" : []
}
로그 인터페이스는 PSR 사양에 따라 세부적으로 정의됩니다. 로그는 ./storage/log
디렉터리에 기록되며日期.log
매일 생성됩니다. 현재 다음 유형의 로깅이 지원됩니다.
로깅 시스템은 다음을 사용합니다.
DI()->logger->debug("日志测试debug"); #开发调试类日记
DI()->logger->info("日志测试info"); #业务纪录类日记
DI()->logger->notice("日志测试notice");#系统提示类日记
DI()->logger->waring("日志测试waring");#系统致命类日记
DI()->logger->error("日志测试error"); #系统异常类日记
./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
HttpServer를 상속하므로 HttpServer
에서 제공하는 모든 API
및 구성 항목을 사용할 수 있습니다. HttpServer 장을 참조하세요.
WebSocketServer
동시에 HTTP
서버 역할도 할 수 있습니다.WebSocketServer
HTTP
요청을 받은 후 HTTP 400
오류 페이지를 반환합니다. 웹소켓 서버만 구현하려면 ./config/conf.php
구성에서 ['request', SapiEvents::class, 'onRequest']
삭제하세요.
HTTP/websocket 서버 구성 옵션은 ./config/conf.php
에 있습니다. 구체적인 구성 정보는 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,
],
],
];
HTTP 서버의 경로 빌드 파일은 ./route/http.php
에 있습니다. 특정 라우팅 규칙을 선언합니다. 첫 번째 매개변수는 정의된 브라우저 액세스 주소입니다. 두 번째 매개변수 @
의 전반부는 파일의 전체 네임스페이스입니다. @
의 후반부는 클래스에서 호출되는 특정 메서드입니다.
return [
HttpRouter("/", "AppExampleApp@Index"),
HttpRouter("/hello", "AppExampleHello@index"),
HttpRouter("声明浏览器地址", "命名空间+类@类中的方法"),
];
전체 URL 주소는 http://ip网址:端口/定义的路由
로 구성됩니다.
기본 경로를 구축하려면 URI와闭包
만 필요하며 경로를 정의하는 매우 간단한 방법을 제공합니다.
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'),
],
];
}),
];
해당 컨트롤러 메서드에는 기본적으로 $request
및 $reponse
두 개의 매개 변수가 있습니다. Request 및 Response 개체에 대한 전체 소개는 Swoole 설명서(HttpRequest, HttpResponse)를 참조하세요.
<?php
namespace AppController;
use SapiApi;
class Hello extends Api
{
public function index()
{
return [
'code' => 200,
'data' => 'hello world'
];
}
}
인터페이스 매개변수 규칙은 Api
클래스를 상속하여 구현되며, 특정 정의 규칙은 rule()
메소드를 통해 구현됩니다.
name
클라이언트가 전달한 값에 해당합니다.require
값이 옵션으로 전달되고, true
전달되고, false
전달되어야 함을 나타냅니다.type
, int
, string
, float
, bool
, array
, file
지원source
매개변수는 해당 위치로 전달되며 get
, post
및 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/')
],
];
}
}
websocket 서버의 경로 정의 파일은 ./route/websocket.php
에 있습니다. 특정 라우팅 규칙을 선언합니다. 첫 번째 매개변수는 정의된 브라우저 액세스 주소입니다. 두 번째 매개변수 @
의 전반부는 파일의 전체 네임스페이스입니다. @
의 후반부는 클래스에서 호출되는 특정 메서드입니다.
return [
WsRouter("/", "AppExampleWebsocket@index"),
WsRouter("/login", "AppExampleWebsocket@login"),
];
전체 URL 주소는 ws://ip网址:端口
로 구성됩니다.
해당 컨트롤러 메서드에는 기본적으로 $server
및 $msg
두 개의 매개 변수가 있습니다. $server
개체에 대한 전체 소개는 Swoole 설명서인 WebSocketServer를 참조하세요. $msg
클라이언트가 보낸 데이터 정보입니다.
클라이언트가 보내는 데이터 정보는 기본적으로 json 형식으로 전송되어야 하며, id, path, data 3가지 필드를 포함해야 합니다.
id
필드는 메시지 본문의 고유 식별자입니다.path
필드는 ./route/websocket.php
경로에 의해 선언된 액세스 주소입니다.data
필드는 프로젝트의 특정 메시지 매개변수이며 기본 제어 방법은 $msg
입니다. {
"id" : " 918wsEMQDrj0RXxm " ,
"path" : " / " ,
"data" : {
"username" : " api-swoole "
}
}
컨트롤러 코드 섹션의 예:
<?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'),
]
];
}
}
인터페이스 매개변수 규칙은 Api
클래스를 상속하여 구현되며, 특정 정의 규칙은 rule()
메소드를 통해 구현됩니다.
name
클라이언트가 전달한 값에 해당합니다.require
값이 옵션으로 전달되고, true
전달되고, false
전달되어야 함을 나타냅니다.type
유형, 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'],
]
];
}
}
Api
클래스에는 내장 후크 함수 userCheck
있으며 모든 HTTP 컨트롤러는 Api
클래스 오버로드를 상속할 수 있습니다. 예를 들어 사용자 인증을 수행할 수 있습니다.
먼저 선언 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 "";
}
}
그런 다음 HttpBase.php
상속하여 클래스 오버로딩을 구현합니다.
<?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']
]
];
}
}
Api
클래스에는 내장 후크 함수 userWsCheck
있으며 모든 웹소켓 컨트롤러는 Api
클래스 오버로드를 상속할 수 있습니다. 예를 들어 사용자 인증을 수행할 수 있습니다.
먼저 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 "";
}
}
그런 다음 WsBase.php
상속하여 클래스 오버로딩을 구현합니다.
<?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
여러 포트를 수신할 수 있으며 각 포트는 서로 다른 프로토콜을 처리하도록 설정할 수 있습니다. 예를 들어 포트 80은 HTTP 프로토콜을 처리하고 포트 9500은 TCP 프로토콜을 처리하며 포트 9502는 UDP 프로토콜을 처리합니다. SSL/TLS
전송 암호화는 특정 포트에만 활성화할 수도 있습니다. Swoole 공식 문서 참조(다중 포트 모니터링)
TCP 서버 구성 옵션은 ./config/conf.php
에 tcp 필드를 추가합니다. 구체적인 구성 정보는 Swoole 문서 TCP 구성을 참조하세요.
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', AppControllerTcpServe::class, 'onReceive'],//TCP服务器回调
],
'settings' => [],
],
UDP 서버 구성 옵션은 ./config/conf.php
에 udp 필드를 추가합니다. 구체적인 구성 정보는 Swoole 문서 UDP 구성을 참조하세요.
'udp' => [
'host' => '0.0.0.0',
'port' => 9502,
'sockType' => SWOOLE_SOCK_UDP,
'events' => [
['packet', AppControllerUdpServe::class, 'onPacket'],//UDP服务器回调
],
'settings' => [],
],
Swoole 개발팀은 Hook의 기본 PHP 기능을 사용하여 코루틴 클라이언트를 구현합니다. 한 줄의 코드로 원래 동기 IO 코드를 코루틴에서 예약할 수 있는 비동기 IO, 즉 원클릭 코루틴화로 전환할 수 있습니다. Swoole
에서 제공하는 SwooleServer 클래스 클러스터는 자동으로 생성되므로 수동으로 수행할 필요가 없습니다. 활성화_코루틴을 참조하세요. 구체적인 내용은 원클릭 코루틴화를 위한 Swoole 공식 홈페이지를 참고하시기 바랍니다.
프레임워크 데이터베이스에는 simple-swoole
타사 확장 패키지가 도입되었습니다. 자세한 내용은 simple-swoole/db를 참조하세요.
Redis 서버 구성 옵션은 ./config/db.php
에 있습니다.
<?php
return [
'redis' => [
'host' => '192.168.0.105',//Redis服务器地址
'port' => 6379,//指定 Redis 监听端口
'auth' => '',//登录密码
'db_index' => 2,//指定数据库
'time_out' => 1,//
'size' => 64,//连接池数量
],
];
프로젝트에서 Redis 사용
<?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'],
],
];
}
}
MySQL 서버 구성 옵션은 ./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
연결 풀을 구성합니다.
<?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
경량 PHP 데이터베이스 프레임워크 Medoo를 통합합니다. 사용 시 SimpsDBBaseModel
상속해야 하므로 사용 방법은 기본적으로 Medoo 문서를 확인하세요.
유일한 차이점은 트랜잭션 관련 작업입니다. Medoo에서는 action( $callback )
action( $callback )
를 사용하지만 이 프레임워크에서는 다음 메서드도 사용할 수 있습니다.
beginTransaction(); // 开启事务
commit(); // 提交事务
rollBack(); // 回滚事务
거래 예시
$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();
}
프로젝트에 사용되는 데이터베이스 테이블 구조:
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,
],
];
}
}
사용자 정의 작업자 프로세스를 추가합니다. 이 기능은 일반적으로 모니터링, 보고 또는 기타 특수 작업을 위한 특수 작업자 프로세스를 만드는 데 사용됩니다. 구체적인 내용은 Swoole 공식 홈페이지 addProcess 를 참조하세요.
참고 사항:
getClientList/getClientInfo/stats
등 $server
객체가 제공하는 다양한 메소드를 호출할 수 있습니다.Worker/Task
프로세스에서는 $process
에서 제공하는 메서드를 호출하여 자식 프로세스와 통신할 수 있습니다.$server->sendMessage
호출하여 Worker/Task
프로세스와 통신할 수 있습니다.Server->task/taskwait
인터페이스는 사용자 프로세스에서 사용할 수 없습니다.Server->send/close
와 같은 인터페이스를 사용할 수 있습니다.while(true)
(아래 예 참조) 또는 EventLoop 루프(예: 타이머 생성)를 수행해야 합니다. 그렇지 않으면 사용자 프로세스가 계속 종료되고 다시 시작됩니다.사용예
다음과 같이 사용자 정의 작업자 프로세스를 추가하고 ./config/conf.php
에 process
구성을 추가합니다.
'process' => [
[AppControllerProcess::class, 'addProcess']
],
컨트롤러 예:
<?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);
}
}
프레임워크는 기본적으로 5개의 사용자 정의 이벤트( workerStart、open、close、task、finish
를 등록했습니다. 구체적인 업무 특성에 따라 해당 이벤트 콜백에 처리 업무 코드를 추가할 수 있습니다. ./confg/events.php
, 각 이벤트는 여러 콜백을 허용합니다.
<?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'],
],
];