(一).開始
1.1下載與安裝
源碼地址:
api-swoole框架github源碼地址
api-swoole框架gitee源碼地址
需要確保運(yùn)行環(huán)境達(dá)到了以下的要求:
- PHP >= 7.4
- Swoole PHP 擴(kuò)展 >= 4.5
- Redis PHP 擴(kuò)展 (如需使用 Redis 客戶端)
- PDO PHP 擴(kuò)展 (如需使用 MySQL 客戶端)
1.2通過 Composer 創(chuàng)建項(xiàng)目
composer create-project api-swoole/skeleton
1.3啟動(dòng)
支持 HTTP 服務(wù)、WebSocket 服務(wù)、tcp服務(wù),項(xiàng)目根目錄./apiswoole.php
執(zhí)行命令。
php apiswoole.php
(二).Hello World
2.1編寫一個(gè)接口
在api-swoole框架中壤短,業(yè)務(wù)主要代碼在app目錄中。里面各個(gè)命名空間對(duì)應(yīng)一個(gè)子目錄锭沟,項(xiàng)目的默認(rèn)命名空間是App致燥,創(chuàng)建項(xiàng)目后app目錄中包含Common蹭沛、Controller辽剧、Ext三個(gè)子目錄送淆,Common目錄存放函數(shù)的functions.php文件,Ext一般放置工具等怕轿。目錄結(jié)構(gòu)如下:
./
└── app
├── Controller # 放置接口源代碼偷崩,相當(dāng)于控制器層
├── Common # 公共代碼目錄,
└── Ext# 放置工具等
當(dāng)項(xiàng)目需要新增接口時(shí)撞羽,先在./app/Controller
目錄中新建hello.php
文件阐斜,并用編輯器編輯代碼。
<?php
namespace App\Controller;
use Sapi\Api;
class Hello extends Api
{
public function index()
{
return [
'code' => 200,
'data' => 'hello world'
];
}
}
2.2定義路由
在route/http.php
路由文件中定義項(xiàng)目路由诀紊,第一個(gè)參數(shù)為定義的瀏覽器訪問地址谒出,第二個(gè)參數(shù)@
前半部分為文件的完整命名空間,@
后半部分為在類中調(diào)用的具體方法。
return [
\HttpRouter("/hello", "App\Controller\Hello@index"),
];
2.3啟動(dòng)項(xiàng)目
在項(xiàng)目根目錄下執(zhí)行如下命令以非守護(hù)模式啟動(dòng)笤喳。
php apiswoole.php
默認(rèn)情況下監(jiān)聽本地的HTTP和websocket的9501端口考赛,在cmd中出現(xiàn)如下輸出信息表示項(xiàng)目啟動(dòng)成功。
[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
2.4訪問接口
在瀏覽器地址欄中輸入定義的路由地址莉测,地址組成http://ip網(wǎng)址:端口/定義的路由
。
http://127.0.0.1:9501/hello
請(qǐng)求成功返回?cái)?shù)據(jù)默認(rèn)json方式返回唧喉,包含默認(rèn)的code捣卤、msg、data字段八孝,data中數(shù)據(jù)為方法中返回的數(shù)據(jù)董朝。
{
"code": 200,
"msg": "success",
"data": {
"code": 200,
"data": "hello world"
}
}
(三).反向代理(Nginx + Swoole 配置)
由于 Http\Server
對(duì) HTTP
協(xié)議的支持并不完整,建議僅作為應(yīng)用服務(wù)器干跛,用于處理動(dòng)態(tài)請(qǐng)求子姜,并且在前端增加 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']
來獲取客戶端的真實(shí) IP
(四).配置
4.1配置文件
默認(rèn)config文件夾下包含conf.php楼入、db.php哥捕、events.php三個(gè)文件,conf.php放置項(xiàng)目的配置信息嘉熊,http遥赚、tcp、udp阐肤、websocket等配置凫佛。db.php負(fù)責(zé)配置MySQL、Redis連接孕惜,events.php負(fù)責(zé)定義定制特定事件注冊(cè)監(jiān)聽愧薛,現(xiàn)支持workerStart、open衫画、close毫炉、task、finish
事件注冊(cè) 削罩〉夤浚可以通過DI()->config->get('conf.ws')
或者\Sapi\Di::one()->config->get('conf.ws')
方式讀取配置信息。
./config/
├── conf.php #http鲸郊、tcp丰榴、udp、websocket等配置
├── db.php #數(shù)據(jù)庫配置
└── events.php #定制特定事件注冊(cè)監(jiān)聽
4.2參數(shù)說明
<?php
return [
'debug' => true,//true 調(diào)試模式 false 關(guān)閉調(diào)試
'log' => [
'displayConsole' => true,//控制臺(tái)打印日志秆撮,true打開 false 關(guān)閉
'saveLog' => true,//保存日志 true 打開 false 關(guān)閉
],
'udp' => [
'host' => '0.0.0.0',//指定監(jiān)聽的ip地址
'port' => 9502,//指定監(jiān)聽端口
'sockType' => SWOOLE_SOCK_UDP,//指定這組 Server 的類型
'events' => [
['packet', \App\Controller\UdpServe::class, 'onPacket'],//回調(diào)事件
],
'settings' => [],//配置選項(xiàng)https://wiki.swoole.com/#/server/setting
],
'tcp' => [
'host' => '0.0.0.0',//指定監(jiān)聽的ip地址
'port' => 9501,//指定監(jiān)聽端口
'sockType' => SWOOLE_SOCK_TCP,//指定這組 Server 的類型
'events' => [
['receive', \App\Controller\TcpServe::class, 'onReceive'],//回調(diào)事件
],
'settings' => [],//配置選項(xiàng)https://wiki.swoole.com/#/server/setting
],
'ws' => [
'host' => '0.0.0.0',//指定監(jiān)聽的ip地址
'port' => 9500,//指定監(jiān)聽端口
'sockType' => SWOOLE_SOCK_TCP,//指定這組 Server 的類型
'events' => [
['open', \Sapi\Events::class, 'onOpen'],
['message', \Sapi\Events::class, 'onMessage'],
['close', \Sapi\Events::class, 'onClose'],
['request', \Sapi\Events::class, 'onRequest'],
['Task', \Sapi\Events::class, 'onTask'],
['Finish', \Sapi\Events::class, 'onFinish'],
['workerStart', \Sapi\Events::class, 'onWorkerStart'],
['start', \Sapi\Events::class, 'onStart'],
],//回調(diào)事件
'settings' => [
'daemonize' => false,//設(shè)置 daemonize => true 時(shí)四濒,程序?qū)⑥D(zhuǎn)入后臺(tái)作為守護(hù)進(jìn)程運(yùn)行。長(zhǎng)時(shí)間運(yùn)行的服務(wù)器端程序必須啟用此項(xiàng)。如果不啟用守護(hù)進(jìn)程盗蟆,當(dāng) ssh 終端退出后戈二,程序?qū)⒈唤K止運(yùn)行
'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,//是否啟用異步風(fēng)格服務(wù)器的協(xié)程支持
],
],//配置選項(xiàng)https://wiki.swoole.com/#/websocket_server?id=%e9%80%89%e9%a1%b9
'process' => [
[\App\Controller\Process::class, 'addProcess']
],//添加用戶自定義的工作進(jìn)程 https://wiki.swoole.com/#/server/methods?id=addprocess
];
4.3配置讀取示例
項(xiàng)目啟動(dòng)時(shí)在apiswoole.php
已經(jīng)默認(rèn)注冊(cè)服務(wù)。
$di = DI();
$di->config = new Config("./config");
例如配置信息為conf.php,結(jié)構(gòu)為:
return [
'debug' => true,//調(diào)試模式
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', \App\Controller\TcpServe::class, 'onReceive'],
],
'settings' => [],
],
]
可以使用DI()->config->get('conf.tcp')
讀取配置文件
DI()->config->get('conf.tcp') #返回?cái)?shù)組
返回?cái)?shù)組數(shù)據(jù)結(jié)構(gòu):
{
"host": "0.0.0.0",
"port": 9500,
"sockType": 1,
"events": [
[
"receive",
"App\\Controller\\TcpServe",
"onReceive"
]
],
"settings": []
}
(五).日志
根據(jù)PSR規(guī)范中詳盡定義了日志接口喳资,日志記錄在./storage/log
目錄中觉吭,按照每日生成對(duì)應(yīng)日期.log
日志文件。目前支持以下幾種日志記錄:
- error: 系統(tǒng)異常類日記
- info: 業(yè)務(wù)紀(jì)錄類日記
- debug: 開發(fā)調(diào)試類日記
- notice: 系統(tǒng)提示類日記
- waring: 系統(tǒng)致命類日記
日志系統(tǒng)使用:
DI()->logger->debug("日志測(cè)試debug"); #開發(fā)調(diào)試類日記
DI()->logger->info("日志測(cè)試info"); #業(yè)務(wù)紀(jì)錄類日記
DI()->logger->notice("日志測(cè)試notice");#系統(tǒng)提示類日記
DI()->logger->waring("日志測(cè)試waring");#系統(tǒng)致命類日記
DI()->logger->error("日志測(cè)試error"); #系統(tǒng)異常類日記
./storage/log/20220906.log
目錄下對(duì)應(yīng)日志:
[swoole] | [2022-09-06 01:32:05] | debug | 日志測(cè)試debug
[swoole] | [2022-09-06 01:32:05] | info | 日志測(cè)試info
[swoole] | [2022-09-06 01:32:05] | notice | 日志測(cè)試notice
[swoole] | [2022-09-06 01:32:05] | warning | 日志測(cè)試waring
[swoole] | [2022-09-06 01:32:05] | error | 日志測(cè)試error
(六).HTTP/websocket服務(wù)器(參考地址)
WebSocket\Server
繼承自 Http\Server仆邓,所以 Http\Server
提供的所有 API
和配置項(xiàng)都可以使用鲜滩。請(qǐng)參考 Http\Server 章節(jié)。
- 設(shè)置了 onRequest 回調(diào)节值,
WebSocket\Server
也可以同時(shí)作為HTTP
服務(wù)器 - 未設(shè)置 onRequest 回調(diào)徙硅,
WebSocket\Server
收到HTTP
請(qǐng)求后會(huì)返回HTTP 400
錯(cuò)誤頁面
如若只想實(shí)現(xiàn)websocket服務(wù)器,則在./config/conf.php
配置中刪除['request', \Sapi\Events::class, 'onRequest']
即可搞疗。
6.1HTTP/websocket服務(wù)器配置
HTTP/websocket服務(wù)器配置選項(xiàng)在./config/conf.php
中嗓蘑。具體配置信息可以參考Swoole文檔配置選項(xiàng)。
<?php
return [
'ws' => [
'host' => '0.0.0.0',//監(jiān)聽地址
'port' => 9501,//監(jiān)聽端口
'events' => [
['open', \Sapi\Events::class, 'onOpen'],
['message', \Sapi\Events::class, 'onMessage'],
['close', \Sapi\Events::class, 'onClose'],
['request', \Sapi\Events::class, 'onRequest'],//HTTP服務(wù)器回調(diào)
['Task', \Sapi\Events::class, 'onTask'],
['Finish', \Sapi\Events::class, 'onFinish'],
['workerStart', \Sapi\Events::class, 'onWorkerStart'],
['start', \Sapi\Events::class, 'onStart'],
],//回調(diào)函數(shù)
'settings' => [
'daemonize' => false,//設(shè)置 daemonize => true 時(shí)匿乃,程序?qū)⑥D(zhuǎn)入后臺(tái)作為守護(hù)進(jìn)程運(yùn)行桩皿。長(zhǎng)時(shí)間運(yùn)行的服務(wù)器端程序必須啟用此項(xiàng)。如果不啟用守護(hù)進(jìn)程幢炸,當(dāng) ssh 終端退出后业簿,程序?qū)⒈唤K止運(yùn)行
'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,
],
],
];
6.2HTTP路由
HTTP 服務(wù)器的路由構(gòu)建文件位于./route/http.php
中。聲明具體的路由規(guī)則阳懂,第一個(gè)參數(shù)為定義的瀏覽器訪問地址梅尤,第二個(gè)參數(shù)@
前半部分為文件的完整命名空間,@
后半部分為在類中調(diào)用的具體方法岩调。
return [
\HttpRouter("/", "App\Controller\App@Index"),
\HttpRouter("/hello", "App\Controller\Hello@index"),
\HttpRouter("聲明瀏覽器地址", "命名空間+類@類中的方法"),
];
完整的URL地址組成http://ip網(wǎng)址:端口/定義的路由
巷燥。
構(gòu)建基本路由只需要一個(gè) URI 與一個(gè) 閉包
,提供了一個(gè)非常簡(jiǎn)單定義路由的方法:
return [
\HttpRouter("/start", function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
return 'hello';
}),
];
6.3HTTP控制器
對(duì)應(yīng)的控制器方法默認(rèn)有兩個(gè)參數(shù) $request
和 $reponse
号枕,關(guān)于 Request 和 Response 對(duì)象完整的介紹請(qǐng)查看 Swoole 文檔:Http\Request 缰揪、 Http\Response
<?php
namespace App\Controller;
use Sapi\Api;
class Hello extends Api
{
public function index()
{
return [
'code' => 200,
'data' => 'hello world'
];
}
}
6.4接口參數(shù)規(guī)則
接口參數(shù)規(guī)則通過繼承Api
類實(shí)現(xiàn),具體的定義規(guī)則通過rule()
方法葱淳。
- 一維下標(biāo)是接口類的方法名钝腺。
- 二維下標(biāo)是接口參數(shù)名稱。
- 三維下標(biāo)
name
對(duì)應(yīng)客戶端傳入的值赞厕,下標(biāo)require
表示值傳入可選項(xiàng),true
必須傳入艳狐,false
非必須傳入。
<?php
namespace App\Controller;
use Sapi\Api;
class Auth extends Api
{
public function rule()
{
return [
'login' => [
'username' => ['name' => 'username', 'require' => true]
]
];
}
public function login(\Swoole\Http\Request $request, \Swoole\Http\Response $response): array
{
return [
"code" => 200,
"msg" => "login",
"data" => [
'username' => $request->post['username']
]
];
}
}
6.5websocket路由
websocket服務(wù)器的路由定義文件位于./route/websocket.php
中皿桑。聲明具體的路由規(guī)則毫目,第一個(gè)參數(shù)為定義的瀏覽器訪問地址蔬啡,第二個(gè)參數(shù)@
前半部分為文件的完整命名空間,@
后半部分為在類中調(diào)用的具體方法镀虐。
return [
WsRouter("/", "\App\Controller\Websocket@index"),
WsRouter("/login", "\App\Controller\Websocket@login"),
];
完整的URL地址組成ws://ip網(wǎng)址:端口
箱蟆。
6.6websocket控制器
對(duì)應(yīng)的控制器方法默認(rèn)有兩個(gè)參數(shù) $server
和 $msg
,關(guān)于 $server
對(duì)象完整的介紹請(qǐng)查看 Swoole 文檔:WebSocket\Server刮便。 $msg
是客戶端發(fā)送的數(shù)據(jù)信息空猜。
補(bǔ)充:websocket客戶端消息傳入格式
客戶端發(fā)送的數(shù)據(jù)信息,默認(rèn)需以json格式傳送恨旱,必須包含id辈毯、path、data三個(gè)字段窖杀。
-
id
字段消息體的唯一標(biāo)識(shí)。 -
path
字段是./route/websocket.php
路由聲明的訪問地址裙士。 -
data
字段是項(xiàng)目的具體消息參數(shù)入客,控制方法默認(rèn)的$msg
。
{
"id":"918wsEMQDrj0RXxm",
"path":"/",
"data": {
"username": "api-swoole"
}
}
控制器代碼部分示例:
<?php
namespace App\Controller;
use Sapi\Api;
class Websocket extends Api
{
public function index(\Swoole\WebSocket\Server $server, array $msg): array
{
return [
'err' => 200,
'data' => [
'name' => 'api-swoole',
'version' => '1.0.0',
]
];
}
}
6.7websocket接口參數(shù)規(guī)則
接口參數(shù)規(guī)則通過繼承Api
類實(shí)現(xiàn)腿椎,具體的定義規(guī)則通過rule()
方法桌硫。
- 一維下標(biāo)是接口類的方法名。
- 二維下標(biāo)是接口參數(shù)名稱啃炸。
- 三維下標(biāo)
name
對(duì)應(yīng)客戶端傳入的值铆隘,下標(biāo)require
表示值傳入可選項(xiàng),true
必須傳入,false
非必須傳入南用。
<?php
namespace App\Controller;
use Sapi\Api;
class Websocket extends Api
{
public function rule()
{
return [
'login' => [
'username' => ['name' => 'username', 'require' => true]
]
];
}
public function login(\Swoole\WebSocket\Server $server, array $msg): array
{
return [
'err' => 200,
'data' => [
'username' => $msg['username'],
]
];
}
}
6.8http/websocket勾子函數(shù)
Api
類內(nèi)置了鉤子函數(shù)userCheck
,HTTP/websocket控制器均可繼承Api
類重載膀钠。例如可完成用戶身份驗(yàn)證。
首先定義聲明Base.php
文件裹虫。
<?php
namespace App\Controller;
use Sapi\Api;
class Base extends Api
{
//用戶權(quán)限驗(yàn)證
public function userCheck()
{
if (true) {
return "token過期";
}
}
}
然后繼承Base.php
實(shí)現(xiàn)類重載肿嘲,。
<?php
namespace App\Controller;
use Sapi\Api;
class Auth extends Base
{
public function rule()
{
return [
'login' => [
'username' => ['name' => 'username', 'require' => true]
]
];
}
public function login(\Swoole\Http\Request $request, \Swoole\Http\Response $response): array
{
return [
"code" => 200,
"msg" => "login",
"data" => [
'username' => $request->post['username']
]
];
}
}
(七).TCP/UDP服務(wù)器
Server
可以監(jiān)聽多個(gè)端口筑公,每個(gè)端口都可以設(shè)置不同的協(xié)議處理方式雳窟,例如 80 端口處理 HTTP 協(xié)議,9500 端口處理 TCP 協(xié)議,9502 端口處理 UDP 協(xié)議匣屡。SSL/TLS
傳輸加密也可以只對(duì)特定的端口啟用封救。參考Swoole官方文檔(多端口監(jiān)聽)
7.1TCP服務(wù)器配置
TCP服務(wù)器配置選項(xiàng)在./config/conf.php
中增加tcp字段。具體配置信息可以參考Swoole文檔TCP配置捣作。
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', \App\Controller\TcpServe::class, 'onReceive'],//TCP服務(wù)器回調(diào)
],
'settings' => [],
],
7.1UDP服務(wù)器配置
UDP服務(wù)器配置選項(xiàng)在./config/conf.php
中增加udp字段誉结。具體配置信息可以參考Swoole文檔UDP配置。
'udp' => [
'host' => '0.0.0.0',
'port' => 9502,
'sockType' => SWOOLE_SOCK_UDP,
'events' => [
['packet', \App\Controller\UdpServe::class, 'onPacket'],//UDP服務(wù)器回調(diào)
],
'settings' => [],
],
(八).數(shù)據(jù)庫
Swoole 開發(fā)組采用 Hook 原生 PHP 函數(shù)的方式實(shí)現(xiàn)協(xié)程客戶端券躁,通過一行代碼就可以讓原來的同步 IO 的代碼變成可以協(xié)程調(diào)度的異步 IO搓彻,即一鍵協(xié)程化如绸。Swoole
提供的 Swoole\Server 類簇都是自動(dòng)做好的,不需要手動(dòng)做旭贬,參考 enable_coroutine怔接。具體內(nèi)容可參考Swoole官網(wǎng)一鍵協(xié)程化
框架數(shù)據(jù)庫引入simple-swoole
第三方拓展包具體詳情可參考simple-swoole/db
8.1Redis
配置
Redis服務(wù)器配置選項(xiàng)在./config/db.php
中。
<?php
return [
'redis' => [
'host' => '192.168.0.105',//Redis服務(wù)器地址
'port' => 6379,//指定 Redis 監(jiān)聽端口
'auth' => '',//登錄密碼
'db_index' => 2,//指定數(shù)據(jù)庫
'time_out' => 1,//
'size' => 64,//連接池?cái)?shù)量
],
];
使用
項(xiàng)目中使用Redis
<?php
namespace App\Controller;
use App\Ext\Redis;
class RedisDemo
{
public function setData(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
{
$redis = new \Simps\DB\BaseRedis();
$res = $redis->set('我是key', '我是value');
return [
"code" => 200,
"msg" => "hello World!",
"data" => [
'res' => $res,
'key' => $request->get['key'],
'val' => $request->get['val'],
],
];
}
}
8.2MySQL
8.2.1配置
MySQL服務(wù)器配置選項(xiàng)在./config/db.php
中稀轨。
<?php
return [
'mysql' => [
'host' => '',//連接地址
'port' => ,//連接端口
'database' => '',//數(shù)據(jù)庫名稱
'username' => 'root',//用戶
'password' => '',//密碼
'charset' => 'utf8',//字符集
'unixSocket' => null,//
'options' => [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
'size' => 64 // 連接池?cái)?shù)量
],
];
./app/Ext/Pool.php
配置連接池:
<?php
namespace App\Ext;
use Sapi\Singleton;
use Simps\DB\PDO;
use Simps\DB\Redis;
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);
}
}
}
8.2.2Medoo
simple-swoole
集成了輕量級(jí)的 PHP 數(shù)據(jù)庫框架 Medoo 扼脐,使用時(shí)需要繼承 Simps\DB\BaseModel
,所以使用方法和 Medoo 基本一致奋刽,具體請(qǐng)查看 Medoo 的文檔
唯一不同的是事務(wù)相關(guān)操作瓦侮,在 Medoo 中是使用 action( $callback )
方法,而在本框架中也可以使用 action( $callback )
方法佣谐,另外也支持以下方法
beginTransaction(); // 開啟事務(wù)
commit(); // 提交事務(wù)
rollBack(); // 回滾事務(wù)
事務(wù)示例
$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();
}
8.2.3使用
項(xiàng)目中使用肚吏,數(shù)據(jù)庫表結(jié)構(gòu):
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 App\Controller;
class MysqlDemo
{
public function getOne(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
{
$uid = $request->post['uid'];
$database = new \Simps\DB\BaseModel();
$res = $database->select("user_info", [
"uid",
"nick",
], [
"uid" => $uid
]);
return [
"code" => 200,
"msg" => "MysqlDemo getOne",
"data" => [
'res' => $res,
'uid' => $uid,
],
];
}
public function save(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
{
$username = $request->post['username'];
$database = new \Simps\DB\BaseModel();
$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(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
{
$uid = $request->post['uid'];
$database = new \Simps\DB\BaseModel();
$res = $database->delete("user_info", [
"uid" => $uid
]);
return [
"code" => 200,
"msg" => "MysqlDemo del",
"data" => [
'res' => $res,
'uid' => $uid,
],
];
}
public function update(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
{
$uid = $request->post['uid'];
$username = $request->post['username'];
$database = new \Simps\DB\BaseModel();
$res = $database->update("user_info", [
"nick" => $username
], [
"uid" => $uid
]);
return [
"code" => 200,
"msg" => "MysqlDemo update",
"data" => [
'res' => $res,
'uid' => $uid,
'username' => $username,
],
];
}
}
(九).addProcess
添加一個(gè)用戶自定義的工作進(jìn)程。此函數(shù)通常用于創(chuàng)建一個(gè)特殊的工作進(jìn)程狭魂,用于監(jiān)控罚攀、上報(bào)或者其他特殊的任務(wù)。具體內(nèi)容可參考Swoole官網(wǎng)addProcess
注意事項(xiàng):
- 創(chuàng)建的子進(jìn)程可以調(diào)用
$server
對(duì)象提供的各個(gè)方法雌澄,如getClientList/getClientInfo/stats
- 在
Worker/Task
進(jìn)程中可以調(diào)用$process
提供的方法與子進(jìn)程進(jìn)行通信 - 在用戶自定義進(jìn)程中可以調(diào)用
$server->sendMessage
與Worker/Task
進(jìn)程通信 - 用戶進(jìn)程內(nèi)不能使用
Server->task/taskwait
接口 - 用戶進(jìn)程內(nèi)可以使用
Server->send/close
等接口 - 用戶進(jìn)程內(nèi)應(yīng)當(dāng)進(jìn)行
while(true)
(如下邊的示例) 或 EventLoop 循環(huán) (例如創(chuàng)建個(gè)定時(shí)器)斋泄,否則用戶進(jìn)程會(huì)不停地退出重啟
使用示例
添加一個(gè)用戶自定義的工作進(jìn)程,在./config/conf.php
中增加process
配置镐牺,如下:
'process' => [
[\App\Controller\Process::class, 'addProcess']
],
控制器示例:
<?php
namespace App\Controller;
class Process
{
//添加用戶自定義的工作進(jìn)程
public function addProcess($server)
{
return new \Swoole\Process(function ($process) use ($server) {
while (true) {
\Co::sleep(1);
echo "Hello, api-swoole!\r\n";
}
}, false, 2, 1);
}
}
(十).訂制事件注冊(cè)
框架已默認(rèn)埋點(diǎn)workerStart炫掐、open、close睬涧、task募胃、finish
五個(gè)訂制事件注冊(cè)∑枧ǎ可根據(jù)具體的業(yè)務(wù)特征在對(duì)應(yīng)的事件回調(diào)增加處理業(yè)務(wù)代碼摔认,./confg/events.php
,每個(gè)事件允許有多個(gè)回調(diào)宅粥。
<?php
return [
'workerStart' => [
[\App\Ext\Pool::class, 'startPool'],//啟動(dòng)連接池
// [\App\Controller\EventsDemo::class, 'workerStart'],
],
'open' => [
[\App\Controller\EventsDemo::class, 'open'],
],
'close' => [
[\App\Controller\EventsDemo::class, 'close'],
],
'task' => [
[\App\Controller\EventsDemo::class, 'task'],
],
'finish' => [
[\App\Controller\EventsDemo::class, 'finish'],
],
];