sidalex/ /swoole-app
一个用于在swoole服务器上组织http服务的包
Requires
- haydenpierce/class-finder: ^0.5.3
- oittaa/uuid: ^1.9
- psr/log: ^3.0
- yurunsoft/guzzle-swoole: ^2.2
Requires (Dev)
- phpstan/phpstan: ^1.11
- phpunit/phpunit: ^10.5
This package is not auto-updated.
Last update: 2024-09-29 10:58:30 UTC
README
sidalex/swoole-app Swoole工作框架
安装
安装,执行以下命令
composer require sidalex/swoole-app
要运行Swoole应用,需要创建一个名为server.php的脚本,并包含以下内容
<?php declare(strict_types=1); require_once "./vendor/autoload.php"; use Swoole\Http\Request; use Swoole\Http\Response; use Swoole\Http\Server; use Swoole\Constant; $config = json_decode(file_get_contents('./config.json')); $http = new Server("0.0.0.0", 9501); $http->set( [ Constant::OPTION_WORKER_NUM => 2, Constant::OPTION_TASK_WORKER_NUM => (swoole_cpu_num()) * 10, ] ); $app = new \Sidalex\SwooleApp\Application($config); $http->on( "start", function (Server $http) use ($app) { echo "Swoole HTTP server is started.\n"; $app->initCyclicJobs($http); } ); $http->on( "request", function (Request $request, Response $response) use ($app,$http) { $app->execute($request, $response,$http); } ); $http->on( 'task', function (Server $server, $taskId, $reactorId, $data) use ($app) { return $app->taskExecute($server, $taskId, $reactorId, $data); } ); $http->start();
$config变量应该是\stdClass类型,可以包含以下描述的参数。
要运行需要定期执行的背景进程(不由用户动作触发,而是由调度器触发),实现了CyclicJobsInterface。有关其使用的更详细说明,请参阅此处。要自动启动背景循环进程,需要在配置中指定它们。
要创建应用端点,需要创建控制器类。对于每个端点,您需要创建自己的类。或者,您可以通过notFoundController创建自己的路由规则。
CyclicJobs和控制器内部的所有操作都必须是非阻塞的。否则,反而会降低性能,并且下一个请求将不会在阻塞操作完成之前处理。
所有阻塞操作都必须包装在TaskExecutorInterface中,并作为单独的任务执行。
配置
要运行应用程序,您需要创建一个具有一组属性的stdObjec(以下将更详细地描述)。
预期用途是从json文件中初始化配置数据,请参阅示例server.php
$config = json_decode(file_get_contents('./config.json'));
配置参数列表
$config = new stdClass(); $config->notFoundController = 'appNameSpaceMyApp\MyNotFoundController'; $config->controllers = [ 'appNameSpaseMyApp\MyFirstControllerNamespace', 'appNameSpaseMyApp\MySecondControllerNamespace', 'appNameSpaseMyApp\MyThreeControllerNamespace', ]; $config->CyclicJobs =[ 'appNameSpaseMyApp\MyFirstCyclicJobsClass', 'appNameSpaseMyApp\MySecondCyclicJobsClass', 'appNameSpaseMyApp\MyThreeCyclicJobsClass', ];
notFoundController - 一个字符串,指定处理默认流程找不到的路由的类。此类必须实现Sidalex\SwooleApp\Classes\Controllers\ControllerInterface。
controllers - 一个数组,包含在其中递归搜索实现Sidalex\SwooleApp\Classes\Controllers\ControllerInterface接口的控制器类的命名空间。另外,对于控制器类实现,可以使用AbstractController进行继承。有关更多详细信息,请参阅此处。
CyclicJobs - 一个实现CyclicJobsInterface接口的类的数组,当应用程序启动时启动,并在一定时间间隔内循环执行。有关更多详细信息,请参阅此处。
任务
任务表示在异步执行过程之外运行的过程,可以从应用程序的任何部分调用。
为了简化任务的工作并标准化框架内的执行,已添加了一种启动这些过程的机制。要在启动Swoole服务器(server.php
)时使用此机制,您需要添加以下代码块
$http->on( 'task', function (Server $server, $taskId, $reactorId, $data) use ($app) { return $app->taskExecute($server, $taskId, $reactorId, $data); } );
如果未启动此代码块,框架将无法使用BasicTaskData类和TaskDataInterface接口。
这些过程可能包含阻塞操作。
要运行任务,您需要创建BasicTaskData类的对象或使用实现TaskDataInterface接口的自己的类。了解更多信息。
方法
任务
任务运行任务而不等待其完成。
Swoole\Server->task(Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface $data, int $dstWorkerId = -1, callable $finishCallback = null);
$data: 实现 Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface 的对象。默认情况下,推荐使用BasicTaskData类。了解更多信息。
$dstWorkerId: 工作进程ID。如果不提供,Swoole服务器将为您选择一个随机且未占用的工作进程。
$finishCallback:在任务完成之前要执行的回调。此参数为可选。
taskwait
Taskwait 运行一个任务,等待其完成并获取结果。结果等待以非阻塞方式进行。任务可以从控制器启动。
$result = Swoole\Server->taskwait((Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface $data, float $timeout = 0.5, int $dstWorkerId = -1) :TaskResulted
$data: 实现 Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface 的对象。默认情况下,推荐使用BasicTaskData类。了解更多信息。
$timeout:任务完成的超时时间(秒)。如果达到超时,将返回 false。最小值为 1 毫秒。
$dstWorkerId: 工作进程ID。如果不提供,Swoole服务器将为您选择一个随机且未占用的工作进程。
$result:任务执行的结果,应该是 TaskResulted 类的实例。更多信息请参阅这里。
BasicTaskData
BasicTaskData 类是 Sidalex\SwooleApp 框架的一部分,可以在 Classes\Tasks\Data 目录中找到。它用于创建由 Swoole Task Worker 执行的任务数据。
用法:创建 BasicTaskData 的实例,并将两个参数传递给构造函数
在任务中要创建的类名。此类必须实现 TaskExecutorInterface 接口。一个数组,包含执行任务类中包含的逻辑所需的环境数据。
$taskData = new BasicTaskData('Sidalex\TestSwoole\Tasks\TestTaskExecutor', ['test' => 'test1']);
然后将 $taskData 对象传递给 Swoole 服务器中的 taskwait() 方法,以同步执行任务并获取结果。
$taskResult = $this->server->taskwait($taskData); var_export($taskResult->getResult());
参数
类名 - 第一个参数是一个表示将在任务中创建的类名的字符串。此类必须实现 TaskExecutorInterface 接口。
环境数据 - 第二个参数是一个关联数组,包含执行任务类中包含的逻辑所需的数据。
示例
$taskData = new BasicTaskData('Sidalex\TestSwoole\Tasks\TestTaskExecutor', ['test' => 'test1']); /** * @var $taskResult TaskResulted */ $taskResult = $this->server->taskwait($taskData); var_export($taskResult->getResult());
TaskResulted
描述:TaskResulted 类表示任务执行的结果。它包含有关任务是否成功执行及其结果的信息。
属性
$success - 一个私有属性,包含有关任务执行成功的信息。
$result - 一个私有属性,包含任务执行的结果。
__construct(mixed $inData, bool $success = true) - 类构造函数,接受输入数据和有关任务执行成功的信息。
方法
getResult(): mixed - 一个返回任务执行结果的方法。它可能会抛出 TaskException 异常。
isSuccess(): bool - 一个返回有关任务执行成功信息的方法。
示例
$taskData = new BasicTaskData('Sidalex\TestSwoole\Tasks\TestTaskExecutor', ['test' => 'test1']); /** * @var $taskResult TaskResulted */ $taskResult = $this->server->taskwait($taskData); var_export($taskResult->getResult());
循环任务
这是需要定期执行代码。此机制允许您定期运行脚本。它替代了 cron。
要初始化周期性作业,您需要在配置文件中声明 CyclicJobs 参数。
使用 stdClass 初始化配置的示例
$config = new stdClass(); $config->CyclicJobs =[ "Sidalex\TestSwoole\CyclicJobs\TestCyclicJobs", ];
使用 json 文件初始化配置的示例
{ "CyclicJobs": [ "Sidalex\\TestSwoole\\CyclicJobs\\TestCyclicJobs" ] }
周期性作业的示例类
class MyCyclicJob implements CyclicJobsInterface { private $application; private $server; public function __construct(Application $application, Server $server) { $this->application = $application; $this->server = $server; } public function getTimeSleepSecond(): float { // Returns the sleep time in seconds return 5.0; } public function runJob(): void { $arr = [1,2,3,4,5,6,7,8,9]; foreach ($arr as $value){ if($value % 3 == 0) { echo "example"; } } } }
在配置中指定的任何类都必须实现 CyclicJobsInterface 接口。
getTimeSleepSecond - 返回 runJob 方法将定期执行的时间(秒)。
runJob - 一个包含有用有效载荷(业务逻辑)的方法。这是包含应该周期性执行的主要业务逻辑的代码。
控制器
要创建新的路由,请使用 Controller 类。要添加新路由,需要创建一个实现 ControllerInterface 接口的类,并将此类包含的命名空间添加到配置文件中的 "controllers" 键。更多详情请参阅此处
此外,该框架还有一个特殊的抽象类 AbstractController,它可以简化 Controller 类的创建。
要为 Controller 类创建路由,需要指定以下形式的属性
#[\Sidalex\SwooleApp\Classes\Controllers\Route(uri: '/api/{v1}/get_resume',method:"POST")] class TestController extends AbstractController {
或
use Sidalex\SwooleApp\Classes\Controllers\Route; #[Route(uri: '/api/{v1}/get_resume',method:"POST")] class TestController extends AbstractController {
对于此类,属性必须首先指定。
如果没有找到合适的控制器,将调用 NotFoundController。
uri属性参数
uri - 此参数确定此控制器将用于哪个路由。
如果指定 *,例如,/test/version/*/items,则此控制器将为对应于 /test/version/(任何字符串)/items 的 uris 工作。
如果您在路由中指定 /test/version/{version_number}/items,其行为将与使用 * 类似,但会将 $uri_params['version_number'] 添加到控制器构造函数中。
method属性参数
method - 显示调用此控制器相关的哪个方法。
请求处理
控制器类的 execute 方法包含应用程序应该为此请求执行的主要业务逻辑。此方法必须返回一个响应(\Swoole\Http\Response),它包含在
$this->response
响应
在控制器类中
$this->response
有关此类方法的更详细描述,请参阅官方 Swoole 文档
使用示例
$this->response->setHeader('Content-Type', 'application/json'); $this->response->end( json_encode( [ 'status' => 'error', 'message' => 'collection '.$this->uri_params['collection_name'] . 'not found in collectionList', ] ) );
请求
在控制器类中
$this->request;
有关此类方法的更详细描述,请参阅官方 Swoole 文档
使用示例
$obj = json_decode($this->request->getContent());
notFoundController
它设计用于处理框架路由器未找到的路由,发出 404 响应,或组织应用程序的独特路由逻辑。
要初始化,您需要在配置中传递类名。更多详细信息请这里查看
notFoundController 必须实现 ControllerInterface
示例
class NotFoundController implements ControllerInterface { private \Swoole\Http\Request $request; private \Swoole\Http\Response $responce; /** * @var array|string[] */ private array $uri_params; public function __construct(\Swoole\Http\Request $request, \Swoole\Http\Response $response, array $uri_params=[]) { $this->request = $request; $this->responce = $response; $this->uri_params = $uri_params; } public function execute(): \Swoole\Http\Response { $this->responce->setStatusCode(404); $this->responce->setHeader('Content-Type', 'application/json'); $this->responce->end(json_encode( [ 'codeStatus' => '404', 'text' => 'Page not found' ] )); return $this->responce; } public function setApplication(Application $application, Server $server) { } }
sidalex/swoole-app 是一个用于操作 swoole 的框架
安装
安装时,请执行以下命令
composer require sidalex/swoole-app
要启动 swoole 应用程序,需要创建名为 server.php 的脚本,内容如下
<?php declare(strict_types=1); require_once "./vendor/autoload.php"; use Swoole\Http\Request; use Swoole\Http\Response; use Swoole\Http\Server; use Swoole\Constant; $config = json_decode(file_get_contents('./config.json')); $http = new Server("0.0.0.0", 9501); $http->set( [ Constant::OPTION_WORKER_NUM => 2, Constant::OPTION_TASK_WORKER_NUM => (swoole_cpu_num()) * 10, ] ); $app = new \Sidalex\SwooleApp\Application($config); $http->on( "start", function (Server $http) use ($app) { echo "Swoole HTTP server is started.\n"; $app->initCyclicJobs($http); } ); $http->on( "request", function (Request $request, Response $response) use ($app,$http) { $app->execute($request, $response,$http); } ); $http->on( 'task', function (Server $server, $taskId, $reactorId, $data) use ($app) { return $app->taskExecute($server, $taskId, $reactorId, $data); } ); $http->start();
变量 $config 应该是 \stdClass,可以包含这里描述的参数
为了启动应定期执行的(非用户操作,而是按计划执行)后台进程,实现了 CyclicJobsInterface 接口,有关其使用的更详细描述这里。要自动启动后台循环进程,需要在配置中指定它们这里。
要创建应用程序的端点,需要创建控制器类,为每个端点创建一个类。或者可以通过 notFoundController 创建自己的路由规则。
CyclicJobs 和 controllers 中的所有操作都必须是非阻塞的,否则您可能会大幅降低性能,并且直到阻塞操作完成,下一个请求将无法处理。
所有阻塞操作都必须使用 TaskExecutorInterface 包装,并作为单独的 Task 执行。
配置
要启动应用程序,需要创建一个具有以下属性(以下将更详细地描述)的 stdClass
目标使用被认为是初始化配置数据(从 json 文件读取)
$config = json_decode(file_get_contents('./config.json'));
配置参数列表
$config = new stdClass(); $config->notFoundController = 'appNameSpaceMyApp\MyNotFoundController'; $config->controllers = [ 'appNameSpaseMyApp\MyFirstControllerNamespace', 'appNameSpaseMyApp\MySecondControllerNamespace', 'appNameSpaseMyApp\MyThreeControllerNamespace', ]; $config->CyclicJobs =[ 'appNameSpaseMyApp\MyFirstCyclicJobsClass', 'appNameSpaseMyApp\MySecondCyclicJobsClass', 'appNameSpaseMyApp\MyThreeCyclicJobsClass', ];
notFoundController - 处理标准流程中未找到的路由的类,该类应该实现 Sidalex\SwooleApp\Classes\Controllers\ControllerInterface
controllers - 包含控制器类的 namespace 数组,这些类将递归搜索实现 Sidalex\SwooleApp\Classes\Controllers\ControllerInterface 的控制器类。同样,为了实现控制器类,可以使用 AbstractController 继承,有关更详细的信息这里。
CyclicJobs - 包含实现 CyclicJobsInterface 的类数组,这些类在应用程序启动时启动并按指定的时间间隔循环执行。有关其使用的更详细描述这里。
Task 任务
Tasks(任务)是执行在异步执行过程之外的过程,可以在应用程序的任何部分调用。
为了简化任务的工作和标准化框架内的执行,添加了一个机制来启动这些过程。为了使用此机制,在启动 Swoole 服务器(server.php)时,需要添加以下代码块
$http->on( 'task', function (Server $server, $taskId, $reactorId, $data) use ($app) { return $app->taskExecute($server, $taskId, $reactorId, $data); } );
如果此代码块未被启动,则框架将无法与BasicTaskData类和TaskDataInterface接口协同工作。
这些过程中可能包含阻塞操作。
要启动任务,需要创建BasicTaskData类对象或使用实现TaskDataInterface接口的自己的类。更多详情请点击此处。
Task方法
task:启动任务而不等待其完成。
Swoole\Server->task(Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface $data, int $dstWorkerId = -1, callable $finishCallback = null)
$data:实现Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface接口的对象。默认建议使用BasicTaskData类。更多详情请点击此处。
$dstWorkerId:工作进程的标识号。如果未传递此参数,Swoole服务器将为您选择一个随机且未使用的进程。
$finishCallback:在任务完成前要执行的反调用。此参数是可选的。
taskwait - 启动任务并等待其完成和获取结果。结果获取是非阻塞方式。任务可以从控制器中启动。
$result = Swoole\Server->taskwait((Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface $data, float $timeout = 0.5, int $dstWorkerId = -1) :TaskResulted
$data:实现Sidalex\SwooleApp\Classes\Tasks\Data\TaskDataInterface接口的对象。默认建议使用BasicTaskData类。更多详情请点击此处。
$timeout:等待任务完成的时间(秒)。如果超时,则返回false。最小值为1毫秒。
$dstWorkerId:工作进程的标识号。如果未传递此参数,Swoole服务器将为您选择一个随机且未使用的进程。
$result:任务执行的结果,应为TaskResulted类的实例。更多详情请点击此处。
BasicTaskData类
#Sidalex\SwooleApp\Classes\Tasks\Data\BasicTaskData $taskData = new BasicTaskData('Sidalex\TestSwoole\Tasks\TestTaskExecutor', ['test' => 'test1']);
其中在构造函数中传入2个参数
1个参数('Sidalex\TestSwoole\Tasks\TestTaskExecutor') - 是将在任务中创建以执行其的类的名称。它应该实现TaskExecutorInterface接口
2个参数(['test' => 'test1']) - 是包含所需用于执行任务逻辑的数据上下文(例如'Sidalex\TestSwoole\Tasks\TestTaskExecutor'的示例)的数组
示例应用,例如在控制器或周期性作业中
$taskData = new BasicTaskData('Sidalex\TestSwoole\Tasks\TestTaskExecutor', ['test' => 'test1']); /** * @var $taskResult TaskResulted */ $taskResult = $this->server->taskwait($taskData); var_export($taskResult->getResult());
TaskResulted 类
描述:TaskResulted类代表任务的执行结果。它包含关于任务成功执行及其结果的信息。
TaskResulted类的属性
$success - 私有属性,包含有关任务成功执行的信息。
$result - 私有属性,包含任务执行的结果。
__construct(mixed $inData, bool $success = true) - 类的构造函数,接受输入数据和任务成功执行的信息。
TaskResulted类的方法
getResult(): mixed - 返回任务执行的结果。可能会抛出TaskException类型的异常。
isSuccess(): bool - 返回有关任务是否成功执行的信息。
示例
$taskData = new BasicTaskData('Sidalex\TestSwoole\Tasks\TestTaskExecutor', ['test' => 'test1']); /** * @var $taskResult TaskResulted */ $taskResult = $this->server->taskwait($taskData); var_export($taskResult->getResult());
Cyclic Job类
此代码需要周期性执行。此机制允许以固定间隔运行脚本。它替代了cron。
要初始化Cyclic Job,需要在配置文件中声明CyclicJobs参数。
使用stdClass初始化配置示例
$config = new stdClass(); $config->CyclicJobs = [ "Sidalex\TestSwoole\CyclicJobs\TestCyclicJobs", ];
使用json文件初始化配置示例
{ "CyclicJobs": [ "Sidalex\\TestSwoole\\CyclicJobs\\TestCyclicJobs" ] }
Cyclic Job类示例
class MyCyclicJob implements CyclicJobsInterface { private $application; private $server; public function __construct(Application $application, Server $server) { $this->application = $application; $this->server = $server; } public function getTimeSleepSecond(): float { // Возвращает время задержки в секундах return 5.0; } public function runJob(): void { $arr = [1,2,3,4,5,6,7,8,9]; foreach ($arr as $value){ if($value % 3 == 0) { echo "example"; } } } }
在配置中指定的任何类都必须实现CyclicJobsInterface接口。
getTimeSleepSecond方法返回周期性地执行runJob方法的时间(秒)。
runJob方法包含业务逻辑负载。这是包含需要周期性执行的业务逻辑的方法。
Controller类
使用Controller类创建新的路由。要添加新的路由,需要创建一个实现ControllerInterface接口的类,并将包含该类的命名空间添加到配置文件中,键为"controllers"。更多详情请点击此处。
框架中还有一个特殊的抽象类AbstractController,它可以简化Controller类的创建。
要为Controller类创建路由,需要指定以下类型的属性
#[\Sidalex\SwooleApp\Classes\Controllers\Route(uri: '/api/{v1}/get_resume',method:"POST")] class TestController extends AbstractController {
或
use Sidalex\SwooleApp\Classes\Controllers\Route; #[Route(uri: '/api/{v1}/get_resume',method:"POST")] class TestController extends AbstractController {
非常重要的是,必须首先指定此类属性。
如果找不到合适的控制器,将调用NotFoundController。
uri 属性参数
uri - 此参数定义了将使用此控制器的路由。
如果您在路由中指定了*,例如,/test/version/*/items,则此控制器将适用于uri,如/test/version/(任何字符串)/items。
如果您在路由中指定了/test/version/{version_number}/元素,则行为与指定*类似,但$uri_params['version_number']将被添加到控制器构造函数中。
参数属性
method - 显示调用此控制器时适合的方法。
请求处理
Controller类的execute方法包含应用程序必须为此请求执行的基本业务逻辑。此方法必须返回一个包含在
$this->response
响应
在Controller类中
$this->response
有关此类方法的更详细说明,请参阅Swoole官方文档
示例使用
$this->response->setHeader('Content-Type', 'application/json'); $this->response->end( json_encode( [ 'status' => 'error', 'message' => 'collection '.$this->uri_params['collection_name'] . 'not found in collectionList', ] ) );
请求
在控制器类中
$this->request;
有关此类方法的更详细说明,请参阅Swoole官方文档
示例使用
$obj = json_decode($this->request->getContent());
notFoundController
用于处理框架路由器未找到的路由,以返回404响应或组织应用程序的独特路由逻辑。
为了初始化,需要将类名传递给配置,有关此内容的更多详细信息,请参阅此处
notFoundController必须实现ControllerInterface
示例
class NotFoundController implements ControllerInterface { private \Swoole\Http\Request $request; private \Swoole\Http\Response $responce; /** * @var array|string[] */ private array $uri_params; public function __construct(\Swoole\Http\Request $request, \Swoole\Http\Response $response, array $uri_params=[]) { $this->request = $request; $this->responce = $response; $this->uri_params = $uri_params; } public function execute(): \Swoole\Http\Response { $this->responce->setStatusCode(404); $this->responce->setHeader('Content-Type', 'application/json'); $this->responce->end(json_encode( [ 'codeStatus' => '404', 'text' => 'Page not found' ] )); return $this->responce; } public function setApplication(Application $application, Server $server) { } }