diff --git a/Database/Connection.php b/Database/Connection.php index 1daac767..06e7cc07 100644 --- a/Database/Connection.php +++ b/Database/Connection.php @@ -211,7 +211,7 @@ class Connection extends Component */ private function connections(): \Snowflake\Pool\Connection { - return Snowflake::app()->getMysqlFromPool(); + return Snowflake::getDi()->get(\Snowflake\Pool\Connection::class); } diff --git a/System/Abstracts/BaseApplication.php b/System/Abstracts/BaseApplication.php index 14f34dee..8949eb59 100644 --- a/System/Abstracts/BaseApplication.php +++ b/System/Abstracts/BaseApplication.php @@ -11,6 +11,7 @@ namespace Snowflake\Abstracts; use Annotation\Annotation as SAnnotation; +use Database\Connection; use Exception; use HttpServer\Client\Http2; use HttpServer\Http\HttpHeaders; @@ -24,20 +25,19 @@ use HttpServer\Shutdown; use JetBrains\PhpStorm\Pure; use Kafka\KafkaProvider; use ReflectionException; +use Rpc\Producer; +use Rpc\Service; use Server\ServerManager; use Snowflake\Aop; use Snowflake\Async; use Snowflake\Cache\Redis; -use Snowflake\Di\Service; +use Snowflake\Di\LocalService; use Snowflake\Error\ErrorHandler; use Snowflake\Error\Logger; use Snowflake\Event; use Snowflake\Exception\InitException; use Snowflake\Exception\NotFindClassException; use Snowflake\Jwt\Jwt; -use Snowflake\Pool\Connection; -use Snowflake\Pool\Pool; -use Snowflake\Pool\Redis as SRedis; use Snowflake\Snowflake; use Swoole\Table; @@ -269,7 +269,7 @@ abstract class BaseApplication extends Component */ public function get($name): mixed { - return di(Service::class)->get($name); + return di(LocalService::class)->get($name); } @@ -329,26 +329,6 @@ abstract class BaseApplication extends Component } - /** - * @return Connection - * @throws Exception - */ - public function getMysqlFromPool(): Connection - { - return $this->get('connections'); - } - - - /** - * @return SRedis - * @throws Exception - */ - public function getRedisFromPool(): SRedis - { - return $this->get('redis_connections'); - } - - /** * @param $name * @return Table @@ -433,7 +413,7 @@ abstract class BaseApplication extends Component * @return \Rpc\Producer * @throws Exception */ - public function getRpc(): \Rpc\Producer + public function getRpc(): Producer { return $this->get('rpc'); } @@ -446,7 +426,7 @@ abstract class BaseApplication extends Component */ private function setComponents($array): void { - di(Service::class)->setComponents($array); + di(LocalService::class)->setComponents($array); } @@ -458,7 +438,7 @@ abstract class BaseApplication extends Component */ public function set($id, $definition): void { - di(Service::class)->set($id, $definition); + di(LocalService::class)->set($id, $definition); } @@ -470,7 +450,7 @@ abstract class BaseApplication extends Component */ public function has($id): bool { - return di(Service::class)->has($id); + return di(LocalService::class)->has($id); } @@ -481,27 +461,23 @@ abstract class BaseApplication extends Component { $this->setComponents([ 'error' => ['class' => ErrorHandler::class], - 'connections' => ['class' => Connection::class], - 'redis_connections' => ['class' => SRedis::class], 'config' => ['class' => Config::class], 'logger' => ['class' => Logger::class], 'annotation' => ['class' => SAnnotation::class], 'router' => ['class' => Router::class], 'event' => ['class' => Event::class], 'redis' => ['class' => Redis::class], - 'databases' => ['class' => \Database\Connection::class], + 'databases' => ['class' => Connection::class], 'aop' => ['class' => Aop::class], 'input' => ['class' => HttpParams::class], 'header' => ['class' => HttpHeaders::class], 'jwt' => ['class' => Jwt::class], 'async' => ['class' => Async::class], 'kafka-container' => ['class' => KafkaProvider::class], - 'filter' => ['class' => HttpFilter::class], - 'goto' => ['class' => BaseGoto::class], 'response' => ['class' => Response::class], 'request' => ['class' => Request::class], - 'rpc' => ['class' => \Rpc\Producer::class], - 'rpc-service' => ['class' => \Rpc\Service::class], + 'rpc' => ['class' => Producer::class], + 'rpc-service' => ['class' => Service::class], 'http2' => ['class' => Http2::class], 'shutdown' => ['class' => Shutdown::class], ]); diff --git a/System/Abstracts/TraitApplication.php b/System/Abstracts/TraitApplication.php index 5612bcd7..c24a14ae 100644 --- a/System/Abstracts/TraitApplication.php +++ b/System/Abstracts/TraitApplication.php @@ -35,7 +35,6 @@ use Snowflake\Pool\Pool; * @property Request $request * @property DatabasesProviders $db * @property Async $async - * @property Connection $connections * @property Logger $logger * @property Jwt $jwt * @property SAnnotation $annotation diff --git a/System/Cache/Redis.php b/System/Cache/Redis.php index c5a6cd0f..a694df3f 100644 --- a/System/Cache/Redis.php +++ b/System/Cache/Redis.php @@ -19,11 +19,11 @@ use Snowflake\Core\Json; use Snowflake\Events\EventProvider; use Snowflake\Exception\ConfigException; use Snowflake\Snowflake; +use Snowflake\Pool\Redis as PoolRedis; /** * Class Redis * @package Snowflake\Snowflake\Cache - * @see \Redis * @mixin \Redis */ class Redis extends Component @@ -42,7 +42,7 @@ class Redis extends Component */ public function init() { - $connections = Snowflake::app()->getRedisFromPool(); + $connections = Snowflake::getDi()->get(PoolRedis::class); $config = $this->get_config(); @@ -114,7 +114,7 @@ SCRIPT; */ public function release() { - $connections = Snowflake::app()->getRedisFromPool(); + $connections = Snowflake::getDi()->get(PoolRedis::class); $connections->release($this->get_config(), true); } @@ -125,7 +125,7 @@ SCRIPT; */ public function destroy() { - $connections = Snowflake::app()->getRedisFromPool(); + $connections = Snowflake::getDi()->get(PoolRedis::class); $connections->destroy($this->get_config(), true); } @@ -135,7 +135,7 @@ SCRIPT; */ public function proxy(): \Redis { - $connections = Snowflake::app()->getRedisFromPool(); + $connections = Snowflake::getDi()->get(PoolRedis::class); $config = $this->get_config(); diff --git a/System/Di/LocalService.php b/System/Di/LocalService.php new file mode 100644 index 00000000..d1d2a561 --- /dev/null +++ b/System/Di/LocalService.php @@ -0,0 +1,86 @@ +_components[$name]); + + $this->_definition[$name] = $define; + } + + + /** + * @throws \Exception + */ + public function get(string $name, $throwException = true) + { + if (isset($this->_components[$name])) { + return $this->_components[$name]; + } + if (isset($this->_definitions[$name])) { + $definition = $this->_definitions[$name]; + if (is_object($definition) && !$definition instanceof \Closure) { + return $this->_components[$name] = $definition; + } + return $this->_components[$name] = Snowflake::createObject($definition); + } else if ($throwException) { + throw new \Exception("Unknown component ID: $name"); + } + return null; + } + + + /** + * @param array $components + */ + public function setComponents(array $components) + { + foreach ($components as $name => $component) { + $this->set($name, $component); + } + } + + + /** + * @param $id + * @return bool + */ + public function has($id): bool + { + return isset($this->_components[$id], $this->_definition[$id]); + } + + + /** + * @param $id + */ + public function remove($id): void + { + unset($this->_components[$id], $this->_definition[$id]); + } + + +} diff --git a/System/Di/Service.php b/System/Di/Service.php deleted file mode 100644 index a28342d3..00000000 --- a/System/Di/Service.php +++ /dev/null @@ -1,165 +0,0 @@ -_components[$id])) { - return $this->_components[$id]; - } - $config = $this->_getConfig($id, $try); - if (!is_object($config)) { - $config = Snowflake::createObject($config); - } - return $this->_components[$id] = $config; - } - - - /** - * @param $id - * @param $try - * @return mixed - * @throws ComponentException - */ - private function _getConfig($id, $try): mixed - { - $config = $this->_definition[$id] ?? $this->_alias[$id] ?? null; - if (is_null($config)) { - if ($try === false) { - return null; - } - throw new ComponentException("Unknown component ID: $id"); - } - return $config; - } - - - /** - * @param string $className - * @param string $alias - */ - public function setAlias(string $className, string $alias) - { - $this->_alias[$className] = $alias; - } - - /** - * @param $id - * @param $definition - * - * @return mixed - * @throws Exception - */ - public function set($id, $definition): void - { - if ($definition === NULL) { - $this->remove($id); - return; - } - $this->_ids[] = $id; - unset($this->_components[$id]); - if (is_object($definition)) { - $this->_components[$id] = $definition; - $this->_definition[$id] = $definition; - } else if (!is_array($definition)) { - throw new ComponentException("Unexpected configuration type for the \"$id\" component: " . gettype($definition)); - } else { - $this->_definition[$id] = $definition; - } - } - - /** - * @param $id - * @return bool - */ - #[Pure] public function has($id): bool - { - return in_array($id, $this->_ids); - } - - /** - * @param array $data - * @throws Exception - */ - public function setComponents(array $data) - { - foreach ($data as $key => $val) { - $this->set($key, $val); - } - } - - - /** - * @param $name - * @return mixed - * @throws Exception - */ - public function __get($name): mixed - { - if ($this->has($name)) { - return $this->get($name); - } - - return parent::__get($name); - } - - /** - * @param $id - * @return bool - */ - public function remove($id): bool - { - $component = $this->_components[$id]; - $className = $component::class; - - unset($component, $this->_components[$id]); - unset($this->_definition[$id]); - if (isset($this->_alias[$id])) { - unset($this->_components[$this->_alias[$id]]); - unset($this->_definition[$this->_alias[$id]]); - unset($this->_alias[$id]); - } - - Snowflake::getDi()->unset($className); - - return $this->has($id); - } -} diff --git a/System/Jwt/JwtHelper.php b/System/Jwt/JwtHelper.php index bdf8bc8d..49a3835b 100644 --- a/System/Jwt/JwtHelper.php +++ b/System/Jwt/JwtHelper.php @@ -23,6 +23,9 @@ trait JwtHelper private string $secret = ''; + private string $scene = 'default'; + + private string $encrypt = 'sha256'; @@ -81,6 +84,13 @@ mlAZUEjsoaT9vjvjGTxl3uCm0TX5KTgtSJIt2kA1tYVjQef+/iZTHxY= $this->timeout = $timeout; } + + public function setScene(string $scene) + { + $this->scene = $scene; + } + + /** * @param string $timeout */ diff --git a/System/Snowflake.php b/System/Snowflake.php index a38d9b75..8be2e0a4 100644 --- a/System/Snowflake.php +++ b/System/Snowflake.php @@ -43,602 +43,597 @@ 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 object $class - */ - public static function injectProperty(object $class) - { - $attributes = static::getDi()->getClassReflectionProperty($class::class); - /** - * @var string $property - * @var ReflectionProperty $attribute - */ - foreach ($attributes as $property => $attribute) { - - foreach ($attribute->getAttributes() as $item) { - $item->newInstance()->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; - } - - - /** - * @return Application|null - */ - public static function getFactory(): ?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->newObject($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::isDocker()) { - 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::isDocker()) { - return $workerId; - } - - $tmpFile = storage($workerId . '.sock', 'pid/process'); - - return self::writeFile($tmpFile, $workerId); - } - - - /** - * @return bool - */ - public static function isDocker(): 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::isDocker()) { - 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::isDocker()) { - 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()->getClassReflectionProperty($class::class); + /** + * @var string $property + * @var ReflectionProperty $attribute + */ + foreach ($attributes as $property => $attribute) { + + foreach ($attribute->getAttributes() as $item) { + $item->newInstance()->execute($class, $property); + } + } + } + + + /** + * @param $service + * + * 初始化服务 + */ + public static function init($service) + { + static::$service = $service; + } + + + /** + * @param $alias + * @param array $array + * @throws Exception + */ + public static function set($alias, array $array = []) + { + 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; + } + + + /** + * @return Application|null + */ + public static function getFactory(): ?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_callable($className, TRUE)) { + return call_user_func($className, $construct); + } else if (is_string($className) && class_exists($className)) { + return static::$container->get($className, $construct); + } else if (is_array($className) && isset($class['class'])) { + $class = $className['class']; + unset($className['class']); + return static::$container->newObject($class, $construct, $className); + } else if (is_callable($className, TRUE)) { + return call_user_func($className, $construct); + } 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::isDocker()) { + 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::isDocker()) { + return $workerId; + } + + $tmpFile = storage($workerId . '.sock', 'pid/process'); + + return self::writeFile($tmpFile, $workerId); + } + + + /** + * @return bool + */ + public static function isDocker(): 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::isDocker()) { + 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::isDocker()) { + 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"; + } }