diff --git a/Annotation/Inject.php b/Annotation/Inject.php index 4b86aab8..4bcc4d8c 100644 --- a/Annotation/Inject.php +++ b/Annotation/Inject.php @@ -21,10 +21,10 @@ use Snowflake\Snowflake; /** * Inject constructor. - * @param string $className + * @param string $value * @param array $args */ - public function __construct(private string $className, public bool $withContext = false, private array $args = []) + public function __construct(private string $value, public bool $withContext = false, private array $args = []) { } @@ -93,14 +93,14 @@ use Snowflake\Snowflake; private function parseInjectValue(): mixed { if ($this->withContext) { - return Context::getContext($this->className); + return Context::getContext($this->value); } - if (class_exists($this->className)) { - return Snowflake::getDi()->get($this->className, $this->args); - } else if (Snowflake::app()->has($this->className)) { - return Snowflake::app()->get($this->className); + if (class_exists($this->value)) { + return Snowflake::getDi()->get($this->value, $this->args); + } else if (Snowflake::app()->has($this->value)) { + return Snowflake::app()->get($this->value); } else { - return $this->className; + return $this->value; } } diff --git a/Annotation/Route/Middleware.php b/Annotation/Route/Middleware.php index 87113ad4..69b2d762 100644 --- a/Annotation/Route/Middleware.php +++ b/Annotation/Route/Middleware.php @@ -5,7 +5,7 @@ namespace Annotation\Route; use Annotation\Attribute; -use HttpServer\Route\Middlewares; +use HttpServer\Route\MiddlewareManager; use Snowflake\Snowflake; use HttpServer\IInterface\Middleware as IMiddleware; @@ -47,7 +47,7 @@ use HttpServer\IInterface\Middleware as IMiddleware; */ public function execute(mixed $class, mixed $method = null): static { - $middleware = Snowflake::getDi()->get(Middlewares::class); + $middleware = Snowflake::getDi()->get(MiddlewareManager::class); $middleware->addMiddlewares($class, $method, $this->middleware); return $this; } diff --git a/HttpServer/Controller.php b/HttpServer/Controller.php index 2233bd08..0bc35f8f 100644 --- a/HttpServer/Controller.php +++ b/HttpServer/Controller.php @@ -5,21 +5,15 @@ namespace HttpServer; use Annotation\Inject; -use Exception; -use HttpServer\Abstracts\HttpService; use HttpServer\Http\HttpHeaders; use HttpServer\Http\HttpParams; use HttpServer\Http\Request; use HttpServer\Http\Response; -use Snowflake\Abstracts\Input; use Snowflake\Abstracts\TraitApplication; -use Snowflake\Snowflake; /** * Class WebController * @package Snowflake\Snowflake\Web - * @property-read HttpParams $input - * @property-read HttpHeaders $header */ class Controller { @@ -30,33 +24,33 @@ class Controller /** * inject request * - * @var \HttpServer\Http\Request + * @var \HttpServer\Http\Request|null */ - #[Inject(className: 'request', withContext: true)] - protected ?Request $request = null; + #[Inject(value: 'request', withContext: true)] + public ?Request $request = null; /** - * @var \HttpServer\Http\HttpParams + * @var \HttpServer\Http\HttpParams|null */ - #[Inject(className: 'input', withContext: true)] - protected ?HttpParams $input = null; + #[Inject(value: HttpParams::class, withContext: true)] + public ?HttpParams $input = null; /** - * @var \HttpServer\Http\HttpHeaders + * @var \HttpServer\Http\HttpHeaders|null */ - #[Inject(className: 'header', withContext: true)] - protected ?HttpHeaders $header = null; + #[Inject(value: HttpHeaders::class, withContext: true)] + public ?HttpHeaders $header = null; /** * inject response * - * @var \HttpServer\Http\Response + * @var \HttpServer\Http\Response|null */ #[Inject('response')] - protected ?Response $response = null; + public ?Response $response = null; } diff --git a/HttpServer/Http/Request.php b/HttpServer/Http/Request.php index f985c84c..09c30a3b 100644 --- a/HttpServer/Http/Request.php +++ b/HttpServer/Http/Request.php @@ -463,39 +463,17 @@ class Request extends HttpService if (!empty($request->post)) { $sRequest->params->setPosts($request->post ?? []); } + Context::setContext(HttpParams::class, $sRequest->params); $sRequest->headers = new HttpHeaders(array_merge($request->server, $request->header)); + Context::setContext(HttpHeaders::class, $sRequest->headers); + $sRequest->uri = $sRequest->headers->get('request_uri'); $sRequest->parseUri(); - Context::setContext('input', $sRequest->params); - Context::setContext('header', $sRequest->headers); - return $sRequest; } - /** - * @param $frame - * @param string $route - * @param string $event - * @return Request - */ - public static function socketQuery($frame, string $event = Socket::MESSAGE, string $route = 'event'): Request - { - $sRequest = new Request(); - $sRequest->fd = $frame->fd; - $sRequest->startTime = microtime(true); - - $sRequest->params = new HttpParams([], [], []); - $sRequest->headers = new HttpHeaders([]); - $sRequest->headers->replace('request_method', 'sw::socket'); - $sRequest->headers->replace('request_uri', $event . '::' . $route); - $sRequest->parseUri(); - - return Context::setContext('request', $sRequest); - } - - } diff --git a/HttpServer/Route/Middlewares.php b/HttpServer/Route/MiddlewareManager.php similarity index 82% rename from HttpServer/Route/Middlewares.php rename to HttpServer/Route/MiddlewareManager.php index a8d2837e..0336dbac 100644 --- a/HttpServer/Route/Middlewares.php +++ b/HttpServer/Route/MiddlewareManager.php @@ -9,10 +9,10 @@ use Snowflake\Abstracts\BaseObject; /** - * Class Middlewares + * Class MiddlewareManager * @package HttpServer\Route */ -class Middlewares extends BaseObject +class MiddlewareManager extends BaseObject { private static array $_middlewares = []; @@ -26,7 +26,7 @@ class Middlewares extends BaseObject public function addMiddlewares($class, $method, array|string $middlewares) { if (is_object($class)) { - $class = get_class($class); + $class = $class::class; } if (!isset(static::$_middlewares[$class . '::' . $method])) { static::$_middlewares[$class . '::' . $method] = []; @@ -45,6 +45,20 @@ class Middlewares extends BaseObject } + /** + * @param $class + * @param $method + * @return bool + */ + public function hasMiddleware($class, $method) + { + if (is_object($class)) { + $class = $class::class; + } + return isset(static::$_middlewares[$class . '::' . $method]); + } + + /** * @param $class * @param $method diff --git a/HttpServer/Route/Node.php b/HttpServer/Route/Node.php index 48187991..d0154de7 100644 --- a/HttpServer/Route/Node.php +++ b/HttpServer/Route/Node.php @@ -9,6 +9,7 @@ use Annotation\Route\RpcProducer; use Closure; use Exception; use HttpServer\Abstracts\HttpService; +use HttpServer\Controller; use HttpServer\Http\Context; use HttpServer\Http\Request; use JetBrains\PhpStorm\Pure; @@ -95,7 +96,7 @@ class Node extends HttpService $this->handler = $handler; } if (!empty($this->handler) && is_array($this->handler)) { - $this->callback = di(Middlewares::class)->callerMiddlewares( + $this->callback = di(MiddlewareManager::class)->callerMiddlewares( $this->handler[0], $this->handler[1], $this->createDispatch() ); } @@ -114,10 +115,12 @@ class Node extends HttpService /** @var Aop $aop */ $aop = Snowflake::app()->get('aop'); - if (!is_array($this->handler) || !$aop->hasAop($this->handler)) { + if ($this->handler instanceof Closure || !$aop->hasAop($this->handler)) { return static function () use ($application) { $dispatchParam = Context::getContext('dispatch-param', [\request()]); - + if (is_array($this->handler)){ + Snowflake::injectProperty($this->handler[0]); + } return call_user_func($application->handler, ...$dispatchParam); }; } @@ -129,7 +132,9 @@ class Node extends HttpService $dispatchParam = Context::getContext('dispatch-param', [\request()]); $asp = $reflect->newInstance($this->handler); - + if (is_array($this->handler)){ + Snowflake::injectProperty($this->handler[0]); + } call_user_func($callback, $asp, $dispatchParam); }; } diff --git a/HttpServer/Route/Router.php b/HttpServer/Route/Router.php index d5688c49..624a7604 100644 --- a/HttpServer/Route/Router.php +++ b/HttpServer/Route/Router.php @@ -370,7 +370,7 @@ class Router extends HttpService implements RouterInterface $array[] = $this->getMiddlewareInstance($value); } } - return $array; + return array_filter($array); } @@ -382,15 +382,14 @@ class Router extends HttpService implements RouterInterface */ private function getMiddlewareInstance($value): null|Closure|array { - if (is_string($value)) { - $value = Snowflake::createObject($value); - if (!($value instanceof Middleware)) { - return null; - } - return [$value, 'onHandler']; - } else { + if (!is_string($value)) { return $value; } + $value = Snowflake::createObject($value); + if (!($value instanceof Middleware)) { + return null; + } + return [$value, 'onHandler']; } diff --git a/System/Snowflake.php b/System/Snowflake.php index e633c38b..d01f6179 100644 --- a/System/Snowflake.php +++ b/System/Snowflake.php @@ -42,574 +42,590 @@ defined('SOCKET_PATH') or define('SOCKET_PATH', APP_PATH . 'app/Websocket/'); class Snowflake { - /** @var Container */ - public static Container $container; - - - /** @var ?Application */ - private static ?Application $service = null; - - - /** - * @param $service - * - * 初始化服务 - */ - public static function init($service) - { - static::$service = $service; - } - - - /** - * @param $alias - * @param array $array - * @return mixed - * @throws Exception - */ - public static function set($alias, array $array = []): mixed - { - return static::app()->set($alias, $array); - } - - - /** - * @param string $name - * @return mixed - * @throws Exception - */ - public static function getApp(string $name): mixed - { - return static::app()->get($name); - } - - /** - * @return Application|null - */ - public static function app(): ?Application - { - return static::$service; - } - - /** - * @param $name - * @return bool - */ - #[Pure] public static function has($name): bool - { - return static::$service->has($name); - } - - - /** - * @param $className - * @param $id - */ - public static function setAlias($className, $id) - { - static::$service->setAlias($className, $id); - } - - - /** - * @param $port - * @return bool - * @throws Exception - */ - public static function port_already($port): bool - { - if (empty($port)) { - return false; - } - if (Snowflake::getPlatform()->isLinux()) { - exec('netstat -tunlp | grep ' . $port, $output); - } else { - exec('lsof -i :' . $port . ' | grep -i "LISTEN"', $output); - } - return !empty($output); - } - - - /** - * @return Annotation - * @throws Exception - */ - public static function getAnnotation(): Annotation - { - return static::app()->getAnnotation(); - } - - - /** - * @param $service - * @return string - */ - #[Pure] public static function listen($service): string - { - return sprintf('Check listen %s::%d -> ok', $service['host'], $service['port']); - } - - - /** - * @param $className - * @param array $construct - * @return mixed - * @throws NotFindClassException - * @throws ReflectionException - * @throws Exception - */ - public static function createObject($className, array $construct = []): mixed - { - if (is_object($className)) { - return $className; - } - if (is_string($className)) { - return static::$container->get($className, $construct); - } else if (is_array($className)) { - if (!isset($className['class']) || empty($className['class'])) { - throw new Exception('Object configuration must be an array containing a "class" element.'); - } - - $class = $className['class']; - unset($className['class']); - - return static::$container->get($class, $construct, $className); - } else if (is_callable($className, TRUE)) { - return call_user_func($className, $construct); - } else { - throw new Exception('Unsupported configuration type: ' . gettype($className)); - } - } - - /** - * @return string - * @throws Exception - */ - public static function getStoragePath(): string - { - $default = APP_PATH . 'storage' . DIRECTORY_SEPARATOR; - $path = Config::get('storage', $default); - if (!is_dir($path)) { - mkdir($path, 0777, true); - } - return $path; - } - - - /** - * @return bool - */ - public static function inCoroutine(): bool - { - return Coroutine::getCid() > 0; - } - - - /** - * @return Container - */ - public static function getDi(): Container - { - return static::$container; - } - - - /** - * @param $workerId - * @return mixed - * @throws Exception - */ - public static function setManagerId($workerId): mixed - { - if (empty($workerId) || static::isDcoker()) { - return $workerId; - } - - $tmpFile = storage($workerId . '.sock', 'pid/manager'); - - return self::writeFile($tmpFile, $workerId); - } - - - /** - * @param $workerId - * @return mixed - * @throws Exception - */ - public static function setProcessId($workerId): mixed - { - if (empty($workerId) || static::isDcoker()) { - return $workerId; - } - - $tmpFile = storage($workerId . '.sock', 'pid/process'); - - return self::writeFile($tmpFile, $workerId); - } - - - /** - * @return bool - */ - public static function isDcoker(): bool - { - $output = shell_exec('[ -f /.dockerenv ] && echo yes || echo no'); - if (trim($output) === 'yes') { - return true; - } - return false; - } - - - /** - * @param $workerId - * @return mixed - * @throws Exception - */ - public static function setWorkerId($workerId): mixed - { - if (empty($workerId) || static::isDcoker()) { - return $workerId; - } - - $tmpFile = storage($workerId . '.sock', 'pid/worker'); - - return self::writeFile($tmpFile, $workerId); - } - - - /** - * @param $workerId - * @return mixed - * @throws Exception - */ - public static function setTaskId($workerId): mixed - { - if (empty($workerId) || static::isDcoker()) { - return $workerId; - } - - $tmpFile = storage($workerId . '.sock', 'pid/task'); - - return self::writeFile($tmpFile, $workerId); - } - - /** - * @param $fileName - * @param $content - * @param null $is_append - * @return mixed - */ - public static function writeFile($fileName, $content, $is_append = null): mixed - { - $params = [$fileName, (string)$content]; - if ($is_append !== null) { - $params[] = $is_append; - } - return !self::inCoroutine() ? file_put_contents(...$params) : Coroutine::writeFile(...$params); - } - - - /** - * @param $object - * @param $config - * @return mixed - */ - public static function configure($object, $config): mixed - { - foreach ($config as $key => $value) { - if (!property_exists($object, $key)) { - continue; - } - $object->$key = $value; - } - return $object; - } - - - /** - * @param $workerId - * @param bool $isWorker - * @throws Exception - */ - public static function clearProcessId($workerId, $isWorker = false) - { - clearstatcache(); - $directory = $isWorker === true ? 'pid/worker' : 'pid/task'; - if (!file_exists($file = storage($workerId, $directory))) { - return; - } - shell_exec('rm -rf ' . $file); - } - - - /** - * @param string|null $taskPid - * @throws Exception - */ - public static function clearTaskPid(string $taskPid = null) - { - if (empty($taskPid)) { - exec('rm -rf ' . storage(null, 'pid/task')); - } else { - static::clearProcessId($taskPid); - } - } - - - /** - * @param $taskPid - * @throws Exception - */ - public static function clearWorkerPid($taskPid = null) - { - if (empty($taskPid)) { - exec('rm -rf ' . storage(null, 'pid/worker')); - } else { - static::clearProcessId($taskPid, true); - } - } - - - /** - * @return Server|null - * @throws - */ - public static function getWebSocket(): ?\Swoole\Server - { - $server = static::app()->getSwoole(); - if (!($server instanceof \Swoole\Server)) { - return null; - } - return $server; - } - - - /** - * @return false|string - * @throws Exception - */ - public static function getMasterPid(): bool|string - { - $pid = Snowflake::app()->getSwoole()->setting['pid_file']; - - return file_get_contents($pid); - } - - - /** - * @param int $fd - * @param $data - * @return mixed - * @throws Exception - */ - public static function push(int $fd, $data): mixed - { - $server = static::getWebSocket(); - if (empty($server) || !$server->isEstablished($fd)) { - return false; - } - if (!is_string($data)) { - $data = Json::encode($data); - } - return $server->push($fd, $data); - } - - - /** - * @return mixed - */ - public static function localhost(): mixed - { - return current(swoole_get_local_ip()); - } - - - /** - * @param string $class - * @param array $params - * @throws NotFindClassException - * @throws ReflectionException - * @throws Exception - */ - public static function async(string $class, array $params = []) - { - $server = static::app()->getSwoole(); - if (!isset($server->setting['task_worker_num']) || !class_exists($class)) { - return; - } - - /** @var Task $class */ - $class = static::createObject($class); - $class->setParams($params); - - $server->task(swoole_serialize($class)); - } - - - /** - * @param $v1 - * @param $v2 - * @return float - */ - #[Pure] public static function distance(array $v1, array $v2): float - { - $maxX = max($v1['x'], $v2['x']); - $minX = min($v1['x'], $v2['x']); - - $maxZ = max($v1['z'], $v2['z']); - $minZ = min($v1['z'], $v2['z']); - - $dx = abs($maxX - $minX); - $dy = abs($maxZ - $minZ); - - $sqrt = sqrt($dx * $dx + $dy * $dy); - if ($sqrt < 0) { - $sqrt = abs($sqrt); - } - return (float)$sqrt; - } - - - /** - * @param $process - * @throws Exception - */ - public static function shutdown($process): void - { - static::app()->getSwoole()->shutdown(); - if ($process instanceof Process) { - $process->exit(0); - } - } - - - /** - * @param $tmp_name - * @return string - */ - public static function rename($tmp_name): string - { - $hash = md5_file($tmp_name); - - $later = '.' . exif_imagetype($tmp_name); - - $match = '/(\w{12})(\w{5})(\w{9})(\w{6})/'; - $tmp = preg_replace($match, '$1-$2-$3-$4', $hash); - - return strtoupper($tmp) . $later; - } - - - /** - * @return Environmental - * @throws - */ - public static function getPlatform(): Environmental - { - return Snowflake::createObject(Environmental::class); - } - - - /** - * @return mixed - * @throws Exception - */ - public static function reload(): mixed - { - return Snowflake::app()->getSwoole()->reload(); - } - - - private static array $_autoload = []; - - - const PROCESS = 'process'; - const TASK = 'task'; - const WORKER = 'worker'; - - - /** - * @param string $event - * @param null $data - * @return false|string - * @throws Exception - */ - public static function param(string $event, $data = NULL): bool|string - { - if (is_object($data)) { - if ($data instanceof ActiveRecord || $data instanceof Collection) { - $data = $data->getAttributes(); - } else { - $data = get_object_vars($data); - } - } - if (!is_array($data)) $data = ['data' => $data]; - return json_encode(array_merge(['callback' => $event], $data)); - } - - - /** - * @return string|null - */ - #[Pure] public static function getEnvironmental(): ?string - { - return env('environmental'); - } - - - /** - * @return bool - */ - #[Pure] public static function isTask(): bool - { - return static::getEnvironmental() == static::TASK; - } - - - /** - * @return bool - */ - #[Pure] public static function isWorker(): bool - { - return static::getEnvironmental() == static::WORKER; - } - - - /** - * @return bool - */ - #[Pure] public static function isProcess(): bool - { - return static::getEnvironmental() == static::PROCESS; - } - - - /** - * @param $class - * @param $file - */ - public static function setAutoload($class, $file) - { - if (isset(static::$_autoload[$class])) { - return; - } - static::$_autoload[$class] = $file; - include_once "$file"; - } - - - /** - * @param $className - */ - public static function autoload($className) - { - if (!isset(static::$_autoload[$className])) { - return; - } - $file = static::$_autoload[$className]; - require_once "$file"; - } + /** @var Container */ + public static Container $container; + + + /** @var ?Application */ + private static ?Application $service = null; + + + /** + * @param object $class + */ + public static function injectProperty(object $class) + { + $attributes = static::getDi()->getClassProperty($class::class); + /** + * @var string $property + * @var \Annotation\Attribute $attribute + */ + foreach ($attributes as $property => $attribute) { + $attribute->execute($class, $property); + } + } + + + /** + * @param $service + * + * 初始化服务 + */ + public static function init($service) + { + static::$service = $service; + } + + + /** + * @param $alias + * @param array $array + * @return mixed + * @throws Exception + */ + public static function set($alias, array $array = []): mixed + { + return static::app()->set($alias, $array); + } + + + /** + * @param string $name + * @return mixed + * @throws Exception + */ + public static function getApp(string $name): mixed + { + return static::app()->get($name); + } + + /** + * @return Application|null + */ + public static function app(): ?Application + { + return static::$service; + } + + /** + * @param $name + * @return bool + */ + #[Pure] public static function has($name): bool + { + return static::$service->has($name); + } + + + /** + * @param $className + * @param $id + */ + public static function setAlias($className, $id) + { + static::$service->setAlias($className, $id); + } + + + /** + * @param $port + * @return bool + * @throws Exception + */ + public static function port_already($port): bool + { + if (empty($port)) { + return false; + } + if (Snowflake::getPlatform()->isLinux()) { + exec('netstat -tunlp | grep ' . $port, $output); + } else { + exec('lsof -i :' . $port . ' | grep -i "LISTEN"', $output); + } + return !empty($output); + } + + + /** + * @return Annotation + * @throws Exception + */ + public static function getAnnotation(): Annotation + { + return static::app()->getAnnotation(); + } + + + /** + * @param $service + * @return string + */ + #[Pure] public static function listen($service): string + { + return sprintf('Check listen %s::%d -> ok', $service['host'], $service['port']); + } + + + /** + * @param $className + * @param array $construct + * @return mixed + * @throws NotFindClassException + * @throws ReflectionException + * @throws Exception + */ + public static function createObject($className, array $construct = []): mixed + { + if (is_object($className)) { + return $className; + } + if (is_string($className)) { + return static::$container->get($className, $construct); + } else if (is_array($className)) { + if (!isset($className['class']) || empty($className['class'])) { + throw new Exception('Object configuration must be an array containing a "class" element.'); + } + + $class = $className['class']; + unset($className['class']); + + return static::$container->get($class, $construct, $className); + } else if (is_callable($className, TRUE)) { + return call_user_func($className, $construct); + } else { + throw new Exception('Unsupported configuration type: ' . gettype($className)); + } + } + + /** + * @return string + * @throws Exception + */ + public static function getStoragePath(): string + { + $default = APP_PATH . 'storage' . DIRECTORY_SEPARATOR; + $path = Config::get('storage', $default); + if (!is_dir($path)) { + mkdir($path, 0777, true); + } + return $path; + } + + + /** + * @return bool + */ + public static function inCoroutine(): bool + { + return Coroutine::getCid() > 0; + } + + + /** + * @return Container + */ + public static function getDi(): Container + { + return static::$container; + } + + + /** + * @param $workerId + * @return mixed + * @throws Exception + */ + public static function setManagerId($workerId): mixed + { + if (empty($workerId) || static::isDcoker()) { + return $workerId; + } + + $tmpFile = storage($workerId . '.sock', 'pid/manager'); + + return self::writeFile($tmpFile, $workerId); + } + + + /** + * @param $workerId + * @return mixed + * @throws Exception + */ + public static function setProcessId($workerId): mixed + { + if (empty($workerId) || static::isDcoker()) { + return $workerId; + } + + $tmpFile = storage($workerId . '.sock', 'pid/process'); + + return self::writeFile($tmpFile, $workerId); + } + + + /** + * @return bool + */ + public static function isDcoker(): bool + { + $output = shell_exec('[ -f /.dockerenv ] && echo yes || echo no'); + if (trim($output) === 'yes') { + return true; + } + return false; + } + + + /** + * @param $workerId + * @return mixed + * @throws Exception + */ + public static function setWorkerId($workerId): mixed + { + if (empty($workerId) || static::isDcoker()) { + return $workerId; + } + + $tmpFile = storage($workerId . '.sock', 'pid/worker'); + + return self::writeFile($tmpFile, $workerId); + } + + + /** + * @param $workerId + * @return mixed + * @throws Exception + */ + public static function setTaskId($workerId): mixed + { + if (empty($workerId) || static::isDcoker()) { + return $workerId; + } + + $tmpFile = storage($workerId . '.sock', 'pid/task'); + + return self::writeFile($tmpFile, $workerId); + } + + /** + * @param $fileName + * @param $content + * @param null $is_append + * @return mixed + */ + public static function writeFile($fileName, $content, $is_append = null): mixed + { + $params = [$fileName, (string)$content]; + if ($is_append !== null) { + $params[] = $is_append; + } + return !self::inCoroutine() ? file_put_contents(...$params) : Coroutine::writeFile(...$params); + } + + + /** + * @param $object + * @param $config + * @return mixed + */ + public static function configure($object, $config): mixed + { + foreach ($config as $key => $value) { + if (!property_exists($object, $key)) { + continue; + } + $object->$key = $value; + } + return $object; + } + + + /** + * @param $workerId + * @param bool $isWorker + * @throws Exception + */ + public static function clearProcessId($workerId, $isWorker = false) + { + clearstatcache(); + $directory = $isWorker === true ? 'pid/worker' : 'pid/task'; + if (!file_exists($file = storage($workerId, $directory))) { + return; + } + shell_exec('rm -rf ' . $file); + } + + + /** + * @param string|null $taskPid + * @throws Exception + */ + public static function clearTaskPid(string $taskPid = null) + { + if (empty($taskPid)) { + exec('rm -rf ' . storage(null, 'pid/task')); + } else { + static::clearProcessId($taskPid); + } + } + + + /** + * @param $taskPid + * @throws Exception + */ + public static function clearWorkerPid($taskPid = null) + { + if (empty($taskPid)) { + exec('rm -rf ' . storage(null, 'pid/worker')); + } else { + static::clearProcessId($taskPid, true); + } + } + + + /** + * @return Server|null + * @throws + */ + public static function getWebSocket(): ?\Swoole\Server + { + $server = static::app()->getSwoole(); + if (!($server instanceof \Swoole\Server)) { + return null; + } + return $server; + } + + + /** + * @return false|string + * @throws Exception + */ + public static function getMasterPid(): bool|string + { + $pid = Snowflake::app()->getSwoole()->setting['pid_file']; + + return file_get_contents($pid); + } + + + /** + * @param int $fd + * @param $data + * @return mixed + * @throws Exception + */ + public static function push(int $fd, $data): mixed + { + $server = static::getWebSocket(); + if (empty($server) || !$server->isEstablished($fd)) { + return false; + } + if (!is_string($data)) { + $data = Json::encode($data); + } + return $server->push($fd, $data); + } + + + /** + * @return mixed + */ + public static function localhost(): mixed + { + return current(swoole_get_local_ip()); + } + + + /** + * @param string $class + * @param array $params + * @throws NotFindClassException + * @throws ReflectionException + * @throws Exception + */ + public static function async(string $class, array $params = []) + { + $server = static::app()->getSwoole(); + if (!isset($server->setting['task_worker_num']) || !class_exists($class)) { + return; + } + + /** @var Task $class */ + $class = static::createObject($class); + $class->setParams($params); + + $server->task(swoole_serialize($class)); + } + + + /** + * @param $v1 + * @param $v2 + * @return float + */ + #[Pure] public static function distance(array $v1, array $v2): float + { + $maxX = max($v1['x'], $v2['x']); + $minX = min($v1['x'], $v2['x']); + + $maxZ = max($v1['z'], $v2['z']); + $minZ = min($v1['z'], $v2['z']); + + $dx = abs($maxX - $minX); + $dy = abs($maxZ - $minZ); + + $sqrt = sqrt($dx * $dx + $dy * $dy); + if ($sqrt < 0) { + $sqrt = abs($sqrt); + } + return (float)$sqrt; + } + + + /** + * @param $process + * @throws Exception + */ + public static function shutdown($process): void + { + static::app()->getSwoole()->shutdown(); + if ($process instanceof Process) { + $process->exit(0); + } + } + + + /** + * @param $tmp_name + * @return string + */ + public static function rename($tmp_name): string + { + $hash = md5_file($tmp_name); + + $later = '.' . exif_imagetype($tmp_name); + + $match = '/(\w{12})(\w{5})(\w{9})(\w{6})/'; + $tmp = preg_replace($match, '$1-$2-$3-$4', $hash); + + return strtoupper($tmp) . $later; + } + + + /** + * @return Environmental + * @throws + */ + public static function getPlatform(): Environmental + { + return Snowflake::createObject(Environmental::class); + } + + + /** + * @return mixed + * @throws Exception + */ + public static function reload(): mixed + { + return Snowflake::app()->getSwoole()->reload(); + } + + + private static array $_autoload = []; + + + const PROCESS = 'process'; + const TASK = 'task'; + const WORKER = 'worker'; + + + /** + * @param string $event + * @param null $data + * @return false|string + * @throws Exception + */ + public static function param(string $event, $data = NULL): bool|string + { + if (is_object($data)) { + if ($data instanceof ActiveRecord || $data instanceof Collection) { + $data = $data->getAttributes(); + } else { + $data = get_object_vars($data); + } + } + if (!is_array($data)) $data = ['data' => $data]; + return json_encode(array_merge(['callback' => $event], $data)); + } + + + /** + * @return string|null + */ + #[Pure] public static function getEnvironmental(): ?string + { + return env('environmental'); + } + + + /** + * @return bool + */ + #[Pure] public static function isTask(): bool + { + return static::getEnvironmental() == static::TASK; + } + + + /** + * @return bool + */ + #[Pure] public static function isWorker(): bool + { + return static::getEnvironmental() == static::WORKER; + } + + + /** + * @return bool + */ + #[Pure] public static function isProcess(): bool + { + return static::getEnvironmental() == static::PROCESS; + } + + + /** + * @param $class + * @param $file + */ + public static function setAutoload($class, $file) + { + if (isset(static::$_autoload[$class])) { + return; + } + static::$_autoload[$class] = $file; + include_once "$file"; + } + + + /** + * @param $className + */ + public static function autoload($className) + { + if (!isset(static::$_autoload[$className])) { + return; + } + $file = static::$_autoload[$className]; + require_once "$file"; + } }