diff --git a/src/Application.php b/src/Application.php index e0b4cf8..0e6ac42 100644 --- a/src/Application.php +++ b/src/Application.php @@ -10,12 +10,27 @@ */ namespace Simps; +use Simps\Console\Command; +use Simps\Utils\Env; +use Swoole\Coroutine; + class Application { /** * @var string */ - protected static $version = '1.0.5'; + protected static $version = '2.0.0-dev'; + + protected $console = [ + // Server相关 + \Simps\Console\Server\StatusCommand::class, + \Simps\Console\Server\StartCommand::class, + \Simps\Console\Server\StopCommand::class, + \Simps\Console\Server\RestartCommand::class, + + // 其他命令 + \Simps\Console\Other\HelpCommand::class, + ]; public static function welcome() { @@ -48,41 +63,40 @@ public static function echoError($msg) self::println('[' . date('Y-m-d H:i:s') . '] [ERROR] ' . "\033[31m{$msg}\033[0m"); } - public static function run() + /** + * @return string[] + */ + public function getConsole() + { + return $this->console; + } + + public function start() { + // 初始化环境变量 + container(Env::class); + // 获取所有命令 + $this->console = array_merge($this->console, config('console', [])); + self::welcome(); global $argv; - $count = count($argv); - $funcName = $argv[$count - 1]; - $command = explode(':', $funcName); - switch ($command[0]) { - case 'http': - $className = \Simps\Server\Http::class; - break; - case 'ws': - $className = \Simps\Server\WebSocket::class; - break; - case 'mqtt': - $className = \Simps\Server\MqttServer::class; - break; - case 'main': - $className = \Simps\Server\MainServer::class; - break; - default: - // 用户自定义server - $configs = config('servers', []); - if (isset($configs[$command[0]], $configs[$command[0]]['class_name'])) { - $className = $configs[$command[0]]['class_name']; - } else { - exit(self::echoError("command {$command[0]} is not exist, you can use {$argv[0]} [http:start, ws:start, mqtt:start, main:start]")); + $command = $argv[1] ?? 'help'; + $params = isset($argv[2]) ? array_slice($argv, 2) : []; + foreach ($this->console as $cls) { + $obj = new $cls($this, $params); + if ($obj instanceof Command) { + if ($command == $obj->getCommand()) { + if ($obj->getCoroutine()) { + Coroutine\run(function () use ($obj) { + $obj->handle(); + }); + } else { + $obj->handle(); + } + return; } + } } - switch ($command[1]) { - case 'start': - new $className(); - break; - default: - self::echoError("use {$argv[0]} [http:start, ws:start, mqtt:start, main:start]"); - } + self::echoError("Command `{$command}` not found"); } } diff --git a/src/Console/Command.php b/src/Console/Command.php new file mode 100644 index 0000000..56fa793 --- /dev/null +++ b/src/Console/Command.php @@ -0,0 +1,71 @@ +app = $app; + $this->params = $params; + } + + public function getCoroutine() + { + return $this->coroutine; + } + + /** + * @return bool + */ + public function getShow() + { + return $this->show; + } + + /** + * @return string + */ + public function getHelp() + { + return $this->help; + } + + /** + * @return string + */ + public function getCommand() + { + return $this->command; + } + + /** + * 运行命令. + */ + abstract public function handle(); +} diff --git a/src/Console/Other/HelpCommand.php b/src/Console/Other/HelpCommand.php new file mode 100644 index 0000000..f55d424 --- /dev/null +++ b/src/Console/Other/HelpCommand.php @@ -0,0 +1,37 @@ +app->getConsole(); + foreach ($list as $cls) { + $obj = new $cls($this->app); + if ($obj->getShow()) { + $k = $obj->getCommand(); + $v = $obj->getHelp(); + $commands[$k] = $v; + } + } + foreach ($commands as $command => $help) { + echo "{$command}\t\t`{$help}`\n"; + } + } +} diff --git a/src/Console/Server/RestartCommand.php b/src/Console/Server/RestartCommand.php new file mode 100644 index 0000000..6600d90 --- /dev/null +++ b/src/Console/Server/RestartCommand.php @@ -0,0 +1,29 @@ +params[0] ?? 'http'; + $pid = (int) @file_get_contents(sprintf($this->pid, $ser)); + if ($pid > 0) { + \Swoole\Process::kill($pid, SIGUSR1); + } + } +} diff --git a/src/Console/Server/StartCommand.php b/src/Console/Server/StartCommand.php new file mode 100644 index 0000000..1cc6971 --- /dev/null +++ b/src/Console/Server/StartCommand.php @@ -0,0 +1,53 @@ +params[0] ?? 'http'; + $met = 'start'; + + // 检测服务是否已经启动 + $pid = (int) @file_get_contents(sprintf($this->pid, $ser)); + if ($pid > 0) { + $r = \Swoole\Process::kill($pid, 0); + if ($r) { + Application::echoError("Service `{$ser}` is running"); + return; + } + } + + // 获取服务配置并启动 + $config = config('servers', []); + $config = $config[$ser] ?? null; + if (! $config) { + Application::echoError('Service does not exist'); + exit; + } + $config['name'] = $ser; + $cls = $config['provider']; + $obj = new $cls($config); + if (method_exists($obj, $met)) { + $obj->{$met}(); + } else { + Application::echoError('Service does not exist'); + } + } +} diff --git a/src/Console/Server/StatusCommand.php b/src/Console/Server/StatusCommand.php new file mode 100644 index 0000000..8e46b1d --- /dev/null +++ b/src/Console/Server/StatusCommand.php @@ -0,0 +1,42 @@ + $v) { + $status = $this->getServerStatus($ser) ? 'runtime' : 'stop'; + Application::echoSuccess("Service `{$ser}` {$status}"); + } + } + + /** + * @param string $ser + * @return bool|mixed + */ + protected function getServerStatus($ser) + { + $pid = (int) @file_get_contents(sprintf($this->pid, $ser)); + if ($pid > 0) { + return \Swoole\Process::kill($pid, 0); + } + return false; + } +} diff --git a/src/Console/Server/StopCommand.php b/src/Console/Server/StopCommand.php new file mode 100644 index 0000000..7056e2a --- /dev/null +++ b/src/Console/Server/StopCommand.php @@ -0,0 +1,29 @@ +params[0] ?? 'http'; + $pid = (int) @file_get_contents(sprintf($this->pid, $ser)); + if ($pid > 0) { + \Swoole\Process::kill($pid, SIGTERM); + } + } +}