راعي
تحتاج إلى التأكد من أن بيئة التشغيل تلبي المتطلبات التالية:
composer create-project api-swoole/skeleton
يدعم خدمة HTTP، وخدمة WebSocket، وخدمة TCP، وينفذ الأوامر في الدليل الجذر للمشروع ./apiswoole.php
.
php apiswoole.php
في إطار عمل API-swoole، يوجد رمز العمل الرئيسي في دليل التطبيق. تتوافق كل مساحة اسم بداخلها مع دليل فرعي. مساحة الاسم الافتراضية للمشروع هي App. بعد إنشاء المشروع، يحتوي دليل التطبيق على ثلاثة أدلة فرعية: Common وExample وExt. يخزن الدليل Common ملف function.php الخاص بالوظيفة. و 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"),
];
قم بتنفيذ الأمر التالي في الدليل الجذر للمشروع للبدء في الوضع غير الخفي.
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 بشكل افتراضي، بما في ذلك الرمز الافتراضي والرسائل وحقول البيانات. البيانات الموجودة في البيانات هي البيانات التي يتم إرجاعها في الطريقة.
{
"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;
}
}
يمكنك الحصول على 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
، بشكل افتراضي للحصول على مقدمة كاملة لكائنات الطلب والاستجابة، يرجى الاطلاع على وثائق 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
typeInput يدعم int
string
bool
float
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
هو عنوان الوصول المعلن بواسطة المسار ./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
، ويمكن لجميع وحدات تحكم 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 باستخدام سطر واحد من التعليمات البرمجية، ويمكن تحويل كود الإدخال والإخراج المتزامن الأصلي إلى IO غير متزامن يمكن جدولته بواسطة coroutine، أي coroutineization بنقرة واحدة. يتم إنشاء مجموعات فئة SwooleServer التي توفرها 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'],
],
];