สปอนเซอร์
คุณต้องแน่ใจว่าสภาพแวดล้อมการทำงานตรงตามข้อกำหนดต่อไปนี้:
composer create-project api-swoole/skeleton
รองรับบริการ HTTP, บริการ WebSocket, บริการ TCP และดำเนินการคำสั่งในไดเรกทอรีรากของโปรเจ็กต์ . ./apiswoole.php
php apiswoole.php
ในเฟรมเวิร์ก api-swoole รหัสธุรกิจหลักจะอยู่ในไดเร็กทอรีแอป แต่ละเนมสเปซภายในสอดคล้องกับไดเร็กทอรีย่อย เนมสเปซเริ่มต้นของโปรเจ็กต์คือ App หลังจากสร้างโปรเจ็กต์แล้ว ไดเร็กทอรีแอปจะมีไดเร็กทอรีย่อยสามไดเร็กทอรี: Common, Examples และ Ext และโดยทั่วไปแล้ว Ext จะวางเครื่องมือ ฯลฯ โครงสร้างไดเรกทอรีเป็นดังนี้:
./
└── app
├── Example # 放置接口源代码,相当于控制器层
├── Common # 公共代码目录,
└── Ext# 放置工具等
เมื่อโปรเจ็กต์จำเป็นต้องเพิ่มอินเทอร์เฟซใหม่ ขั้นแรกให้สร้างไฟล์ hello.php
ใหม่ในไดเร็กทอรี ./app/Example
และแก้ไขโค้ดด้วยโปรแกรมแก้ไข
<?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"),
];
ดำเนินการคำสั่งต่อไปนี้ในไดเร็กทอรีรากของโปรเจ็กต์เพื่อเริ่มต้นในโหมดที่ไม่ใช่ daemon
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
ข้อมูลที่ส่งคืนหลังจากการร้องขอที่สำเร็จจะถูกส่งคืนในรูปแบบ json โดยค่าเริ่มต้น รวมถึงโค้ดเริ่มต้น msg และฟิลด์ข้อมูล ข้อมูลใน data คือข้อมูลที่ส่งคืนในเมธอด
{
"code" : 200 ,
"msg" : " success " ,
"data" : {
"code" : 200 ,
"data" : {
"name" : " api-swoole " ,
"version" : " 1.0.2 "
}
},
"debug" : []
}
เนื่องจากการสนับสนุนโปรโตคอล HTTP
ของ HttpServer
ไม่สมบูรณ์ จึงแนะนำให้ใช้เป็นเซิร์ฟเวอร์แอปพลิเคชันเพื่อจัดการคำขอแบบไดนามิกเท่านั้น และเพิ่ม 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;
}
}
คุณสามารถรับ IP
จริงของลูกค้าได้โดยการอ่าน $request->header['x-real-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 ดังนั้น API
และรายการการกำหนดค่าทั้งหมดที่ HttpServer
มอบให้จึงสามารถใช้ได้ โปรดดูบท HttpServer
WebSocketServer
ยังสามารถทำหน้าที่เป็นเซิร์ฟเวอร์ HTTP
ในเวลาเดียวกันได้WebSocketServer
จะส่งกลับหน้าข้อผิดพลาด HTTP 400
หลังจากได้รับคำขอ HTTP
หากคุณต้องการใช้เซิร์ฟเวอร์ websocket เท่านั้น ให้ลบ ['request', SapiEvents::class, 'onRequest']
ในการกำหนดค่า ./config/conf.php
ตัวเลือกการกำหนดค่าเซิร์ฟเวอร์ 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 โปรดดูเอกสารประกอบ Swole: 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, เส้นทาง และข้อมูล
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
มีฟังก์ชัน hook ในตัว 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
มีฟังก์ชัน hook ในตัว userWsCheck
และตัวควบคุม websocket ทั้งหมดสามารถสืบทอดโอเวอร์โหลดคลาส 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 เพิ่มฟิลด์ tcp ใน . ./config/conf.php
สำหรับข้อมูลการกำหนดค่าเฉพาะ โปรดดูการกำหนดค่า TCP ของเอกสาร Swoole
'tcp' => [
'host' => '0.0.0.0',
'port' => 9500,
'sockType' => SWOOLE_SOCK_TCP,
'events' => [
['receive', AppControllerTcpServe::class, 'onReceive'],//TCP服务器回调
],
'settings' => [],
],
ตัวเลือกการกำหนดค่าเซิร์ฟเวอร์ UDP เพิ่มฟิลด์ udp ใน ./config/conf.php
สำหรับข้อมูลการกำหนดค่าเฉพาะ โปรดดูการกำหนดค่า UDP ของเอกสาร Swoole
'udp' => [
'host' => '0.0.0.0',
'port' => 9502,
'sockType' => SWOOLE_SOCK_UDP,
'events' => [
['packet', AppControllerUdpServe::class, 'onPacket'],//UDP服务器回调
],
'settings' => [],
],
ทีมพัฒนา Swoole ใช้ฟังก์ชัน PHP ดั้งเดิมของ Hook เพื่อใช้งานไคลเอ็นต์ Coroutine คลัสเตอร์คลาส SwoolServer ที่ Swoole
มอบให้จะถูกสร้างขึ้นโดยอัตโนมัติ และไม่จำเป็นต้องดำเนินการด้วยตนเอง โปรดดูที่enable_coroutine สำหรับเนื้อหาเฉพาะ โปรดดูที่เว็บไซต์อย่างเป็นทางการของ 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
ข้อแตกต่างเพียงอย่างเดียวคือการดำเนินการที่เกี่ยวข้องกับธุรกรรม ใน 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,
],
];
}
}
เพิ่มกระบวนการของผู้ปฏิบัติงานที่ผู้ใช้กำหนด โดยปกติแล้วฟังก์ชันนี้จะใช้เพื่อสร้างกระบวนการของผู้ปฏิบัติงานพิเศษสำหรับการตรวจสอบ การรายงาน หรืองานพิเศษอื่นๆ สำหรับเนื้อหาเฉพาะ โปรดดู addProcess เว็บไซต์อย่างเป็นทางการของ Swoole
สิ่งที่ควรทราบ:
$server
เช่น getClientList/getClientInfo/stats
Worker/Task
คุณสามารถเรียกใช้เมธอดที่ $process
จัดเตรียมไว้เพื่อสื่อสารกับกระบวนการลูกได้$server->sendMessage
เพื่อสื่อสารกับกระบวนการ Worker/Task
ได้Server->task/taskwait
ไม่สามารถใช้ในกระบวนการผู้ใช้ได้Server->send/close
while(true)
(ดังแสดงในตัวอย่างด้านล่าง) หรือลูป EventLoop (เช่น การสร้างตัวจับเวลา) มิฉะนั้น กระบวนการผู้ใช้จะยังคงออกและรีสตาร์ทตัวอย่างการใช้งาน
เพิ่มกระบวนการของผู้ปฏิบัติงานที่ผู้ใช้กำหนดและเพิ่มการกำหนดค่า process
ใน ./config/conf.php
ดังนี้:
'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);
}
}
เฟรมเวิร์กมีเหตุการณ์ที่กำหนดเองที่ลงทะเบียนไว้ห้าเหตุการณ์ตามค่าเริ่มต้น: 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'],
],
];