diff --git a/Abstracts/AsyncServer.php b/Abstracts/AsyncServer.php index 7b3e2b3..a8c9545 100644 --- a/Abstracts/AsyncServer.php +++ b/Abstracts/AsyncServer.php @@ -11,6 +11,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use Psr\Log\LoggerInterface; use ReflectionException; +use Swoole\Coroutine; use Swoole\Server; use Kiri\Server\ServerInterface; use Kiri\Server\Constant; @@ -21,7 +22,7 @@ use Kiri\Server\Events\OnServerBeforeStart; /** * */ -class AsyncServer +class AsyncServer implements ServerInterface { use TraitServer; diff --git a/Abstracts/CoroutineServer.php b/Abstracts/CoroutineServer.php new file mode 100644 index 0000000..ab64d4a --- /dev/null +++ b/Abstracts/CoroutineServer.php @@ -0,0 +1,200 @@ + + */ + private array $servers = []; + + + use TraitServer; + + + /** + * @param Config $config + * @param ContainerInterface $container + * @param EventDispatch $dispatch + * @param LoggerInterface $logger + * @param ProcessManager $processManager + * @param array $params + */ + public function __construct(public Config $config, + public ContainerInterface $container, + public EventDispatch $dispatch, + public LoggerInterface $logger, + public ProcessManager $processManager, + public array $params = [] + ) + { + } + + + /** + * @param string $name + * @return Server|\Swoole\Coroutine\Server|\Swoole\Coroutine\Http\Server|null + */ + public function getServer(string $name): Server|\Swoole\Coroutine\Server|\Swoole\Coroutine\Http\Server|null + { + return $this->servers[$name] ?? null; + } + + + /** + * @param array $service + * @param int $daemon + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function initCoreServers(array $service, int $daemon = 0): void + { + // TODO: Implement initCoreServers() method. + $service = $this->genConfigService($service); + foreach ($service as $value) { + $this->addListener($value); + } + } + + + /** + * @param \Kiri\Server\Config $config + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function addListener(\Kiri\Server\Config $config): void + { + // TODO: Implement addListener() method. + $class = $this->getCoroutineServerClass($config->type); + + /** @var Coroutine\Server|Coroutine\Http\Server $server */ + $server = new $class($config->host, $config->port); + $server->set($config->settings); + if ($server instanceof Server) { + $this->onTcpConnection($server, $config); + } else { + $this->onRequestCallback($server, $config); + } + + $this->servers[$config->name] = $server; + } + + + /** + * @param Coroutine\Http\Server $server + * @param \Kiri\Server\Config $config + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function onRequestCallback(Coroutine\Http\Server $server, \Kiri\Server\Config $config): void + { + $requestCallback = $config->events[Constant::REQUEST] ?? null; + if (empty($requestCallback)) { + return; + } + if (is_array($requestCallback) && is_string($requestCallback[0])) { + $requestCallback[0] = $this->container->get($requestCallback[0]); + } + $server->handle('/', function (Request $request, Response $response) use ($requestCallback) { + call_user_func($requestCallback, $request, $response); + }); + } + + + /** + * @param Coroutine\Server $server + * @param \Kiri\Server\Config $config + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function onTcpConnection(Coroutine\Server $server, \Kiri\Server\Config $config): void + { + $requestCallback = $config->events[Constant::RECEIVE] ?? null; + if (is_null($requestCallback)) { + return; + } + if (is_array($requestCallback) && is_string($requestCallback[0])) { + $requestCallback[0] = $this->container->get($requestCallback[0]); + } + $closeCallback = $config->events[Constant::CLOSE] ?? null; + $server->handle(function (Coroutine\Server\Connection $connection) use ($requestCallback, $closeCallback) { + + defer(function () use ($connection, $closeCallback) { + call_user_func($closeCallback, $connection->exportSocket()->fd); + }); + while (true) { + $read = $connection->recv(); + if ($read === null || $read === false) { + break; + } + $requestCallback($read); + } + }); + } + + + /** + * @return void + */ + public function start(): void + { + // TODO: Implement start() method. + run(function () { + $this->processManager->batch(Config::get('processes', [])); + $this->processManager->batch($this->getProcess()); + + foreach ($this->servers as $server) { + Coroutine::create(function () use ($server) { + $this->runServer($server); + }); + } + }); + } + + + /** + * @param Coroutine\Http\Server|Coroutine\Server $server + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws \ReflectionException + */ + public function runServer(Coroutine\Http\Server|Coroutine\Server $server): void + { + $this->dispatch->dispatch(new OnWorkerStart($server, 0)); + + $server->start(); + + $this->dispatch->dispatch(new OnWorkerStop($server,0)); + + $this->runServer($server); + } + + +} diff --git a/Events/OnShutdown.php b/Events/OnShutdown.php index 964f55a..c61ada4 100644 --- a/Events/OnShutdown.php +++ b/Events/OnShutdown.php @@ -2,6 +2,8 @@ namespace Kiri\Server\Events; +use Swoole\Coroutine\Http\Server as CHServer; +use Swoole\Coroutine\Server as CServer; use Swoole\Server; class OnShutdown @@ -9,9 +11,9 @@ class OnShutdown /** - * @param Server|null $server + * @param Server|CHServer|CServer|null $server */ - public function __construct(public ?Server $server = null) + public function __construct(public Server|null|CHServer|CServer $server = null) { } diff --git a/Events/OnWorkerStart.php b/Events/OnWorkerStart.php index 5addb14..44f6234 100644 --- a/Events/OnWorkerStart.php +++ b/Events/OnWorkerStart.php @@ -3,6 +3,8 @@ namespace Kiri\Server\Events; use Swoole\Server; +use Swoole\Coroutine\Server as CServer; +use Swoole\Coroutine\Http\Server as CHServer; /** * @@ -12,10 +14,10 @@ class OnWorkerStart /** - * @param Server|null $server + * @param Server|CHServer|CServer|null $server * @param int $workerId */ - public function __construct(public ?Server $server, public int $workerId) + public function __construct(public Server|null|CHServer|CServer $server, public int $workerId) { } diff --git a/Events/OnWorkerStop.php b/Events/OnWorkerStop.php index 8ad3de6..de797dc 100644 --- a/Events/OnWorkerStop.php +++ b/Events/OnWorkerStop.php @@ -2,6 +2,8 @@ namespace Kiri\Server\Events; +use Swoole\Coroutine\Http\Server as CHServer; +use Swoole\Coroutine\Server as CServer; use Swoole\Server; /** @@ -12,10 +14,10 @@ class OnWorkerStop /** - * @param Server $server + * @param Server|CHServer|CServer|null $server * @param int $workerId */ - public function __construct(public Server $server, public int $workerId) + public function __construct(public Server|null|CHServer|CServer $server, public int $workerId) { } diff --git a/ServerInterface.php b/ServerInterface.php index 4568a09..d94d313 100644 --- a/ServerInterface.php +++ b/ServerInterface.php @@ -14,8 +14,29 @@ interface ServerInterface /** * @param string $name - * @return Server|\Swoole\Coroutine\Server|\Swoole\Coroutine\Http\Server + * @return Server|\Swoole\Coroutine\Server|\Swoole\Coroutine\Http\Server|null */ - public function getServer(string $name): Server|\Swoole\Coroutine\Server|\Swoole\Coroutine\Http\Server; + public function getServer(string $name): Server|\Swoole\Coroutine\Server|\Swoole\Coroutine\Http\Server|null; + + + /** + * @param array $service + * @param int $daemon + * @return void + */ + public function initCoreServers(array $service, int $daemon = 0): void; + + + /** + * @param Config $config + * @return void + */ + public function addListener(Config $config): void; + + + /** + * @return void + */ + public function start(): void; }