sidalex//swoole-app

一个用于在swoole服务器上组织http服务的包

0.2.1 2024-07-28 18:51 UTC

This package is not auto-updated.

Last update: 2024-09-29 10:58:30 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License PHP Version Require

en | ru

sidalex/swoole-app Swoole工作框架

  1. 安装
  2. 配置
  3. 配置参数列表
  4. 任务
    1. 方法
  5. BasicTaskData
    1. 参数
  6. TaskResulted
    1. 属性
  7. 循环任务
  8. 控制器
    1. uri属性参数
    2. method属性参数
    3. 请求处理
    4. 响应
    5. 请求
  9. notFoundController

安装

安装,执行以下命令

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 的框架

  1. 安装
  2. 配置
    1. 配置参数列表
  3. 任务
    1. 方法
  4. BasicTaskData
  5. TaskResulted 类
    1. 属性
    2. 方法
  6. 循环任务
  7. 控制器
    1. uri 属性参数
    2. 参数属性
    3. 请求处理
    4. 响应
    5. 请求
  8. notFoundController

安装

安装时,请执行以下命令

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)
    {

    }
}