diff --git a/Database/DatabasesProviders.php b/Database/DatabasesProviders.php index 2d5e192b..95fd686c 100644 --- a/Database/DatabasesProviders.php +++ b/Database/DatabasesProviders.php @@ -71,7 +71,7 @@ class DatabasesProviders extends Providers */ public function createPool() { - $databases = Config::get('databases', false, []); + $databases = Config::get('databases', []); if (empty($databases)) { return; } @@ -101,7 +101,7 @@ class DatabasesProviders extends Providers */ public function getConfig($name): mixed { - return Config::get('databases.' . $name, true); + return Config::get('databases.' . $name,null, true); } diff --git a/HttpServer/Abstracts/Callback.php b/HttpServer/Abstracts/Callback.php index 533d625f..a09bed7c 100644 --- a/HttpServer/Abstracts/Callback.php +++ b/HttpServer/Abstracts/Callback.php @@ -27,141 +27,141 @@ abstract class Callback extends HttpService { - /** - * @param $server - * @param $worker_id - * @param $message - * @throws Exception - */ - protected function clear(Server $server, $worker_id, $message) - { - try { - /** @var Process $logger */ - $logger = Snowflake::app()->get(LoggerProcess::class); - $logger->write(Json::encode([$this->_MESSAGE[$message] . $worker_id, 'log/app'])); + /** + * @param $server + * @param $worker_id + * @param $message + * @throws Exception + */ + protected function clear(Server $server, $worker_id, $message) + { + try { + /** @var Process $logger */ + $logger = Snowflake::app()->get(LoggerProcess::class); + $logger->write(Json::encode([$this->_MESSAGE[$message] . $worker_id, 'log/app'])); - $this->eventNotify($message); - } catch (\Throwable $exception) { - $this->addError($exception,'throwable'); - } - } + $this->eventNotify($message); + } catch (\Throwable $exception) { + $this->addError($exception, 'throwable'); + } + } - const EVENT_ERROR = 'WORKER:ERROR'; - const EVENT_STOP = 'WORKER:STOP'; - const EVENT_EXIT = 'WORKER:EXIT'; + const EVENT_ERROR = 'WORKER:ERROR'; + const EVENT_STOP = 'WORKER:STOP'; + const EVENT_EXIT = 'WORKER:EXIT'; - private array $_MESSAGE = [ - self::EVENT_ERROR => 'The server error. at No.', - self::EVENT_STOP => 'The server stop. at No.', - self::EVENT_EXIT => 'The server exit. at No.', - ]; + private array $_MESSAGE = [ + self::EVENT_ERROR => 'The server error. at No.', + self::EVENT_STOP => 'The server stop. at No.', + self::EVENT_EXIT => 'The server exit. at No.', + ]; - /** - * @param $message - * @throws Exception - */ - private function eventNotify($message) - { - switch ($message) { - case self::EVENT_ERROR: - fire(Event::SERVER_WORKER_ERROR); - break; - case self::EVENT_EXIT: - fire(Event::SERVER_WORKER_EXIT); - break; - case self::EVENT_STOP: - fire(Event::SERVER_WORKER_STOP); - break; - } - } + /** + * @param $message + * @throws Exception + */ + private function eventNotify($message) + { + switch ($message) { + case self::EVENT_ERROR: + fire(Event::SERVER_WORKER_ERROR); + break; + case self::EVENT_EXIT: + fire(Event::SERVER_WORKER_EXIT); + break; + case self::EVENT_STOP: + fire(Event::SERVER_WORKER_STOP); + break; + } + } - /** - * @return PHPMailer - * @throws \PHPMailer\PHPMailer\Exception - * @throws ConfigException - */ - private function createEmail(): PHPMailer - { - $mail = new PHPMailer(true); - $mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output - $mail->isSMTP(); // Send using SMTP - $mail->Host = Config::get('email.host'); // Set the SMTP server to send through - $mail->SMTPAuth = true; // Enable SMTP authentication - $mail->Debugoutput = false; // Enable SMTP authentication - $mail->CharSet = "UTF8"; // Enable SMTP authentication - $mail->Username = Config::get('email.username'); // SMTP username - $mail->Password = Config::get('email.password'); // SMTP password - $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged - $mail->Port = Config::get('email.port'); // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above - $mail->setFrom(Config::get('email.send.address'), Config::get('email.send.nickname')); - return $mail; - } + /** + * @return PHPMailer + * @throws \PHPMailer\PHPMailer\Exception + * @throws ConfigException + */ + private function createEmail(): PHPMailer + { + $mail = new PHPMailer(true); + $mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output + $mail->isSMTP(); // Send using SMTP + $mail->Host = Config::get('email.host'); // Set the SMTP server to send through + $mail->SMTPAuth = true; // Enable SMTP authentication + $mail->Debugoutput = false; // Enable SMTP authentication + $mail->CharSet = "UTF8"; // Enable SMTP authentication + $mail->Username = Config::get('email.username'); // SMTP username + $mail->Password = Config::get('email.password'); // SMTP password + $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged + $mail->Port = Config::get('email.port'); // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above + $mail->setFrom(Config::get('email.send.address'), Config::get('email.send.nickname')); + return $mail; + } - /** - * @param $message - * @throws - */ - protected function system_mail($message) - { - try { - if (!Config::get('email.enable', false, false)) { - return; - } - $mail = $this->createEmail(); - $receives = Config::get('email.receive'); - if (empty($receives) || !is_array($receives)) { - throw new Exception('接收人信息错误'); - } - foreach ($receives as $receive) { - $mail->addAddress($receive['address'], $receive['nickname']); // Add a recipient - } - $mail->isHTML(true); // Set email format to HTML - $mail->Subject = 'service error'; - $mail->Body = $message; - $mail->AltBody = $message; - $mail->send(); - } catch (\Throwable $e) { - $this->addError($e, 'email'); - } - } + /** + * @param $message + * @throws + */ + protected function system_mail($message) + { + try { + if (!Config::get('email.enable', false)) { + return; + } + $mail = $this->createEmail(); + $receives = Config::get('email.receive'); + if (empty($receives) || !is_array($receives)) { + throw new Exception('接收人信息错误'); + } + foreach ($receives as $receive) { + $mail->addAddress($receive['address'], $receive['nickname']); // Add a recipient + } + $mail->isHTML(true); // Set email format to HTML + $mail->Subject = 'service error'; + $mail->Body = $message; + $mail->AltBody = $message; + $mail->send(); + } catch (\Throwable $e) { + $this->addError($e, 'email'); + } + } - /** - * @throws ConfigException - * @throws ComponentException - * @throws Exception - */ - protected function clearMysqlClient() - { - $databases = Config::get('databases', false, []); - if (empty($databases)) { - return; - } - $application = Snowflake::app(); - foreach ($databases as $name => $database) { - /** @var Connection $connection */ - $connection = $application->get('databases.' . $name, false); - if (empty($connection)) { - continue; - } - $connection->disconnect(); - } - } + /** + * @throws ConfigException + * @throws ComponentException + * @throws Exception + */ + protected function clearMysqlClient() + { + $databases = Config::get('databases', []); + if (empty($databases)) { + return; + } + $application = Snowflake::app(); + foreach ($databases as $name => $database) { + /** @var Connection $connection */ + $connection = $application->get('databases.' . $name, false); + if (empty($connection)) { + continue; + } + $connection->disconnect(); + } + } - /** - * @throws ConfigException - * @throws ComponentException - * @throws Exception - */ - protected function clearRedisClient() - { - $redis = Snowflake::app()->getRedis(); - $redis->destroy(); - } + /** + * @throws ConfigException + * @throws ComponentException + * @throws Exception + */ + protected function clearRedisClient() + { + $redis = Snowflake::app()->getRedis(); + $redis->destroy(); + } } diff --git a/HttpServer/Http/Request.php b/HttpServer/Http/Request.php index fa0d1c3e..dbca976d 100644 --- a/HttpServer/Http/Request.php +++ b/HttpServer/Http/Request.php @@ -535,7 +535,7 @@ class Request extends HttpService $port = $sRequest->clientInfo['server_port']; - $rpc = Config::get('rpc.port', false, []); + $rpc = Config::get('rpc.port', []); if ($rpc !== $port) { $sRequest->headers->replace('request_uri', 'add-port-listen/port_' . $port); $sRequest->headers->replace('request_method', 'listen'); diff --git a/HttpServer/Route/Router.php b/HttpServer/Route/Router.php index 20be621e..a9461304 100644 --- a/HttpServer/Route/Router.php +++ b/HttpServer/Route/Router.php @@ -61,7 +61,7 @@ class Router extends HttpService implements RouterInterface */ public function init() { - $this->dir = Config::get('http.namespace', false, $this->dir); + $this->dir = Config::get('http.namespace', $this->dir); } diff --git a/HttpServer/Server.php b/HttpServer/Server.php index 0ead7c2d..3dd55810 100644 --- a/HttpServer/Server.php +++ b/HttpServer/Server.php @@ -48,478 +48,478 @@ defined('PID_PATH') or define('PID_PATH', APP_PATH . 'storage/server.pid'); class Server extends HttpService { - const HTTP = 'HTTP'; - const TCP = 'TCP'; - const PACKAGE = 'PACKAGE'; - const WEBSOCKET = 'WEBSOCKET'; - - private array $listening = []; - private array $server = [ - 'HTTP' => [SWOOLE_TCP, Http::class], - 'TCP' => [SWOOLE_TCP, Receive::class], - 'PACKAGE' => [SWOOLE_UDP, Packet::class], - 'WEBSOCKET' => [SWOOLE_SOCK_TCP, Websocket::class], - ]; - - private Packet|Websocket|Receive|null|Http $swoole = null; - - public int $daemon = 0; - - - private array $listenTypes = []; - - - private array $process = [ - 'biomonitoring' => Biomonitoring::class, - 'logger_process' => LoggerProcess::class - ]; - - private array $params = []; - - - /** - * @param $name - * @param $process - * @param array $params - */ - public function addProcess($name, $process, $params = []) - { - $this->process[$name] = $process; - $this->params[$name] = $params; - } - - - /** - * @return array - */ - public function getProcesses(): array - { - return $this->process ?? []; - } - - - /** - * @param $configs - * @return Packet|Websocket|Receive|Http|null - * @throws Exception - */ - private function initCore($configs): Packet|Websocket|Receive|Http|null - { - $servers = $this->sortServers($configs); - foreach ($servers as $server) { - $this->create($server); - if (!$this->swoole) { - throw new Exception('Base service create fail.'); - } - } - return $this->startRpcService(); - } - - - /** - * @return string start server - * - * start server - * @throws ConfigException - * @throws Exception - */ - public function start(): string - { - $configs = Config::get('servers', true); - - $baseServer = $this->initCore($configs); - if (!$baseServer) { - return 'ok'; - } - - Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL ^ SWOOLE_HOOK_BLOCKING_FUNCTION); - - Coroutine::set(['enable_deadlock_check' => false]); - - return $this->execute($baseServer); - } - - - /** - * @param $baseServer - * @return mixed - * @throws Exception - */ - private function execute($baseServer): mixed - { - $app = Snowflake::app(); - $app->set('base-server', $baseServer); - return $baseServer->start(); - } - - - /** - * @param $host - * @param $Port - * @return Packet|Websocket|Receive|Http|null - * @throws Exception - */ - public function error_stop($host, $Port): Packet|Websocket|Receive|Http|null - { - $this->error(sprintf('Port %s::%d is already.', $host, $Port)); - if ($this->swoole) { - $this->swoole->shutdown(); - } else { - $this->shutdown(); - } - return $this->swoole; - } - - - /** - * @return bool - * @throws ConfigException - * @throws Exception - */ - public function isRunner(): bool - { - $port = $this->sortServers(Config::get('servers')); - if (empty($port)) { - return false; - } - foreach ($port as $value) { - if ($this->checkPort($value['port'])) { - return true; - } - } - return false; - } - - - /** - * @param $port - * @return bool - * @throws Exception - */ - private function checkPort($port): bool - { - if (Snowflake::getPlatform()->isLinux()) { - exec('netstat -tunlp | grep ' . $port, $output); - } else { - exec('lsof -i :' . $port . ' | grep -i "LISTEN"', $output); - } - return !empty($output); - } - - - /** - * @return void - * - * start server - * @throws Exception - */ - public function shutdown() - { - /** @var Shutdown $shutdown */ - $shutdown = Snowflake::app()->get('shutdown'); - $shutdown->shutdown(); - } - - - /** - * @throws ConfigException - * @throws Exception - */ - public function onProcessListener(): void - { - if (!($this->swoole instanceof \Swoole\Server)) { - return; - } - - $processes = Config::get('processes'); - if (!empty($processes) && is_array($processes)) { - $this->deliveryProcess(merge($processes, $this->process)); - } else { - $this->deliveryProcess($this->process); - } - } - - - /** - * @param $processes - * @throws Exception - */ - private function deliveryProcess($processes) - { - $application = Snowflake::app(); - if (empty($processes) || !is_array($processes)) { - return; - } - foreach ($processes as $name => $process) { - $this->debug(sprintf('Process %s', $process)); - if (!is_string($process)) { - continue; - } - $system = Snowflake::createObject($process, [Snowflake::app(), $name, true]); - if (isset($this->params[$name]) && !empty($this->params[$name])) { - $system->write(swoole_serialize($this->params[$name])); - } - $this->swoole->addProcess($system); - $application->set($process, $system); - } - } - - - /** - * @param $daemon - * @return Server - */ - public function setDaemon($daemon): static - { - if (!in_array($daemon, [0, 1])) { - return $this; - } - $this->daemon = $daemon; - return $this; - } - - - /** - * @return Packet|Websocket|Receive|Http|null - */ - public function getServer(): Packet|Websocket|Receive|Http|null - { - return $this->swoole; - } - - - /** - * @param $config - * @return mixed - * @throws Exception - */ - private function create($config): mixed - { - $settings = Config::get('settings', false, []); - if (!isset($this->server[$config['type']])) { - throw new Exception('Unknown server type(' . $config['type'] . ').'); - } - $server = $this->dispatchCreate($config, $settings); - if (isset($config['events'])) { - $this->createEventListen($config); - } - return $server; - } - - - /** - * @param $config - * @throws Exception - */ - protected function createEventListen($config) - { - if (!is_array($config['events'])) { - return; - } - $event = Snowflake::app()->getEvent(); - foreach ($config['events'] as $name => $_event) { - $event->on('listen ' . $config['port'] . ' ' . $name, $_event); - } - } - - /** - * @param $config - * @param $settings - * @return \Swoole\Server|Packet|Receive|Http|Websocket|null - * @throws NotFindClassException - * @throws ReflectionException - * @throws Exception - */ - private function dispatchCreate($config, $settings): \Swoole\Server|Packet|Receive|Http|Websocket|null - { - if (Snowflake::port_already($config['port'])) { - return $this->error_stop($config['host'], $config['port']); - } - if (!($this->swoole instanceof \Swoole\Server)) { - return $this->parseServer($config, $settings); - } - return $this->addListener($config); - } - - - /** - * @param $config - * @return Http|Packet|Receive|Websocket|null - * @throws NotFindClassException - * @throws ReflectionException - * @throws Exception - */ - private function addListener($config): Packet|Websocket|Receive|Http|null - { - $newListener = $this->swoole->addlistener($config['host'], $config['port'], $config['mode']); - if (!$newListener) { - exit($this->addError(sprintf('Listen %s::%d fail.', $config['host'], $config['port']))); - } - - if (isset($config['settings']) && is_array($config['settings'])) { - $newListener->set($config['settings']); - } - $this->onListenerBind($config, $this->swoole); - - return $this->swoole; - } - - - /** - * @return Packet|Websocket|Receive|Http|null - * @throws ConfigException - * @throws Exception - */ - private function startRpcService(): Packet|Websocket|Receive|Http|null - { - $rpcService = Config::get('rpc.enable', false, []); - if ($rpcService === true) { - /** @var Service $service */ - $service = Snowflake::app()->get('rpc-service'); - $service->instance($this->swoole); - } - return $this->swoole; - } - - - /** - * @param $config - * @param $settings - * @return Packet|Websocket|Receive|Http|null - * @throws Exception - */ - private function parseServer($config, $settings): Packet|Websocket|Receive|Http|null - { - $class = $this->dispatch($config['type']); - if (is_array($config['settings'] ?? null)) { - $settings = array_merge($settings, $config['settings']); - } - $this->swoole = $this->createServer($class, $config); - $settings['daemonize'] = $this->daemon; - if (!isset($settings['pid_file'])) { - $settings['pid_file'] = PID_PATH; - } - - $this->debug(Snowflake::listen($config)); - $this->swoole->set($settings); - $this->onProcessListener(); - - return $this->swoole; - } - - - /** - * @param $class - * @param $config - * @return mixed - */ - private function createServer($class, $config): mixed - { - return new $class($config['host'], $config['port'], SWOOLE_PROCESS, $config['mode']); - } - - - /** - * @param $listen - * @return bool - */ - #[Pure] public function isListen($listen): bool - { - return in_array($listen, $this->listenTypes); - } - - - /** - * @param $config - * @param $newListener - * @return Packet|Websocket|Receive|Http|null - * @throws NotFindClassException - * @throws ReflectionException - * @throws Exception - */ - private function onListenerBind($config, $newListener): Packet|Websocket|Receive|Http|null - { - if (!in_array($config['type'], [self::HTTP, self::TCP, self::PACKAGE])) { - throw new Exception('Unknown server type(' . $config['type'] . ').'); - } - if ($config['type'] == self::HTTP && !$this->swoole->getCallback('request')) { - $this->onBindCallback('request', [make(OnRequest::class), 'onHandler']); - } else { - $this->noHttp($newListener, $config); - } - $this->debug(sprintf('Check listen %s::%d -> ok', $config['host'], $config['port'])); - $this->listenTypes[] = $config['type']; - return $this->swoole; - } - - - /** - * @param $newListener - * @param $config - * @throws Exception - */ - private function noHttp($newListener, $config) - { - $this->onBindCallback('connect', [make(OnConnect::class), 'onHandler']); - $this->onBindCallback('close', [make(OnClose::class), 'onHandler']); - if ($config['type'] == self::TCP) { - $this->onBindCallback('receive', [make(OnReceive::class), 'onHandler']); - } else { - $this->onBindCallback('packet', [make(OnPacket::class), 'onHandler']); - } - } - - - /** - * @param $name - * @param $callback - * @throws Exception - */ - public function onBindCallback($name, $callback) - { - if ($this->swoole->getCallback($name) !== null) { - return; - } - $this->swoole->on($name, $callback); - } - - - /** - * @param $type - * @return string - */ - private function dispatch($type): string - { - return match ($type) { - self::HTTP => Http::class, - self::WEBSOCKET => Websocket::class, - self::PACKAGE => Packet::class, - default => Receive::class - }; - } - - /** - * @param $servers - * @return array - */ - private function sortServers($servers): array - { - $array = []; - foreach ($servers as $server) { - switch ($server['type']) { - case self::WEBSOCKET: - array_unshift($array, $server); - break; - case self::HTTP: - case self::PACKAGE | self::TCP: - $array[] = $server; - break; - default: - $array[] = $server; - } - } - return $array; - } + const HTTP = 'HTTP'; + const TCP = 'TCP'; + const PACKAGE = 'PACKAGE'; + const WEBSOCKET = 'WEBSOCKET'; + + private array $listening = []; + private array $server = [ + 'HTTP' => [SWOOLE_TCP, Http::class], + 'TCP' => [SWOOLE_TCP, Receive::class], + 'PACKAGE' => [SWOOLE_UDP, Packet::class], + 'WEBSOCKET' => [SWOOLE_SOCK_TCP, Websocket::class], + ]; + + private Packet|Websocket|Receive|null|Http $swoole = null; + + public int $daemon = 0; + + + private array $listenTypes = []; + + + private array $process = [ + 'biomonitoring' => Biomonitoring::class, + 'logger_process' => LoggerProcess::class + ]; + + private array $params = []; + + + /** + * @param $name + * @param $process + * @param array $params + */ + public function addProcess($name, $process, $params = []) + { + $this->process[$name] = $process; + $this->params[$name] = $params; + } + + + /** + * @return array + */ + public function getProcesses(): array + { + return $this->process ?? []; + } + + + /** + * @param $configs + * @return Packet|Websocket|Receive|Http|null + * @throws Exception + */ + private function initCore($configs): Packet|Websocket|Receive|Http|null + { + $servers = $this->sortServers($configs); + foreach ($servers as $server) { + $this->create($server); + if (!$this->swoole) { + throw new Exception('Base service create fail.'); + } + } + return $this->startRpcService(); + } + + + /** + * @return string start server + * + * start server + * @throws ConfigException + * @throws Exception + */ + public function start(): string + { + $configs = Config::get('servers', [], true); + + $baseServer = $this->initCore($configs); + if (!$baseServer) { + return 'ok'; + } + + Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL ^ SWOOLE_HOOK_BLOCKING_FUNCTION); + + Coroutine::set(['enable_deadlock_check' => false]); + + return $this->execute($baseServer); + } + + + /** + * @param $baseServer + * @return mixed + * @throws Exception + */ + private function execute($baseServer): mixed + { + $app = Snowflake::app(); + $app->set('base-server', $baseServer); + return $baseServer->start(); + } + + + /** + * @param $host + * @param $Port + * @return Packet|Websocket|Receive|Http|null + * @throws Exception + */ + public function error_stop($host, $Port): Packet|Websocket|Receive|Http|null + { + $this->error(sprintf('Port %s::%d is already.', $host, $Port)); + if ($this->swoole) { + $this->swoole->shutdown(); + } else { + $this->shutdown(); + } + return $this->swoole; + } + + + /** + * @return bool + * @throws ConfigException + * @throws Exception + */ + public function isRunner(): bool + { + $port = $this->sortServers(Config::get('servers')); + if (empty($port)) { + return false; + } + foreach ($port as $value) { + if ($this->checkPort($value['port'])) { + return true; + } + } + return false; + } + + + /** + * @param $port + * @return bool + * @throws Exception + */ + private function checkPort($port): bool + { + if (Snowflake::getPlatform()->isLinux()) { + exec('netstat -tunlp | grep ' . $port, $output); + } else { + exec('lsof -i :' . $port . ' | grep -i "LISTEN"', $output); + } + return !empty($output); + } + + + /** + * @return void + * + * start server + * @throws Exception + */ + public function shutdown() + { + /** @var Shutdown $shutdown */ + $shutdown = Snowflake::app()->get('shutdown'); + $shutdown->shutdown(); + } + + + /** + * @throws ConfigException + * @throws Exception + */ + public function onProcessListener(): void + { + if (!($this->swoole instanceof \Swoole\Server)) { + return; + } + + $processes = Config::get('processes'); + if (!empty($processes) && is_array($processes)) { + $this->deliveryProcess(merge($processes, $this->process)); + } else { + $this->deliveryProcess($this->process); + } + } + + + /** + * @param $processes + * @throws Exception + */ + private function deliveryProcess($processes) + { + $application = Snowflake::app(); + if (empty($processes) || !is_array($processes)) { + return; + } + foreach ($processes as $name => $process) { + $this->debug(sprintf('Process %s', $process)); + if (!is_string($process)) { + continue; + } + $system = Snowflake::createObject($process, [Snowflake::app(), $name, true]); + if (isset($this->params[$name]) && !empty($this->params[$name])) { + $system->write(swoole_serialize($this->params[$name])); + } + $this->swoole->addProcess($system); + $application->set($process, $system); + } + } + + + /** + * @param $daemon + * @return Server + */ + public function setDaemon($daemon): static + { + if (!in_array($daemon, [0, 1])) { + return $this; + } + $this->daemon = $daemon; + return $this; + } + + + /** + * @return Packet|Websocket|Receive|Http|null + */ + public function getServer(): Packet|Websocket|Receive|Http|null + { + return $this->swoole; + } + + + /** + * @param $config + * @return mixed + * @throws Exception + */ + private function create($config): mixed + { + $settings = Config::get('settings', []); + if (!isset($this->server[$config['type']])) { + throw new Exception('Unknown server type(' . $config['type'] . ').'); + } + $server = $this->dispatchCreate($config, $settings); + if (isset($config['events'])) { + $this->createEventListen($config); + } + return $server; + } + + + /** + * @param $config + * @throws Exception + */ + protected function createEventListen($config) + { + if (!is_array($config['events'])) { + return; + } + $event = Snowflake::app()->getEvent(); + foreach ($config['events'] as $name => $_event) { + $event->on('listen ' . $config['port'] . ' ' . $name, $_event); + } + } + + /** + * @param $config + * @param $settings + * @return \Swoole\Server|Packet|Receive|Http|Websocket|null + * @throws NotFindClassException + * @throws ReflectionException + * @throws Exception + */ + private function dispatchCreate($config, $settings): \Swoole\Server|Packet|Receive|Http|Websocket|null + { + if (Snowflake::port_already($config['port'])) { + return $this->error_stop($config['host'], $config['port']); + } + if (!($this->swoole instanceof \Swoole\Server)) { + return $this->parseServer($config, $settings); + } + return $this->addListener($config); + } + + + /** + * @param $config + * @return Http|Packet|Receive|Websocket|null + * @throws NotFindClassException + * @throws ReflectionException + * @throws Exception + */ + private function addListener($config): Packet|Websocket|Receive|Http|null + { + $newListener = $this->swoole->addlistener($config['host'], $config['port'], $config['mode']); + if (!$newListener) { + exit($this->addError(sprintf('Listen %s::%d fail.', $config['host'], $config['port']))); + } + + if (isset($config['settings']) && is_array($config['settings'])) { + $newListener->set($config['settings']); + } + $this->onListenerBind($config, $this->swoole); + + return $this->swoole; + } + + + /** + * @return Packet|Websocket|Receive|Http|null + * @throws ConfigException + * @throws Exception + */ + private function startRpcService(): Packet|Websocket|Receive|Http|null + { + $rpcService = Config::get('rpc.enable', []); + if ($rpcService === true) { + /** @var Service $service */ + $service = Snowflake::app()->get('rpc-service'); + $service->instance($this->swoole); + } + return $this->swoole; + } + + + /** + * @param $config + * @param $settings + * @return Packet|Websocket|Receive|Http|null + * @throws Exception + */ + private function parseServer($config, $settings): Packet|Websocket|Receive|Http|null + { + $class = $this->dispatch($config['type']); + if (is_array($config['settings'] ?? null)) { + $settings = array_merge($settings, $config['settings']); + } + $this->swoole = $this->createServer($class, $config); + $settings['daemonize'] = $this->daemon; + if (!isset($settings['pid_file'])) { + $settings['pid_file'] = PID_PATH; + } + + $this->debug(Snowflake::listen($config)); + $this->swoole->set($settings); + $this->onProcessListener(); + + return $this->swoole; + } + + + /** + * @param $class + * @param $config + * @return mixed + */ + private function createServer($class, $config): mixed + { + return new $class($config['host'], $config['port'], SWOOLE_PROCESS, $config['mode']); + } + + + /** + * @param $listen + * @return bool + */ + #[Pure] public function isListen($listen): bool + { + return in_array($listen, $this->listenTypes); + } + + + /** + * @param $config + * @param $newListener + * @return Packet|Websocket|Receive|Http|null + * @throws NotFindClassException + * @throws ReflectionException + * @throws Exception + */ + private function onListenerBind($config, $newListener): Packet|Websocket|Receive|Http|null + { + if (!in_array($config['type'], [self::HTTP, self::TCP, self::PACKAGE])) { + throw new Exception('Unknown server type(' . $config['type'] . ').'); + } + if ($config['type'] == self::HTTP && !$this->swoole->getCallback('request')) { + $this->onBindCallback('request', [make(OnRequest::class), 'onHandler']); + } else { + $this->noHttp($newListener, $config); + } + $this->debug(sprintf('Check listen %s::%d -> ok', $config['host'], $config['port'])); + $this->listenTypes[] = $config['type']; + return $this->swoole; + } + + + /** + * @param $newListener + * @param $config + * @throws Exception + */ + private function noHttp($newListener, $config) + { + $this->onBindCallback('connect', [make(OnConnect::class), 'onHandler']); + $this->onBindCallback('close', [make(OnClose::class), 'onHandler']); + if ($config['type'] == self::TCP) { + $this->onBindCallback('receive', [make(OnReceive::class), 'onHandler']); + } else { + $this->onBindCallback('packet', [make(OnPacket::class), 'onHandler']); + } + } + + + /** + * @param $name + * @param $callback + * @throws Exception + */ + public function onBindCallback($name, $callback) + { + if ($this->swoole->getCallback($name) !== null) { + return; + } + $this->swoole->on($name, $callback); + } + + + /** + * @param $type + * @return string + */ + private function dispatch($type): string + { + return match ($type) { + self::HTTP => Http::class, + self::WEBSOCKET => Websocket::class, + self::PACKAGE => Packet::class, + default => Receive::class + }; + } + + /** + * @param $servers + * @return array + */ + private function sortServers($servers): array + { + $array = []; + foreach ($servers as $server) { + switch ($server['type']) { + case self::WEBSOCKET: + array_unshift($array, $server); + break; + case self::HTTP: + case self::PACKAGE | self::TCP: + $array[] = $server; + break; + default: + $array[] = $server; + } + } + return $array; + } } diff --git a/Kafka/KafkaProviders.php b/Kafka/KafkaProviders.php index dd744a7e..ba0a720c 100644 --- a/Kafka/KafkaProviders.php +++ b/Kafka/KafkaProviders.php @@ -36,7 +36,7 @@ class KafkaProviders extends Providers return; } - $kafkaServers = Config::get('kafka.servers', false, []); + $kafkaServers = Config::get('kafka.servers', []); if (empty($kafkaServers)) { return; } diff --git a/System/Abstracts/BaseApplication.php b/System/Abstracts/BaseApplication.php index a4250d03..a4cf223c 100644 --- a/System/Abstracts/BaseApplication.php +++ b/System/Abstracts/BaseApplication.php @@ -156,7 +156,7 @@ abstract class BaseApplication extends Service foreach ($config as $key => $value) { Config::set($key, $value); } - if ($storage = Config::get('storage', false, 'storage')) { + if ($storage = Config::get('storage', 'storage')) { if (!str_contains($storage, APP_PATH)) { $storage = APP_PATH . $storage . '/'; } diff --git a/System/Abstracts/Config.php b/System/Abstracts/Config.php index 90e8273e..77fb69cc 100644 --- a/System/Abstracts/Config.php +++ b/System/Abstracts/Config.php @@ -53,7 +53,7 @@ class Config extends Component * @return mixed * @throws */ - public static function get($key, $try = FALSE, $default = null): mixed + public static function get($key, $default = null, $try = FALSE): mixed { $instance = Snowflake::app()->getConfig()->getData(); if (!str_contains($key, '.')) { diff --git a/System/Abstracts/Pool.php b/System/Abstracts/Pool.php index 4e71a713..72e4081d 100644 --- a/System/Abstracts/Pool.php +++ b/System/Abstracts/Pool.php @@ -40,8 +40,8 @@ abstract class Pool extends Component */ private function getClearTime(): array { - $firstClear = Config::get('pool.clear.start', false, 600); - $lastClear = Config::get('pool.clear.end', false, 300); + $firstClear = Config::get('pool.clear.start', 600); + $lastClear = Config::get('pool.clear.end', 300); return [$firstClear, $lastClear]; } diff --git a/System/Error/Logger.php b/System/Error/Logger.php index f4f263b7..e09699c1 100644 --- a/System/Error/Logger.php +++ b/System/Error/Logger.php @@ -112,7 +112,7 @@ class Logger extends Component */ public function print_r($message, $method = '') { - $debug = Config::get('debug', false, ['enable' => false]); + $debug = Config::get('debug', ['enable' => false]); if ((bool)$debug['enable'] === true) { if (!is_callable($debug['callback'] ?? null, true)) { return; diff --git a/System/Jwt/Jwt.php b/System/Jwt/Jwt.php index ebc7c3e8..1bbe41bc 100644 --- a/System/Jwt/Jwt.php +++ b/System/Jwt/Jwt.php @@ -26,20 +26,20 @@ use Snowflake\Snowflake; class Jwt extends Component { - /** @var int $user */ - private int $user; + /** @var int $user */ + private int $user; - private array $data; + private array $data; - private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame']; + private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame']; - private array $config = ['token' => '']; + private array $config = ['token' => '']; - private ?int $timeout = 7200; + private ?int $timeout = 7200; - private string $key = 'www.xshucai.com'; + private string $key = 'www.xshucai.com'; - private ?string $public = '-----BEGIN PUBLIC KEY----- + private ?string $public = '-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6BuML3gtLGde7QKNuNST UCB9gdHC7XIpOc7Wx2I64Esj3UxWHTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6Xad jqfjEWpTy4WwGYsOfH0tFl3wAmse0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5t @@ -49,7 +49,7 @@ WlQhpQrA5/wKd76dCzjvqw9M32OiZl2lCKT73cV8GUvt7BNsM1SiPhqfY7nhO6y3 cwIDAQAB -----END PUBLIC KEY-----'; - private ?string $private = '-----BEGIN RSA PRIVATE KEY----- + private ?string $private = '-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA6BuML3gtLGde7QKNuNSTUCB9gdHC7XIpOc7Wx2I64Esj3UxW HTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6XadjqfjEWpTy4WwGYsOfH0tFl3wAmse 0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5tWhTMEnpTFDYoDR0KXlLXltQMudBB @@ -78,425 +78,425 @@ mlAZUEjsoaT9vjvjGTxl3uCm0TX5KTgtSJIt2kA1tYVjQef+/iZTHxY= -----END RSA PRIVATE KEY-----'; - /** - * @throws ConfigException - */ - public function init() - { - if (!Config::has('ssl.public') || !Config::has('ssl.private')) { - return; - } - $this->public = Config::get('ssl.public', false, $this->public); - $this->private = Config::get('ssl.private', false, $this->private); - $this->timeout = Config::get('ssl.timeout', false, 7200); - } + /** + * @throws ConfigException + */ + public function init() + { + if (!Config::has('ssl.public') || !Config::has('ssl.private')) { + return; + } + $this->public = Config::get('ssl.public', $this->public); + $this->private = Config::get('ssl.private', $this->private); + $this->timeout = Config::get('ssl.timeout', 7200); + } - /** - * @param string $publicKey - */ - public function setPublic(string $publicKey) - { - $this->public = $publicKey; - } + /** + * @param string $publicKey + */ + public function setPublic(string $publicKey) + { + $this->public = $publicKey; + } - /** - * @param $timeout - */ - public function setTimeout(int $timeout) - { - $this->timeout = $timeout; - } + /** + * @param $timeout + */ + public function setTimeout(int $timeout) + { + $this->timeout = $timeout; + } - /** - * @param $timeout - */ - public function setKey(string $timeout) - { - $this->key = $timeout; - } + /** + * @param $timeout + */ + public function setKey(string $timeout) + { + $this->key = $timeout; + } - /** - * @param string $privateKey - */ - public function setPrivate(string $privateKey) - { - $this->private = $privateKey; - } + /** + * @param string $privateKey + */ + public function setPrivate(string $privateKey) + { + $this->private = $privateKey; + } - /** - * @param int $unionId - * @param array $headers - * - * @return array - * @throws Exception - */ - public function create(int $unionId, $headers = []): array - { - $this->user = $unionId; - $this->config['time'] = time(); - if (empty($headers)) { - $headers = request()->headers->getHeaders(); - } else if ($headers instanceof HttpHeaders) { - $headers = $headers->getHeaders(); - } + /** + * @param int $unionId + * @param array $headers + * + * @return array + * @throws Exception + */ + public function create(int $unionId, $headers = []): array + { + $this->user = $unionId; + $this->config['time'] = time(); + if (empty($headers)) { + $headers = request()->headers->getHeaders(); + } else if ($headers instanceof HttpHeaders) { + $headers = $headers->getHeaders(); + } - $this->data = $headers; - if (empty($unionId)) { - throw new AuthException('您还未登录或已登录超时'); - } - $source = $header['source'] ?? 'browser'; - if (empty($source) || !in_array($source, $this->source)) { - throw new Exception('未知的登录设备'); - } - return $this->createEncrypt($unionId); - } + $this->data = $headers; + if (empty($unionId)) { + throw new AuthException('您还未登录或已登录超时'); + } + $source = $header['source'] ?? 'browser'; + if (empty($source) || !in_array($source, $this->source)) { + throw new Exception('未知的登录设备'); + } + return $this->createEncrypt($unionId); + } - /** - * @param $unionId - * @return array - * @throws Exception - * 对相关信息进行加密 - */ - private function createEncrypt($unionId): array - { - $caches = $this->clear($unionId); - $param = $this->assembly(array_merge($this->config, [ - 'user' => $unionId, - 'token' => $this->token($unionId, [ - 'device' => Str::rand(128), - ], $this->config['time']), - ]), TRUE); - $refresh = array_intersect_key($param, $this->config); + /** + * @param $unionId + * @return array + * @throws Exception + * 对相关信息进行加密 + */ + private function createEncrypt($unionId): array + { + $caches = $this->clear($unionId); + $param = $this->assembly(array_merge($this->config, [ + 'user' => $unionId, + 'token' => $this->token($unionId, [ + 'device' => Str::rand(128), + ], $this->config['time']), + ]), TRUE); + $refresh = array_intersect_key($param, $this->config); - $params['user'] = $this->user; - $params['token'] = $refresh['token']; - $json = json_encode($params, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE); + $params['user'] = $this->user; + $params['token'] = $refresh['token']; + $json = json_encode($params, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE); - openssl_private_encrypt($json, $encode, $this->private); - $refresh['refresh'] = base64_encode($encode); - $this->setRefresh($refresh['refresh']); + openssl_private_encrypt($json, $encode, $this->private); + $refresh['refresh'] = base64_encode($encode); + $this->setRefresh($refresh['refresh']); - $redis = $this->getRedis(); - foreach ($caches as $cache) { - $redis->del($cache); - } + $redis = $this->getRedis(); + foreach ($caches as $cache) { + $redis->del($cache); + } - return $refresh; - } + return $refresh; + } - /** - * @param bool $update - * @param array $param - * @return array - * @throws - */ - private function assembly(array $param, $update = FALSE): array - { - if (isset($param['sign'])) { - unset($param['sign']); - } - $param = $this->initialize($param); - asort($param, SORT_STRING); - $_tmp = []; - foreach ($param as $key => $val) { - $_tmp[] = trim($key) . '=>' . trim((string)$val); - } - $param['sign'] = md5(implode(':', $_tmp)); - if ($update) { - $this->setCache($param); - } - return $param; - } + /** + * @param bool $update + * @param array $param + * @return array + * @throws + */ + private function assembly(array $param, $update = FALSE): array + { + if (isset($param['sign'])) { + unset($param['sign']); + } + $param = $this->initialize($param); + asort($param, SORT_STRING); + $_tmp = []; + foreach ($param as $key => $val) { + $_tmp[] = trim($key) . '=>' . trim((string)$val); + } + $param['sign'] = md5(implode(':', $_tmp)); + if ($update) { + $this->setCache($param); + } + return $param; + } - /** - * @param array $headers - * @return array - * @throws Exception - */ - public function refresh($headers = []): array - { - $this->data = $headers; - if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) { - throw new AuthException('信息解码失败.'); - } + /** + * @param array $headers + * @return array + * @throws Exception + */ + public function refresh($headers = []): array + { + $this->data = $headers; + if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) { + throw new AuthException('信息解码失败.'); + } - $this->user = $data['user']; + $this->user = $data['user']; - if (!$this->getRedis()->exists('refresh:' . $this->user)) { - throw new AuthException('refresh data error.'); - } + if (!$this->getRedis()->exists('refresh:' . $this->user)) { + throw new AuthException('refresh data error.'); + } - $this->getRedis()->del('refresh:' . $this->user); + $this->getRedis()->del('refresh:' . $this->user); - return $this->create($this->user, $headers); - } + return $this->create($this->user, $headers); + } - /** - * @param $param - * - * @return array - */ - private function initialize(array $param): array - { - $_param = [ - 'version' => '1', - 'source' => $this->getSource(), - ]; - if (!isset($param['device'])) { - $param['device'] = Str::rand(128); - } - return array_merge($_param, $param); - } + /** + * @param $param + * + * @return array + */ + private function initialize(array $param): array + { + $_param = [ + 'version' => '1', + 'source' => $this->getSource(), + ]; + if (!isset($param['device'])) { + $param['device'] = Str::rand(128); + } + return array_merge($_param, $param); + } - /** - * @param array $data - * @throws Exception - */ - private function setCache(array $data) - { - $redis = $this->getRedis(); - $redis->hMset($this->authKey($this->getSource(), $data['token']), $data); - $redis->expire($this->authKey($this->getSource(), $data['token']), $this->timeout); - } + /** + * @param array $data + * @throws Exception + */ + private function setCache(array $data) + { + $redis = $this->getRedis(); + $redis->hMset($this->authKey($this->getSource(), $data['token']), $data); + $redis->expire($this->authKey($this->getSource(), $data['token']), $this->timeout); + } - /** - * @param string $refresh - * @throws Exception - */ - private function setRefresh(string $refresh) - { - $redis = $this->getRedis(); + /** + * @param string $refresh + * @throws Exception + */ + private function setRefresh(string $refresh) + { + $redis = $this->getRedis(); - $redis->set('refresh:' . $this->user, $refresh); - $redis->expire('refresh:' . $this->user, $this->timeout); - } + $redis->set('refresh:' . $this->user, $refresh); + $redis->expire('refresh:' . $this->user, $this->timeout); + } - /** - * @param string $_source - * @param string $token - * - * @return string - * @throws Exception - */ - private function authKey(string $_source, string $token): string - { - $source = $this->getSource(); - if (!empty($_source)) $source = $_source; - if (empty($source)) { - throw new AuthException("未知的登陆设备"); - } - return 'Tmp_Token:' . strtoupper($source) . ':' . $token; - } + /** + * @param string $_source + * @param string $token + * + * @return string + * @throws Exception + */ + private function authKey(string $_source, string $token): string + { + $source = $this->getSource(); + if (!empty($_source)) $source = $_source; + if (empty($source)) { + throw new AuthException("未知的登陆设备"); + } + return 'Tmp_Token:' . strtoupper($source) . ':' . $token; + } - /** - * @return string - */ - public function getSource(): string - { - return $this->data['source'] ?? 'browser'; - } + /** + * @return string + */ + public function getSource(): string + { + return $this->data['source'] ?? 'browser'; + } - /** - * @param int $user - * @param array $param - * @param null $requestTime - * - * @return string - */ - private function token(int $user, $param = [], $requestTime = NULL): string - { - $str = ''; + /** + * @param int $user + * @param array $param + * @param null $requestTime + * + * @return string + */ + private function token(int $user, $param = [], $requestTime = NULL): string + { + $str = ''; - $user = (string)$user; - $_user = str_split(md5($user . md5($user))); - ksort($_user); - foreach ($_user as $key => $val) { - $str .= md5(sha1($key . $val . $this->key)); - } - foreach ($param as $key => $val) { - $str .= md5($str . sha1($key . md5($val))); - } - $str .= sha1(base64_encode((string)$requestTime)); - return $this->preg(md5($str . $user)); - } + $user = (string)$user; + $_user = str_split(md5($user . md5($user))); + ksort($_user); + foreach ($_user as $key => $val) { + $str .= md5(sha1($key . $val . $this->key)); + } + foreach ($param as $key => $val) { + $str .= md5($str . sha1($key . md5($val))); + } + $str .= sha1(base64_encode((string)$requestTime)); + return $this->preg(md5($str . $user)); + } - /** - * @param string $str - * - * @return array|string|null 将字符串替换成指定格式 - */ - private function preg(string $str): null|array|string - { - return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $str); - } + /** + * @param string $str + * + * @return array|string|null 将字符串替换成指定格式 + */ + private function preg(string $str): null|array|string + { + return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $str); + } - /** - * @param int $user - * @return string[] - * @throws Exception - */ - public function clear(int $user): array - { - $this->user = $user; - $redis = $this->getRedis(); - if (is_bool($refresh = $redis->get('refresh:' . $this->user))) { - return []; - }; - openssl_public_decrypt(base64_decode($refresh), $info, $this->public); + /** + * @param int $user + * @return string[] + * @throws Exception + */ + public function clear(int $user): array + { + $this->user = $user; + $redis = $this->getRedis(); + if (is_bool($refresh = $redis->get('refresh:' . $this->user))) { + return []; + }; + openssl_public_decrypt(base64_decode($refresh), $info, $this->public); - $_tmp = []; - if (!empty($info) && $json = json_decode($info, true)) { - if (!isset($json['token'])) { - return []; - } - foreach ($this->source as $value) { - $_tmp[] = $this->authKey($value, $json['token']); - } - } - return $_tmp; - } + $_tmp = []; + if (!empty($info) && $json = json_decode($info, true)) { + if (!isset($json['token'])) { + return []; + } + foreach ($this->source as $value) { + $_tmp[] = $this->authKey($value, $json['token']); + } + } + return $_tmp; + } - /** - * @param array $data - * @param int $user - * @return bool - * @throws AuthException - */ - public function check(array $data, int $user): bool - { - $this->data = $data; - $this->user = $user; + /** + * @param array $data + * @param int $user + * @return bool + * @throws AuthException + */ + public function check(array $data, int $user): bool + { + $this->data = $data; + $this->user = $user; - if (empty($this->user)) return FALSE; - $cache = $this->getUserModel(); - if (empty($cache)) { - return FALSE; - } + if (empty($this->user)) return FALSE; + $cache = $this->getUserModel(); + if (empty($cache)) { + return FALSE; + } - $merge = $this->assembly(array_merge($cache, [ - 'token' => $data['token'], - ])); - $check = array_diff_assoc($this->initialize($cache), $merge); - return !((bool)count($check)); - } + $merge = $this->assembly(array_merge($cache, [ + 'token' => $data['token'], + ])); + $check = array_diff_assoc($this->initialize($cache), $merge); + return !((bool)count($check)); + } - /** - * @return mixed - * @throws - */ - public function getCurrentOnlineUser(): int - { - $this->data = request()->headers->getHeaders(); + /** + * @return mixed + * @throws + */ + public function getCurrentOnlineUser(): int + { + $this->data = request()->headers->getHeaders(); - return $this->loadByCache(); - } + return $this->loadByCache(); + } - /** - * @param string $token - * @param string $source - * @return mixed - * @throws AuthException - */ - public function getOnlineUserByToken(string $token, string $source = 'BROWSER'): int - { - $this->data['token'] = $token; - $this->data['source'] = $source; + /** + * @param string $token + * @param string $source + * @return mixed + * @throws AuthException + */ + public function getOnlineUserByToken(string $token, string $source = 'BROWSER'): int + { + $this->data['token'] = $token; + $this->data['source'] = $source; - return $this->loadByCache(); - } + return $this->loadByCache(); + } - /** - * @return int - * @throws AuthException - * @throws Exception - */ - private function loadByCache(): int - { - $model = $this->getUserModel(); - if (empty($model)) { - throw new AuthException('授权信息已过期!'); - } - if (!isset($model['user'])) { - throw new AuthException('授权信息错误!'); - } - if (!$this->check($this->data, (int)$model['user'])) { - throw new AuthException('授权信息不合法!'); - } + /** + * @return int + * @throws AuthException + * @throws Exception + */ + private function loadByCache(): int + { + $model = $this->getUserModel(); + if (empty($model)) { + throw new AuthException('授权信息已过期!'); + } + if (!isset($model['user'])) { + throw new AuthException('授权信息错误!'); + } + if (!$this->check($this->data, (int)$model['user'])) { + throw new AuthException('授权信息不合法!'); + } - $this->expireRefresh(); + $this->expireRefresh(); - return (int)$model['user']; - } + return (int)$model['user']; + } - /** - * @param array $header - * @return mixed - * @throws AuthException - * @throws Exception - */ - public static function checkAuth(array $header = []): mixed - { - $instance = Snowflake::app()->getJwt(); - if (empty($header)) { - $header = request()->headers->getHeaders(); - } + /** + * @param array $header + * @return mixed + * @throws AuthException + * @throws Exception + */ + public static function checkAuth(array $header = []): mixed + { + $instance = Snowflake::app()->getJwt(); + if (empty($header)) { + $header = request()->headers->getHeaders(); + } - $instance->data = $header; - $model = $instance->getUserModel(); - if (empty($model) || !isset($model['user'])) { - return false; - } + $instance->data = $header; + $model = $instance->getUserModel(); + if (empty($model) || !isset($model['user'])) { + return false; + } - if (!$instance->check($header, (int)$model['user'])) { - return false; - } - $instance->expireRefresh(); - return $model['user']; - } + if (!$instance->check($header, (int)$model['user'])) { + return false; + } + $instance->expireRefresh(); + return $model['user']; + } - /** - * @param null $token - * @param null $source - * @throws Exception - */ - public function expireRefresh($token = null, $source = null) - { - if (!empty($token)) { - $this->data['token'] = $token; - } - if (!empty($source)) { - $this->data['source'] = $source; - } - $key = $this->authKey($this->getSource(), $this->data['token']); - $this->getRedis()->expire($key, $this->timeout); - } + /** + * @param null $token + * @param null $source + * @throws Exception + */ + public function expireRefresh($token = null, $source = null) + { + if (!empty($token)) { + $this->data['token'] = $token; + } + if (!empty($source)) { + $this->data['source'] = $source; + } + $key = $this->authKey($this->getSource(), $this->data['token']); + $this->getRedis()->expire($key, $this->timeout); + } - /** - * @return bool|array - * @throws AuthException - * @throws Exception - */ - private function getUserModel(): bool|array - { - if (!isset($this->data['token'])) { - throw new AuthException('暂无访问权限!'); - } - $key = $this->authKey($this->getSource(), $this->data['token']); - return $this->getRedis()->hGetAll($key); - } + /** + * @return bool|array + * @throws AuthException + * @throws Exception + */ + private function getUserModel(): bool|array + { + if (!isset($this->data['token'])) { + throw new AuthException('暂无访问权限!'); + } + $key = $this->authKey($this->getSource(), $this->data['token']); + return $this->getRedis()->hGetAll($key); + } - /** - * @return Redis|\Redis - * @throws - */ - private function getRedis(): Redis|\Redis - { - return Snowflake::app()->getRedis(); - } + /** + * @return Redis|\Redis + * @throws + */ + private function getRedis(): Redis|\Redis + { + return Snowflake::app()->getRedis(); + } } diff --git a/System/Process/ServerInotify.php b/System/Process/ServerInotify.php index 6d016020..bcc27aca 100644 --- a/System/Process/ServerInotify.php +++ b/System/Process/ServerInotify.php @@ -25,285 +25,285 @@ use Swoole\Timer; */ class ServerInotify extends Process { - private mixed $inotify; - private bool $isReloading = false; - private bool $isReloadingOut = false; - private array $watchFiles = []; - private ?array $dirs = []; - private int $events; + private mixed $inotify; + private bool $isReloading = false; + private bool $isReloadingOut = false; + private array $watchFiles = []; + private ?array $dirs = []; + private int $events; - private int $int = -1; + private int $int = -1; - /** - * @param \Swoole\Process $process - * @throws Exception - */ - public function onHandler(\Swoole\Process $process): void - { - set_error_handler([$this, 'onErrorHandler']); - $this->dirs = Config::get('inotify', false, [APP_PATH]); - if (extension_loaded('inotify')) { - $this->inotify = inotify_init(); - $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; + /** + * @param \Swoole\Process $process + * @throws Exception + */ + public function onHandler(\Swoole\Process $process): void + { + set_error_handler([$this, 'onErrorHandler']); + $this->dirs = Config::get('inotify', [APP_PATH]); + if (extension_loaded('inotify')) { + $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::wait(); - } else { - $this->loadDirs(); - $this->tick(); - } - } + foreach ($this->dirs as $dir) { + if (!is_dir($dir)) continue; + $this->watch($dir); + } + Event::add($this->inotify, [$this, 'check']); + Event::wait(); + } else { + $this->loadDirs(); + $this->tick(); + } + } - /** - * @param bool $isReload - * @throws Exception - */ - private function loadDirs($isReload = false) - { - foreach ($this->dirs as $value) { - if (is_bool($path = realpath($value))) { - continue; - } + /** + * @param bool $isReload + * @throws Exception + */ + private function loadDirs($isReload = false) + { + foreach ($this->dirs as $value) { + if (is_bool($path = realpath($value))) { + continue; + } - if (!is_dir($path)) continue; + if (!is_dir($path)) continue; - $this->loadByDir($path, $isReload); - } - } + $this->loadByDir($path, $isReload); + } + } - private array $md5Map = []; + private array $md5Map = []; - /** - * @throws Exception - */ - public function tick() - { - if ($this->isReloading) { - return; - } + /** + * @throws Exception + */ + public function tick() + { + if ($this->isReloading) { + return; + } - $this->loadDirs(true); + $this->loadDirs(true); - Timer::after(2000, [$this, 'tick']); - } + Timer::after(2000, [$this, 'tick']); + } - /** - * @param $path - * @param bool $isReload - * @return void - * @throws Exception - */ - private function loadByDir($path, $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)) { - $this->timerReload(); - break; - } - } - } - } + /** + * @param $path + * @param bool $isReload + * @return void + * @throws Exception + */ + private function loadByDir($path, $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)) { + $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; - } + /** + * @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; + } - /** - * 开始监听 - */ - public function check() - { - if (!($events = inotify_read($this->inotify))) { - return; - } - if ($this->isReloading) { - if (!$this->isReloadingOut) { - $this->isReloadingOut = true; - } - return; - } + /** + * 开始监听 + */ + public function check() + { + if (!($events = inotify_read($this->inotify))) { + return; + } + if ($this->isReloading) { + if (!$this->isReloadingOut) { + $this->isReloadingOut = true; + } + return; + } - $eventList = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM]; - foreach ($events as $ev) { - if (empty($ev['name'])) { - continue; - } - if ($ev['mask'] == IN_IGNORED) { - continue; - } - if (!in_array($ev['mask'], $eventList)) { - continue; - } - $fileType = strstr($ev['name'], '.'); - //非重启类型 - if ($fileType !== '.php') { - continue; - } - if ($this->int !== -1) { - return; - } - $this->int = @swoole_timer_after(2000, [$this, 'reload']); + $eventList = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM]; + foreach ($events as $ev) { + if (empty($ev['name'])) { + continue; + } + if ($ev['mask'] == IN_IGNORED) { + continue; + } + if (!in_array($ev['mask'], $eventList)) { + continue; + } + $fileType = strstr($ev['name'], '.'); + //非重启类型 + if ($fileType !== '.php') { + continue; + } + if ($this->int !== -1) { + return; + } + $this->int = @swoole_timer_after(2000, [$this, 'reload']); - $this->isReloading = true; - } - } + $this->isReloading = true; + } + } - /** - * @throws Exception - */ - public function reload() - { - $this->isReloading = true; - $this->trigger_reload(); - $this->clearWatch(); - foreach ($this->dirs as $root) { - $this->watch($root); - } - $this->int = -1; - $this->isReloading = FALSE; - $this->isReloadingOut = FALSE; - $this->md5Map = []; - } + /** + * @throws Exception + */ + public function reload() + { + $this->isReloading = true; + $this->trigger_reload(); + $this->clearWatch(); + foreach ($this->dirs as $root) { + $this->watch($root); + } + $this->int = -1; + $this->isReloading = FALSE; + $this->isReloadingOut = FALSE; + $this->md5Map = []; + } - /** - * @throws Exception - */ - public function timerReload() - { - $this->isReloading = true; - $this->trigger_reload(); - $this->int = -1; + /** + * @throws Exception + */ + public function timerReload() + { + $this->isReloading = true; + $this->trigger_reload(); + $this->int = -1; - $this->loadDirs(); + $this->loadDirs(); - $this->isReloading = FALSE; - $this->isReloadingOut = FALSE; + $this->isReloading = FALSE; + $this->isReloadingOut = FALSE; - $this->tick(); - } + $this->tick(); + } - /** - * 重启 - * @throws Exception - */ - public function trigger_reload() - { - Snowflake::reload(); - } + /** + * 重启 + * @throws Exception + */ + public function trigger_reload() + { + Snowflake::reload(); + } - /** - * @throws Exception - */ - public function clearWatch() - { - foreach ($this->watchFiles as $wd) { - try { - inotify_rm_watch($this->inotify, $wd); - } catch (\Throwable $exception) { - logger()->addError($exception, 'throwable'); - } - } - $this->watchFiles = []; - } + /** + * @throws Exception + */ + public function clearWatch() + { + foreach ($this->watchFiles as $wd) { + try { + inotify_rm_watch($this->inotify, $wd); + } catch (\Throwable $exception) { + logger()->addError($exception, 'throwable'); + } + } + $this->watchFiles = []; + } - /** - * @param $code - * @param $message - * @param $file - * @param $line - * @throws Exception - */ - protected function onErrorHandler($code, $message, $file, $line) - { - if (str_contains($message, 'The file descriptor is not an inotify instance')) { - return; - } - $this->application->debug('Error:' . $message); - $this->application->debug($file . ':' . $line); - } + /** + * @param $code + * @param $message + * @param $file + * @param $line + * @throws Exception + */ + protected function onErrorHandler($code, $message, $file, $line) + { + if (str_contains($message, 'The file descriptor is not an inotify instance')) { + return; + } + $this->application->debug('Error:' . $message); + $this->application->debug($file . ':' . $line); + } - /** - * @param $dir - * @return bool - * @throws Exception - */ - public function watch($dir): bool - { - //目录不存在 - if (!is_dir($dir)) { - return $this->application->addError("[$dir] is not a directory."); - } - //避免重复监听 - if (isset($this->watchFiles[$dir])) { - return FALSE; - } + /** + * @param $dir + * @return bool + * @throws Exception + */ + public function watch($dir): bool + { + //目录不存在 + if (!is_dir($dir)) { + return $this->application->addError("[$dir] is not a directory."); + } + //避免重复监听 + if (isset($this->watchFiles[$dir])) { + return FALSE; + } - if (in_array($dir, [APP_PATH . 'config', APP_PATH . 'commands', APP_PATH . '.git', APP_PATH . '.gitee'])) { - return FALSE; - } + if (in_array($dir, [APP_PATH . 'config', APP_PATH . 'commands', APP_PATH . '.git', APP_PATH . '.gitee'])) { + return FALSE; + } - $wd = @inotify_add_watch($this->inotify, $dir, $this->events); - $this->watchFiles[$dir] = $wd; + $wd = @inotify_add_watch($this->inotify, $dir, $this->events); + $this->watchFiles[$dir] = $wd; - $files = scandir($dir); - foreach ($files as $f) { - if ($f == '.' or $f == '..' or $f == 'runtime' or preg_match('/\.txt/', $f) or preg_match('/\.sql/', $f) or preg_match('/\.log/', $f)) { - continue; - } - $path = $dir . '/' . $f; - //递归目录 - if (is_dir($path)) { - $this->watch($path); - } + $files = scandir($dir); + foreach ($files as $f) { + if ($f == '.' or $f == '..' or $f == 'runtime' or preg_match('/\.txt/', $f) or preg_match('/\.sql/', $f) or preg_match('/\.log/', $f)) { + continue; + } + $path = $dir . '/' . $f; + //递归目录 + if (is_dir($path)) { + $this->watch($path); + } - //检测文件类型 - if (strstr($f, '.') == '.php') { - $wd = @inotify_add_watch($this->inotify, $path, $this->events); - $this->watchFiles[$path] = $wd; - } - } - return TRUE; - } + //检测文件类型 + if (strstr($f, '.') == '.php') { + $wd = @inotify_add_watch($this->inotify, $path, $this->events); + $this->watchFiles[$path] = $wd; + } + } + return TRUE; + } } diff --git a/System/Snowflake.php b/System/Snowflake.php index d6ceafbf..36bea5a0 100644 --- a/System/Snowflake.php +++ b/System/Snowflake.php @@ -172,7 +172,7 @@ class Snowflake public static function getStoragePath(): string { $default = APP_PATH . 'storage' . DIRECTORY_SEPARATOR; - $path = Config::get('storage', false, $default); + $path = Config::get('storage', $default); if (!is_dir($path)) { mkdir($path, 0777, true); } diff --git a/function.php b/function.php index 65faa255..cefd3b59 100644 --- a/function.php +++ b/function.php @@ -616,7 +616,7 @@ if (!function_exists('name')) { return; } - $name = Config::get('id', false, 'system') . '[' . $pid . ']'; + $name = Config::get('id', 'system') . '[' . $pid . ']'; if (!empty($prefix)) { $name .= '.' . $prefix; }