From 0051f1f15c216a8f5c67cef9e567a97f20ececce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=91=E6=9E=97?= Date: Thu, 16 Jun 2022 17:38:22 +0800 Subject: [PATCH] modify plugin name --- Abstracts/AsyncServer.php | 195 ++++++++++ Abstracts/DoWhile.php | 36 ++ .../ProcessManager.php | 147 ++++---- Abstracts/Server.php | 19 +- Broadcast/Broadcast.php | 4 +- Config.php | 143 ++++++++ Contract/OnCloseInterface.php | 4 +- Contract/OnMessageInterface.php | 4 +- Contract/OnOpenInterface.php | 5 +- Contract/OnPacketInterface.php | 2 +- Events/OnProcessStop.php | 17 + Events/OnTaskerStart.php | 16 +- Events/OnWorkerStart.php | 14 +- Handler/OnServer.php | 69 +++- Handler/OnServerManager.php | 26 +- Handler/OnServerReload.php | 38 -- Handler/OnServerWorker.php | 181 +++++----- Inotify.php | 212 ----------- Scaner.php | 170 --------- Server.php | 86 ++++- ServerCommand.php | 146 +++++--- ServerInterface.php | 21 ++ ServerManager.php | 332 ------------------ SwooleServerInterface.php | 14 - TraitServer.php | 82 +++++ 25 files changed, 928 insertions(+), 1055 deletions(-) create mode 100644 Abstracts/AsyncServer.php create mode 100644 Abstracts/DoWhile.php rename ProcessManager.php => Abstracts/ProcessManager.php (55%) create mode 100644 Config.php create mode 100644 Events/OnProcessStop.php delete mode 100644 Handler/OnServerReload.php delete mode 100644 Inotify.php delete mode 100644 Scaner.php create mode 100644 ServerInterface.php delete mode 100644 ServerManager.php delete mode 100644 SwooleServerInterface.php diff --git a/Abstracts/AsyncServer.php b/Abstracts/AsyncServer.php new file mode 100644 index 0000000..006a6fc --- /dev/null +++ b/Abstracts/AsyncServer.php @@ -0,0 +1,195 @@ +genConfigService($service); + $this->createBaseServer(array_shift($service), $daemon); + foreach ($service as $value) { + $this->addListener($value); + } + $this->processManager->batch(Config::get('processes', []), $this->server); + $this->processManager->batch($this->getProcess(), $this->server); + } + + + /** + * @param string $name + * @return Server|null + */ + public function getServer(string $name = ''): Server|null + { + return $this->server; + } + + + /** + * @param \Kiri\Server\Config $config + * @param int $daemon + * @return void + * @throws ConfigException + * @throws ContainerExceptionInterface + * @throws NotFindClassException + * @throws NotFoundExceptionInterface + */ + private function createBaseServer(\Kiri\Server\Config $config, int $daemon = 0): void + { + $match = $this->getServerClass($config->type); + if (is_null($match)) { + throw new NotFindClassException('Unknown server type ' . $config->type); + } + $this->server = new $match($config->host, $config->port, SWOOLE_PROCESS, $config->mode); + + $this->server->set($this->systemConfig($config, $daemon)); + + $this->onEventListen($this->server, Config::get('server.events', [])); + + $this->container->setBindings(ServerInterface::class, $this->server); + } + + + /** + * @param \Kiri\Server\Config $config + * @param int $daemon + * @return array + * @throws Exception + * @throws ConfigException + */ + protected function systemConfig(\Kiri\Server\Config $config, int $daemon): array + { + $settings = array_merge(Config::get('server.settings', []), $config->settings); + $settings[Constant::OPTION_DAEMONIZE] = (bool)$daemon; + $settings[Constant::OPTION_ENABLE_REUSE_PORT] = true; + $settings[Constant::OPTION_PID_FILE] = storage('.swoole.pid'); + if (!isset($settings[Constant::OPTION_PID_FILE])) { + $settings[Constant::OPTION_LOG_FILE] = storage('system.log'); + } + return $settings; + } + + + /** + * @param \Kiri\Server\Config $config + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws Exception + */ + public function addListener(\Kiri\Server\Config $config): void + { + $port = $this->server->addlistener($config->host, $config->port, $config->mode); + if ($port === false) { + throw new Exception('Listen port fail.' . swoole_last_error()); + } + + $port->set($this->resetSettings($config->type, $config->settings)); + + $this->onEventListen($port, $config->getEvents()); + Kiri::app()->set($config->getName(), $port); + } + + + /** + * @param string $type + * @param array $settings + * @return array + */ + private function resetSettings(string $type, array $settings): array + { + if ($type == Constant::SERVER_TYPE_HTTP && !isset($settings['open_http_protocol'])) { + $settings['open_http_protocol'] = true; + if (in_array($this->server->setting['dispatch_mode'], [2, 4])) { + $settings['open_http2_protocol'] = true; + } + } + if ($type == Constant::SERVER_TYPE_WEBSOCKET && !isset($settings['open_websocket_protocol'])) { + $settings['open_websocket_protocol'] = true; + } + return $settings; + } + + + /** + * @param Server\Port|Server $base + * @param array $events + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private function onEventListen(Server\Port|Server $base, array $events): void + { + foreach ($events as $name => $event) { + if (is_array($event) && is_string($event[0])) { + $event[0] = $this->container->get($event[0]); + } + $base->on($name, $event); + } + } + + + /** + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ReflectionException + */ + public function start(): void + { + $this->dispatch->dispatch(new OnServerBeforeStart()); + $this->server->start(); + } + + +} diff --git a/Abstracts/DoWhile.php b/Abstracts/DoWhile.php new file mode 100644 index 0000000..6f0a33c --- /dev/null +++ b/Abstracts/DoWhile.php @@ -0,0 +1,36 @@ + */ - private array $_taskProcess = []; + /** + * @param ContainerInterface $container + * @param LoggerInterface $logger + */ + public function __construct(public ContainerInterface $container, public LoggerInterface $logger) + { + } - #[Inject(LoggerInterface::class)] - public LoggerInterface $logger; - /** * @param string|OnProcessInterface|BaseProcess $customProcess - * @param string $tag - * @return void + * @return array * @throws ConfigException */ - public function add(string|OnProcessInterface|BaseProcess $customProcess, string $tag = 'default') + public function add(string|OnProcessInterface|BaseProcess $customProcess): array { if (is_string($customProcess)) { $customProcess = Kiri::getDi()->get($customProcess); @@ -46,15 +51,41 @@ class ProcessManager $system = sprintf('[%s].Custom Process', Config::get('id', 'system-service')); $this->logger->debug($system . ' ' . $customProcess->getName() . ' start.'); - $process = $this->parse($customProcess, $system); - if (!Kiri::getDi()->has(SwooleServerInterface::class)) { - $process->start(); - } else { - $server = Kiri::getDi()->get(SwooleServerInterface::class); - - $server->addProcess($process = $this->parse($customProcess, $system)); + if (Context::inCoroutine()) { + return [$customProcess, $this->resolve($customProcess, $system)]; } - $this->_process[$tag][$customProcess->getName()] = $process; + + $process = new Process($this->resolve($customProcess, $system), + $customProcess->getRedirectStdinAndStdout(), + $customProcess->getPipeType(), + $customProcess->isEnableCoroutine() + ); + + return [$customProcess, $process]; + } + + + /** + * @param $customProcess + * @param $system + * @return Closure + */ + public function resolve($customProcess, $system): Closure + { + return static function () use ($customProcess, $system) { + $process = func_get_arg(0); + if ($process instanceof Process\Pool) { + $process = $process->getProcess(func_get_arg(1)); + } + set_env('environmental', Kiri::PROCESS); + if (Kiri::getPlatform()->isLinux()) { + $process->name($system . '(' . $customProcess->getName() . ')'); + } + $dispatcher = Kiri::getDi()->get(EventDispatch::class); + $dispatcher->dispatch(new OnProcessStart()); + $customProcess->onSigterm()->process($process); + $dispatcher->dispatch(new OnProcessStop($process)); + }; } @@ -82,66 +113,56 @@ class ProcessManager /** * @return void */ - public function stop() + public function stop(): void { foreach ($this->_process as $process) { $process->exit(0); } - foreach ($this->_taskProcess as $process) { - $process->exit(0); - } - } - - - /** - * @param $customProcess - * @param $system - * @return Process - */ - private function parse($customProcess, $system): Process - { - return new Process(static function (Process $process) use ($customProcess, $system) { - if (Kiri::getPlatform()->isLinux()) { - $process->name($system . '(' . $customProcess->getName() . ')'); - } - - Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnProcessStart()); - - set_env('environmental', Kiri::PROCESS); -// $channel = Coroutine::create(function () use ($process, $customProcess) { -// while (!$customProcess->isStop()) { -// $message = $process->read(); -// if (!empty($message)) { -// $message = unserialize($message); -// } -// if (is_null($message)) { -// continue; -// } -// $customProcess->onBroadcast($message); -// } -// }); -// Context::setContext('waite:process:message', $channel); - - $customProcess->onSigterm()->process($process); - }, - $customProcess->getRedirectStdinAndStdout(), - $customProcess->getPipeType(), - $customProcess->isEnableCoroutine() - ); } /** * @param array $processes - * @param string $tag + * @param \Swoole\Server|null $server * @return void * @throws ConfigException */ - public function batch(array $processes, string $tag = 'default') + public function batch(array $processes, ?\Swoole\Server $server = null): void { - foreach ($processes as $process) { - $this->add($process, $tag); + $processes = array_merge($processes, Config::get('processes', [])); + + if (Context::inCoroutine()) { + $this->poolManager($processes); + return; } + + foreach ($processes as $process) { + [$customProcess, $sProcess] = $this->add($process); + + $this->_process[$customProcess->getName()] = $customProcess; + + $server->addProcess($sProcess); + } + } + + + /** + * @param array $processes + * @return void + * @throws ConfigException + */ + protected function poolManager(array $processes): void + { + $manager = new Process\Manager(); + foreach ($processes as $process) { + /** @var BaseProcess $customProcess */ + [$customProcess, $sProcess] = $this->add($process); + + $this->_process[$customProcess->getName()] = $customProcess; + + $manager->add($sProcess, $customProcess->isEnableCoroutine()); + } + $manager->start(); } @@ -151,7 +172,7 @@ class ProcessManager * @param string $tag * @return void */ - public function push(string $message, string $name = '', string $tag = 'default') + public function push(string $message, string $name = '', string $tag = 'default'): void { $processes = $this->_process; if (!empty($this->_process[$name])) { diff --git a/Abstracts/Server.php b/Abstracts/Server.php index 67a3e53..44bac55 100644 --- a/Abstracts/Server.php +++ b/Abstracts/Server.php @@ -21,29 +21,12 @@ abstract class Server /** - * @var LoggerInterface + * @var LoggerInterface */ #[Inject(LoggerInterface::class)] public LoggerInterface $logger; - /** - * @param $prefix - * @throws ConfigException - */ - protected function setProcessName($prefix) - { - if (Kiri::getPlatform()->isMac()) { - return; - } - $name = '[' . Config::get('id', 'system-service') . ']'; - if (!empty($prefix)) { - $name .= '.' . $prefix; - } - swoole_set_process_name($name); - } - - /** * Server constructor. * @throws Exception diff --git a/Broadcast/Broadcast.php b/Broadcast/Broadcast.php index 95f7a65..d477517 100644 --- a/Broadcast/Broadcast.php +++ b/Broadcast/Broadcast.php @@ -4,7 +4,7 @@ namespace Kiri\Server\Broadcast; use Kiri; use Kiri\Server\ProcessManager; -use Kiri\Server\SwooleServerInterface; +use Kiri\Server\ServerInterface; class Broadcast { @@ -19,7 +19,7 @@ class Broadcast $di = Kiri::getDi(); $di->get(ProcessManager::class)->push($message); - $server = $di->get(SwooleServerInterface::class); + $server = $di->get(ServerInterface::class); $total = $server->setting['worker_num'] + $server->setting['task_worker_num']; for ($i = 0; $i < $total; $i++) { diff --git a/Config.php b/Config.php new file mode 100644 index 0000000..c2490e4 --- /dev/null +++ b/Config.php @@ -0,0 +1,143 @@ +type; + } + + /** + * @param string $type + */ + public function setType(string $type): void + { + $this->type = $type; + } + + /** + * @return string + */ + public function getHost(): string + { + return $this->host; + } + + /** + * @param string $host + */ + public function setHost(string $host): void + { + $this->host = $host; + } + + /** + * @return int + */ + public function getPort(): int + { + return $this->port; + } + + /** + * @param int $port + */ + public function setPort(int $port): void + { + $this->port = $port; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * @return int + */ + public function getMode(): int + { + return $this->mode; + } + + /** + * @param int $mode + */ + public function setMode(int $mode): void + { + $this->mode = $mode; + } + + /** + * @return array + */ + public function getSettings(): array + { + return $this->settings; + } + + /** + * @param array $settings + */ + public function setSettings(array $settings): void + { + $this->settings = $settings; + } + + /** + * @return array + */ + public function getEvents(): array + { + return $this->events; + } + + /** + * @param array $events + */ + public function setEvents(array $events): void + { + $this->events = $events; + } + +} diff --git a/Contract/OnCloseInterface.php b/Contract/OnCloseInterface.php index 9e0fb79..ccc9dc9 100644 --- a/Contract/OnCloseInterface.php +++ b/Contract/OnCloseInterface.php @@ -13,11 +13,11 @@ interface OnCloseInterface /** - * @param Server $server + * @param Server|\Swoole\Coroutine\Http\Server $server * @param int $fd * @return void */ - public function onClose(Server $server, int $fd): void; + public function onClose(Server|\Swoole\Coroutine\Http\Server $server, int $fd): void; } diff --git a/Contract/OnMessageInterface.php b/Contract/OnMessageInterface.php index f127ea5..0d68e05 100644 --- a/Contract/OnMessageInterface.php +++ b/Contract/OnMessageInterface.php @@ -10,10 +10,10 @@ interface OnMessageInterface /** - * @param Server $server + * @param Server|\Swoole\Coroutine\Http\Server $server * @param Frame $frame * @return void */ - public function onMessage(Server $server, Frame $frame): void; + public function onMessage(Server|\Swoole\Coroutine\Http\Server $server, Frame $frame): void; } diff --git a/Contract/OnOpenInterface.php b/Contract/OnOpenInterface.php index 4c33071..084c683 100644 --- a/Contract/OnOpenInterface.php +++ b/Contract/OnOpenInterface.php @@ -4,16 +4,17 @@ namespace Kiri\Server\Contract; use Swoole\Http\Request; use Swoole\WebSocket\Server; +use Swoole\Coroutine\Http\Server as HServer; interface OnOpenInterface { /** - * @param Server $server + * @param Server|HServer $server * @param Request $request * @return void */ - public function onOpen(Server $server, Request $request): void; + public function onOpen(Server|HServer $server, Request $request): void; } diff --git a/Contract/OnPacketInterface.php b/Contract/OnPacketInterface.php index 8f6130f..f420989 100644 --- a/Contract/OnPacketInterface.php +++ b/Contract/OnPacketInterface.php @@ -12,7 +12,7 @@ interface OnPacketInterface * @param Server $server * @param string $data * @param array $clientInfo - * @return mixed + * @return void */ public function onPacket(Server $server, string $data, array $clientInfo): void; diff --git a/Events/OnProcessStop.php b/Events/OnProcessStop.php new file mode 100644 index 0000000..1640772 --- /dev/null +++ b/Events/OnProcessStop.php @@ -0,0 +1,17 @@ +setProcessName(sprintf('start[%d].server', $server->master_pid)); + \Kiri::setProcessName(sprintf('start[%d].server', $server->master_pid)); - \Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnStart($server)); + $this->dispatch->dispatch(new OnStart($server)); } /** - * @param \Swoole\Server $server + * @param SServer $server + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface * @throws ReflectionException */ - public function onBeforeShutdown(\Swoole\Server $server) + public function onBeforeShutdown(SServer $server) { - \Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnBeforeShutdown($server)); + $this->dispatch->dispatch(new OnBeforeShutdown($server)); } /** - * @param \Swoole\Server $server + * @param SServer $server + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface * @throws ReflectionException */ - public function onShutdown(\Swoole\Server $server) + public function onShutdown(SServer $server) { - \Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnShutdown($server)); + $this->dispatch->dispatch(new OnShutdown($server)); } + /** + * @param SServer $server + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ReflectionException + */ + public function onBeforeReload(SServer $server) + { + $this->dispatch->dispatch(new OnBeforeReload($server)); + } + + + /** + * @param SServer $server + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ReflectionException + */ + public function onAfterReload(SServer $server) + { + $this->dispatch->dispatch(new OnAfterReload($server)); + } + + + } diff --git a/Handler/OnServerManager.php b/Handler/OnServerManager.php index e5ad813..6d35f6b 100644 --- a/Handler/OnServerManager.php +++ b/Handler/OnServerManager.php @@ -2,8 +2,11 @@ namespace Kiri\Server\Handler; +use Kiri; use Kiri\Annotation\Inject; use Kiri\Events\EventDispatch; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; use ReflectionException; use Kiri\Server\Abstracts\Server; use Kiri\Exception\ConfigException; @@ -18,26 +21,39 @@ use Kiri\Server\Events\OnManagerStop; class OnServerManager extends Server { + /** + * @param EventDispatch $dispatch + * @throws \Exception + */ + public function __construct(public EventDispatch $dispatch) + { + parent::__construct(); + } /** - * @param \Swoole\Server $server - * @throws ConfigException|ReflectionException + * @param \Swoole\Server $server + * @throws ConfigException + * @throws ReflectionException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface */ public function onManagerStart(\Swoole\Server $server) { - $this->setProcessName(sprintf('manger[%d].0', $server->manager_pid)); + Kiri::setProcessName(sprintf('manger[%d].0', $server->manager_pid)); - \Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnManagerStart($server)); + $this->dispatch->dispatch(new OnManagerStart($server)); } /** * @param \Swoole\Server $server + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface * @throws ReflectionException */ public function onManagerStop(\Swoole\Server $server) { - \Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnManagerStop($server)); + $this->dispatch->dispatch(new OnManagerStop($server)); } diff --git a/Handler/OnServerReload.php b/Handler/OnServerReload.php deleted file mode 100644 index 371bae6..0000000 --- a/Handler/OnServerReload.php +++ /dev/null @@ -1,38 +0,0 @@ -get(EventDispatch::class)->dispatch(new OnBeforeReload($server)); - } - - - /** - * @param Server $server - * @throws \ReflectionException - */ - public function onAfterReload(Server $server) - { - \Kiri::getDi()->get(EventDispatch::class)->dispatch(new OnAfterReload($server)); - } - -} diff --git a/Handler/OnServerWorker.php b/Handler/OnServerWorker.php index 3b0df93..3058293 100644 --- a/Handler/OnServerWorker.php +++ b/Handler/OnServerWorker.php @@ -30,111 +30,100 @@ class OnServerWorker extends \Kiri\Server\Abstracts\Server { - public Router $router; + /** + * @param EventDispatch $dispatch + * @param Router $router + * @throws Exception + */ + public function __construct(public EventDispatch $dispatch, public Router $router) + { + parent::__construct(); + } - public EventDispatch $dispatch; + /** + * @param Server $server + * @param int $workerId + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws Exception + */ + public function onWorkerStart(Server $server, int $workerId): void + { + $this->dispatch->dispatch(new OnBeforeWorkerStart($workerId)); + set_env('environmental_workerId', $workerId); + if ($workerId < $server->setting['worker_num']) { + $this->dispatch->dispatch(new OnWorkerStart($server, $workerId)); + } else { + $this->dispatch->dispatch(new OnTaskStart($server, $workerId)); + } + $this->dispatch->dispatch(new OnAfterWorkerStart()); + } - /** - * @return void - */ - public function init() - { - $this->dispatch = Kiri::getDi()->get(EventDispatch::class); - $this->router = Kiri::getDi()->get(Router::class); - } + /** + * @param Server $server + * @param int $workerId + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface|ReflectionException + */ + public function onWorkerStop(Server $server, int $workerId) + { + $this->dispatch->dispatch(new OnWorkerStop($server, $workerId)); + } - /** - * @param Server $server - * @param int $workerId - * @return void - * @throws Kiri\Exception\ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws Exception - */ - public function onWorkerStart(Server $server, int $workerId) - { - $this->dispatch->dispatch(new OnBeforeWorkerStart($workerId)); - set_env('environmental_workerId', $workerId); - if ($workerId < $server->setting['worker_num']) { - set_env('environmental', Kiri::WORKER); - $this->setProcessName(sprintf('Worker Process[%d].%d', $server->worker_pid, $workerId)); - $this->dispatch->dispatch(new OnWorkerStart($server, $workerId)); - } else { - set_env('environmental', Kiri::TASK); - $this->setProcessName(sprintf('Tasker Process[%d].%d', $server->worker_pid, $workerId)); - $this->dispatch->dispatch(new OnTaskStart($server, $workerId)); - } - $this->dispatch->dispatch(new OnAfterWorkerStart()); - } + /** + * @param Server $server + * @param int $workerId + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface|ReflectionException + */ + public function onWorkerExit(Server $server, int $workerId) + { + $this->dispatch->dispatch(new OnWorkerExit($server, $workerId)); + } - /** - * @param Server $server - * @param int $workerId - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface|ReflectionException - */ - public function onWorkerStop(Server $server, int $workerId) - { - Timer::clearAll(); - $this->dispatch->dispatch(new OnWorkerStop($server, $workerId)); - } + /** + * @param Server $server + * @param int $worker_id + * @param int $worker_pid + * @param int $exit_code + * @param int $signal + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws Exception + */ + public function onWorkerError(Server $server, int $worker_id, int $worker_pid, int $exit_code, int $signal) + { + $this->dispatch->dispatch(new OnWorkerError($server, $worker_id, $worker_pid, $exit_code, $signal)); + + $message = sprintf('Worker#%d::%d error stop. signal %d, exit_code %d, msg %s', + $worker_id, $worker_pid, $signal, $exit_code, swoole_strerror(swoole_last_error(), 9) + ); + + $this->logger->error($message); + + $this->system_mail($message); + } - /** - * @param Server $server - * @param int $workerId - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface|ReflectionException - */ - public function onWorkerExit(Server $server, int $workerId) - { - $this->dispatch->dispatch(new OnWorkerExit($server, $workerId)); - } - - - /** - * @param Server $server - * @param int $worker_id - * @param int $worker_pid - * @param int $exit_code - * @param int $signal - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws Exception - */ - public function onWorkerError(Server $server, int $worker_id, int $worker_pid, int $exit_code, int $signal) - { - $this->dispatch->dispatch(new OnWorkerError($server, $worker_id, $worker_pid, $exit_code, $signal)); - - $message = sprintf('Worker#%d::%d error stop. signal %d, exit_code %d, msg %s', - $worker_id, $worker_pid, $signal, $exit_code, swoole_strerror(swoole_last_error(), 9) - ); - - $this->logger->error($message); - - $this->system_mail($message); - } - - - /** - * @param $messageContent - * @throws Exception - */ - protected function system_mail($messageContent) - { - try { - $email = Config::get('email', ['enable' => false]); - if (!empty($email) && ($email['enable'] ?? false) == true) { - Help::sendEmail($email, 'Service Error', $messageContent); - } - } catch (\Throwable $e) { - error($e, 'email'); - } - } + /** + * @param $messageContent + * @throws Exception + */ + protected function system_mail($messageContent) + { + try { + $email = Config::get('email', ['enable' => false]); + if (!empty($email) && ($email['enable'] ?? false)) { + Help::sendEmail($email, 'Service Error', $messageContent); + } + } catch (\Throwable $e) { + error($e, 'email'); + } + } } diff --git a/Inotify.php b/Inotify.php deleted file mode 100644 index d7568db..0000000 --- a/Inotify.php +++ /dev/null @@ -1,212 +0,0 @@ -isStop()) { - break; - } - sleep(1); - } - return; - } - $this->dirs = Config::get('reload.inotify', []); - $this->start(); - } - - - public function onSigterm(): static - { - pcntl_signal(SIGTERM, function () { - $this->isStop = true; - }); - return $this; - } - - - /** - * @return void - */ - public function error(): void - { - - } - - - /** - * @throws Exception - */ - public function start() - { - $this->inotify = inotify_init(); - $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; - foreach ($this->dirs as $dir) { - if (!is_dir($dir)) continue; - $this->watch($dir); - } - Event::add($this->inotify, [$this, 'check']); - Event::cycle(function () { - if ($this->isStop()) { - Event::del($this->inotify); - Event::exit(); - } - }, true); - Event::wait(); - } - - - /** - * 开始监听 - * @throws Exception - */ - public function check() - { - if (!($events = inotify_read($this->inotify))) { - return; - } - if ($this->isReloading) { - return; - } - - $LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM]; - foreach ($events as $ev) { - if (!in_array($ev['mask'], $LISTEN_TYPE)) { - continue; - } - - //非重启类型 - if (str_ends_with($ev['name'], '.php')) { - if ($this->isReloading) { - break; - } - $this->isReloading = TRUE; - Timer::after(3000, fn() => $this->reload()); - } - } - } - - /** - * @throws Exception - */ - public function reload() - { - $swollen = \Kiri::getDi()->get(SwooleServerInterface::class); - - $swollen->reload(); - - $this->clearWatch(); - foreach ($this->dirs as $root) { - $this->watch($root); - } - $this->isReloading = FALSE; - } - - - /** - * @throws Exception - */ - public function clearWatch() - { - foreach ($this->watchFiles as $wd) { - @inotify_rm_watch($this->inotify, $wd); - } - $this->watchFiles = []; - } - - - /** - * @param $dir - * @return bool - * @throws Exception - */ - public function watch($dir): bool - { - //目录不存在 - if (!is_dir($dir)) { - return $this->logger->addError("[$dir] is not a directory."); - } - //避免重复监听 - if (isset($this->watchFiles[$dir])) { - return FALSE; - } - - if (in_array($dir, self::IG_DIR)) { - return FALSE; - } - - $wd = @inotify_add_watch($this->inotify, $dir, $this->events); - $this->watchFiles[$dir] = $wd; - - $files = scandir($dir); - foreach ($files as $f) { - if ($f == '.' || $f == '..') { - continue; - } - $path = $dir . '/' . $f; - //递归目录 - if (is_dir($path)) { - $this->watch($path); - } else if (!str_ends_with($f, '.php')) { - continue; - } - //检测文件类型 - if (strstr($f, '.') == '.php') { - $wd = @inotify_add_watch($this->inotify, $path, $this->events); - $this->watchFiles[$path] = $wd; - } - } - return TRUE; - } -} diff --git a/Scaner.php b/Scaner.php deleted file mode 100644 index 7161466..0000000 --- a/Scaner.php +++ /dev/null @@ -1,170 +0,0 @@ -dirs = Config::get('reload.inotify', []); - - $this->loadDirs(); - $this->tick(); - } - - - /** - * @param bool $isReload - * @throws Exception - */ - private function loadDirs(bool $isReload = FALSE) - { - foreach ($this->dirs as $value) { - if (is_bool($path = realpath($value))) { - continue; - } - - if (!is_dir($path)) continue; - - $this->loadByDir($path, $isReload); - } - } - - - /** - * @param $path - * @param bool $isReload - * @return void - * @throws Exception - */ - private function loadByDir($path, bool $isReload = FALSE): void - { - if (!is_string($path)) { - return; - } - $path = rtrim($path, '/'); - foreach (glob(realpath($path) . '/*') as $value) { - if (is_dir($value)) { - $this->loadByDir($value, $isReload); - } - if (is_file($value)) { - if ($this->checkFile($value, $isReload)) { - if ($this->isReloading) { - break; - } - $this->isReloading = TRUE; - - sleep(2); - - $this->timerReload(); - break; - } - } - } - } - - - /** - * @param $value - * @param $isReload - * @return bool - */ - private function checkFile($value, $isReload): bool - { - $md5 = md5($value); - $mTime = filectime($value); - if (!isset($this->md5Map[$md5])) { - if ($isReload) { - return TRUE; - } - $this->md5Map[$md5] = $mTime; - } else { - if ($this->md5Map[$md5] != $mTime) { - if ($isReload) { - return TRUE; - } - $this->md5Map[$md5] = $mTime; - } - } - return FALSE; - } - - - /** - * @throws Exception - */ - public function timerReload() - { - $this->isReloading = TRUE; - - $this->logger->warning('file change'); - - $swow = \Kiri::getDi()->get(SwooleServerInterface::class); - - $swow->reload(); - - $this->loadDirs(); - - $this->isReloading = FALSE; - - $this->tick(); - } - - - /** - * @return $this - */ - public function onSigterm(): static - { - pcntl_signal(SIGTERM, function () { - $this->onProcessStop(); - }); - return $this; - } - - - /** - * @throws Exception - */ - public function tick() - { - if ($this->isStop) { - return; - } - - $this->loadDirs(TRUE); - - sleep(2); - - $this->tick(); - } - -} diff --git a/Server.php b/Server.php index e362102..d44d208 100644 --- a/Server.php +++ b/Server.php @@ -20,10 +20,13 @@ use Kiri\Server\Events\OnBeforeShutdown; use Kiri\Server\Events\OnServerBeforeStart; use Kiri\Server\Events\OnShutdown; use Kiri\Server\Events\OnWorkerStart; +use Kiri\Server\Events\OnTaskerStart; use Psr\Container\ContainerExceptionInterface; -use Psr\Container\ContainerInterface; +use Kiri\Di\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; +use Kiri\Server\Events\OnWorkerStop; use ReflectionException; +use Kiri\Reload\Scaner; use Swoole\WebSocket\Server as WsServer; use Swoole\Server as SServer; use Swoole\Http\Server as HServer; @@ -47,7 +50,7 @@ class Server extends HttpService /** * @param State $state - * @param ServerManager $manager + * @param AsyncServer $manager * @param ContainerInterface $container * @param ProcessManager $processManager * @param EventDispatch $dispatch @@ -57,7 +60,7 @@ class Server extends HttpService * @throws Exception */ public function __construct(public State $state, - public ServerManager $manager, + public AsyncServer $manager, public ContainerInterface $container, public ProcessManager $processManager, public EventDispatch $dispatch, @@ -72,14 +75,9 @@ class Server extends HttpService /** * @return void * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface */ public function init(): void { - $this->container->mapping(ResponseInterface::class, Response::class); - $this->container->mapping(RequestInterface::class, Request::class); - $enable_coroutine = Config::get('servers.settings.enable_coroutine', false); if (!$enable_coroutine) { return; @@ -112,23 +110,78 @@ class Server extends HttpService */ public function start(): void { - $this->manager->initBaseServer(Config::get('server', [], true), $this->daemon); + $this->manager->initCoreServers(Config::get('server', [], true), $this->daemon); $rpcService = Config::get('rpc', []); if (!empty($rpcService)) { - $this->manager->addListener($rpcService['type'], $rpcService['host'], $rpcService['port'], $rpcService['mode'], $rpcService); + /** @var \Kiri\Server\Config $create */ + $create = $this->container->create(\Kiri\Server\Config::class, null, $rpcService); + $this->manager->addListener($create); } + pcntl_signal(SIGINT, [$this, 'onSigint']); + $this->onHotReload(); - pcntl_signal(SIGINT, [$this, 'onSigint']); - $processes = array_merge($this->process, Config::get('processes', [])); - $this->processManager->batch($processes); + $this->processManager->batch($this->process, $this->manager->getServer()); $this->dispatch->dispatch(new OnServerBeforeStart()); $this->manager->start(); } + /** + * @return void + */ + protected function onWorkerListener(): void + { + $this->provider->on(OnWorkerStop::class, '\Swoole\Timer::clearAll'); + $this->provider->on(OnWorkerStart::class, [$this, 'setWorkerName']); + $this->provider->on(OnTaskerStart::class, [$this, 'setTaskerName']); + } + + + /** + * @param OnWorkerStart $onWorkerStart + * @throws ConfigException + */ + protected function setWorkerName(OnWorkerStart $onWorkerStart): void + { + $prefix = sprintf('Worker Process[%d].%d', $onWorkerStart->server->worker_pid, $onWorkerStart->workerId); + set_env('environmental', Kiri::WORKER); + + $this->setProcessName($prefix); + } + + + /** + * @param OnWorkerStart $onWorkerStart + * @throws ConfigException + */ + protected function setTaskerName(OnWorkerStart $onWorkerStart): void + { + $prefix = sprintf('Worker Process[%d].%d', $onWorkerStart->server->worker_pid, $onWorkerStart->workerId); + set_env('environmental', Kiri::WORKER); + + $this->setProcessName($prefix); + } + + + /** + * @param $prefix + * @throws ConfigException + */ + protected function setProcessName($prefix): void + { + if (Kiri::getPlatform()->isMac()) { + return; + } + $name = '[' . Config::get('id', 'system-service') . ']'; + if (!empty($prefix)) { + $name .= '.' . $prefix; + } + swoole_set_process_name($name); + } + /** * @return void * @throws ConfigException @@ -136,13 +189,14 @@ class Server extends HttpService */ public function onHotReload(): void { + $this->onWorkerListener(); $reload = Config::get('reload.hot', false); if ($reload !== false) { - $this->provider->on(OnWorkerStart::class, [$this, 'onWorkerStart']); + $this->provider->on(OnWorkerStart::class, [$this, 'LoadRoutingList']); $this->process[] = Scaner::class; } else { - $this->onWorkerStart(); + $this->LoadRoutingList(); } } @@ -167,7 +221,7 @@ class Server extends HttpService * @throws ReflectionException * @throws Exception */ - public function onWorkerStart(): void + public function LoadRoutingList(): void { scan_directory(MODEL_PATH, 'app\Model'); diff --git a/ServerCommand.php b/ServerCommand.php index c22e2e2..1cd5fdb 100644 --- a/ServerCommand.php +++ b/ServerCommand.php @@ -10,6 +10,7 @@ use Kiri\Abstracts\Config; use Kiri\Exception\ConfigException; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; +use ReflectionException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -24,67 +25,100 @@ class ServerCommand extends Command { - const ACTIONS = ['start', 'stop', 'restart']; + const ACTIONS = ['start', 'stop', 'restart']; - /** - * - */ - protected function configure() - { - $this->setName('sw:server') - ->setDescription('server start|stop|reload|restart') - ->addArgument('action', InputArgument::OPTIONAL, 'run action', 'start') - ->addOption('daemon', 'd', InputOption::VALUE_OPTIONAL, 'is run daemonize'); - } + /** + * @return void + */ + protected function configure(): void + { + $this->setName('sw:server') + ->setDescription('server start|stop|reload|restart') + ->addArgument('action', InputArgument::OPTIONAL, 'run action', 'start') + ->addOption('daemon', 'd', InputOption::VALUE_OPTIONAL, 'is run daemonize'); + } - /** - * @param InputInterface $input - * @param OutputInterface $output - * @return int - * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws \ReflectionException - * @throws Exception - */ - public function execute(InputInterface $input, OutputInterface $output): int - { - $manager = Kiri::app()->getServer(); - $manager->setDaemon((int)!is_null($input->getOption('daemon'))); - - $this->scan_file(); - - $action = $input->getArgument('action'); - if (is_null($action)) { - throw new Exception('I don\'t know what I want to do.'); - } - if (!in_array($action, self::ACTIONS)) { - throw new Exception('I don\'t know what I want to do.'); - } - if ($action == 'restart' || $action == 'stop') { - $manager->shutdown(); - if ($action == 'stop') { - return 1; - } - } - $manager->start(); - return 1; - } + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + * @throws ConfigException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ReflectionException + * @throws Exception + */ + public function execute(InputInterface $input, OutputInterface $output): int + { + return match ($input->getArgument('action')) { + 'restart' => $this->restart($input), + 'stop' => $this->stop(), + 'start' => $this->start($input), + default => + throw new Exception('I don\'t know what I want to do.') + }; + } - /** - * @return void - * @throws ConfigException - * @throws \ReflectionException - */ - protected function scan_file(): void - { - $config = Config::get('reload.scanner', []); - if (is_array($config)) foreach ($config as $key => $value) { - scan_directory($value, $key); - } - } + /** + * @param InputInterface $input + * @return int + * @throws ConfigException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface|ReflectionException + */ + protected function restart(InputInterface $input): int + { + $this->stop(); + $this->start($input); + return 1; + } + + + /** + * @return int + * @throws ConfigException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + protected function stop(): int + { + $manager = Kiri::app()->getServer(); + $manager->shutdown(); + return 1; + } + + + /** + * @param InputInterface $input + * @return int + * @throws ConfigException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface|ReflectionException + */ + protected function start(InputInterface $input): int + { + $this->scan_file(); + $manager = Kiri::app()->getServer(); + $manager->setDaemon((int)!is_null($input->getOption('daemon'))); + $manager->start(); + return 1; + } + + + /** + * @return void + * @throws ConfigException + * @throws ReflectionException + */ + protected function scan_file(): void + { + $config = Config::get('reload.scanner', []); + if (is_array($config)) foreach ($config as $key => $value) { + scan_directory($value, $key); + } + } } diff --git a/ServerInterface.php b/ServerInterface.php new file mode 100644 index 0000000..4568a09 --- /dev/null +++ b/ServerInterface.php @@ -0,0 +1,21 @@ + */ - public array $ports = []; - - public int $mode = SWOOLE_TCP; - - - private Server|null $server = null; - - - const DEFAULT_EVENT = [ - Constant::WORKER_START => [OnServerWorker::class, 'onWorkerStart'], - Constant::WORKER_EXIT => [OnServerWorker::class, 'onWorkerExit'], - Constant::WORKER_STOP => [OnServerWorker::class, 'onWorkerStop'], - Constant::WORKER_ERROR => [OnServerWorker::class, 'onWorkerError'], - Constant::MANAGER_START => [OnServerManager::class, 'onManagerStart'], - Constant::MANAGER_STOP => [OnServerManager::class, 'onManagerStop'], - Constant::START => [OnServer::class, 'onStart'], - Constant::SHUTDOWN => [OnServer::class, 'onShutdown'], - ]; - - - /** - * @var array|string[] - */ - private array $eventInterface = [ - OnReceiveInterface::class => 'receive', - OnPacketInterface::class => 'packet', - OnHandshakeInterface::class => 'handshake', - OnMessageInterface::class => 'message', - OnConnectInterface::class => 'connect', - OnCloseInterface::class => 'close', - OnDisconnectInterface::class => 'disconnect' - ]; - - - /** - * @return Server|WServer|HServer|null - */ - public function getServer(): Server|WServer|HServer|null - { - return $this->server; - } - - - /** - * @param ContainerInterface $container - * @param TaskManager $manager - * @param array $config - * @throws Exception - */ - public function __construct(public ContainerInterface $container, - public TaskManager $manager, array $config = []) - { - parent::__construct($config); - } - - /** - * @param string $type - * @param string $host - * @param int $port - * @param int $mode - * @param array $settings - * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function addListener(string $type, string $host, int $port, int $mode, array $settings = []) - { - if (!$this->server) { - $this->createBaseServer($type, $host, $port, $mode, $settings); - } else { - if (!isset($settings['settings'])) { - $settings['settings'] = []; - } - $this->addNewListener($type, $host, $port, $mode, $settings); - } - } - - - /** - * @param $configs - * @param int $daemon - * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function initBaseServer($configs, int $daemon = 0): void - { - $context = di(ServerManager::class); - foreach ($this->sortService($configs['ports']) as $config) { - $this->startListenerHandler($context, $config, $daemon); - } - $this->bindPipeMessage(); - } - - - /** - * @return void - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function bindPipeMessage(): void - { - $pipeMessage = $this->container->get(OnPipeMessage::class); - $this->server->on(Constant::PIPE_MESSAGE, [$pipeMessage, 'onPipeMessage']); - - if (!isset($this->server->setting['task_worker_num']) || $this->server->setting['task_worker_num'] < 1) { - return; - } - $this->manager->taskListener($this->server); - } - - - /** - * @return array - */ - public function getSetting(): array - { - return $this->server->setting; - } - - - /** - * @param ServerManager $context - * @param array $config - * @param int $daemon - * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws Exception - */ - private function startListenerHandler(ServerManager $context, array $config, int $daemon = 0) - { - if (!$this->server) { - $config = $this->mergeConfig($config, $daemon); - } - $context->addListener( - $config['type'], $config['host'], $config['port'], $config['mode'], - $config); - } - - - /** - * @param $config - * @param $daemon - * @return array - * @throws Exception - */ - private function mergeConfig($config, $daemon): array - { - $config['settings'] = $config['settings'] ?? []; - $config['settings']['daemonize'] = $daemon; - if (!isset($config['settings']['log_file'])) { - $config['settings']['log_file'] = storage('system.log'); - } - $config['settings']['pid_file'] = storage('.swoole.pid'); - $config['settings'][Constant::OPTION_ENABLE_REUSE_PORT] = true; - $config['events'] = $config['events'] ?? []; - return $config; - } - - - /** - * @param string $type - * @param string $host - * @param int $port - * @param int $mode - * @param array $settings - * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws Exception - */ - private function addNewListener(string $type, string $host, int $port, int $mode, array $settings = []) - { - $id = Config::get('id', 'system-service'); - - $this->logger->alert(sprintf('[%s].' . $type . ' service %s::%d start', $id, $host, $port)); - - /** @var Server\Port $service */ - $this->ports[$port] = $this->server->addlistener($host, $port, $mode); - if ($this->ports[$port] === false) { - throw new Exception("The port is already in use[$host::$port]"); - } - - $this->addServiceEvents($settings['events'] ?? [], $this->ports[$port]); - - $this->ports[$port]->set($this->resetSettings($type, $settings)); - } - - - /** - * @param string $type - * @param array $settings - * @return array - */ - private function resetSettings(string $type, array $settings): array - { - if ($type == Constant::SERVER_TYPE_HTTP && !isset($settings['settings']['open_http_protocol'])) { - $settings['settings']['open_http_protocol'] = true; - if (in_array($this->server->setting['dispatch_mode'], [2, 4])) { - $settings['settings']['open_http2_protocol'] = true; - } - } - if ($type == Constant::SERVER_TYPE_WEBSOCKET && !isset($settings['settings']['open_websocket_protocol'])) { - $settings['settings']['open_websocket_protocol'] = true; - } - return $settings['settings'] ?? []; - } - - - /** - * @param string $type - * @param string $host - * @param int $port - * @param int $mode - * @param array $settings - * @throws ConfigException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws Exception - */ - private function createBaseServer(string $type, string $host, int $port, int $mode, array $settings = []) - { - $match = match ($type) { - Constant::SERVER_TYPE_BASE, Constant::SERVER_TYPE_TCP, - Constant::SERVER_TYPE_UDP => Server::class, - Constant::SERVER_TYPE_HTTP => HServer::class, - Constant::SERVER_TYPE_WEBSOCKET => WServer::class - }; - $this->server = new $match($host, $port, SWOOLE_PROCESS, $mode); - $this->server->set(array_merge(Config::get('server.settings', []), $settings['settings'])); - - $this->container->setBindings(SwooleServerInterface::class, $this->server); - $this->container->setBindings(Emitter::class, ResponseEmitter::class); - - $id = Config::get('id', 'system-service'); - - $this->logger->alert(sprintf('[%s].' . $type . ' service %s::%d start', $id, $host, $port)); - - $this->addDefaultListener($settings); - } - - - /** - * @param array $settings - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function addDefaultListener(array $settings): void - { - $this->addServiceEvents(ServerManager::DEFAULT_EVENT, $this->server); - if (!empty($settings['events']) && is_array($settings['events'])) { - $this->addServiceEvents($settings['events'], $this->server); - } - } - - - /** - * @param array $events - * @param Server|Port $server - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - private function addServiceEvents(array $events, Server|Port $server) - { - foreach ($events as $name => $event) { - if (is_array($event) && is_string($event[0])) { - $event[0] = $this->container->get($event[0]); - } - $server->on($name, $event); - } - } - - - /** - * - */ - public function start() - { - $this->server->start(); - } - - -} diff --git a/SwooleServerInterface.php b/SwooleServerInterface.php deleted file mode 100644 index 53e4ca7..0000000 --- a/SwooleServerInterface.php +++ /dev/null @@ -1,14 +0,0 @@ -_process[] = $class; + } + + + /** + * @return array + */ + public function getProcess(): array + { + return $this->_process; + } + + /** * @param array $ports * @return array @@ -29,4 +55,60 @@ trait TraitServer return $array; } + + /** + * @param array $ports + * @return array + */ + public function genConfigService(array $ports): array + { + $array = []; + foreach ($ports as $port) { + $config = \Kiri::getDi()->create(Config::class, [], $port); + if ($port['type'] == Constant::SERVER_TYPE_WEBSOCKET) { + array_unshift($array, $config); + } else if ($port['type'] == Constant::SERVER_TYPE_HTTP) { + if (!empty($array) && $array[0]['type'] == Constant::SERVER_TYPE_WEBSOCKET) { + $array[] = $config; + } else { + array_unshift($array, $config); + } + } else { + $array[] = $config; + } + } + return $array; + } + + + /** + * @param $type + * @return string|null + */ + public function getServerClass($type): ?string + { + return match ($type) { + Constant::SERVER_TYPE_BASE, Constant::SERVER_TYPE_TCP, + Constant::SERVER_TYPE_UDP => Server::class, + Constant::SERVER_TYPE_HTTP => HServer::class, + Constant::SERVER_TYPE_WEBSOCKET => WServer::class, + default => null + }; + } + + + /** + * @param $type + * @return string|null + */ + public function getCoroutineServerClass($type): ?string + { + return match ($type) { + Constant::SERVER_TYPE_BASE, Constant::SERVER_TYPE_TCP, Constant::SERVER_TYPE_UDP => Server::class, + Constant::SERVER_TYPE_HTTP, Constant::SERVER_TYPE_WEBSOCKET => \Swoole\Coroutine\Http\Server::class, + default => null + }; + } + + }