diff --git a/HttpServer/Action.php b/HttpServer/Action.php new file mode 100644 index 00000000..095fded9 --- /dev/null +++ b/HttpServer/Action.php @@ -0,0 +1,152 @@ +get('server'); +// if (isset($argv[2])) { +// $this->modify($argv, $socket); +// } + + if (!isset($argv[1])) $argv[1] = 'start'; + + return $this->checkAction($argv, $socket); + } + + /** + * @param $argv + * @param $socket + * @return Server + * @throws Exception + */ + private function checkAction($argv, $socket) + { + if (!in_array($argv[1], ['stop', 'start', 'restart'])) { + exit($this->error('action not exists.')); + } + return $this->{$argv[1]}($socket); + } + + /** + * @param \HttpServer\Server $socket + * @return mixed + * @throws Exception + */ + public function restart($socket) + { + $this->_shutdown($socket); + + return $this->start(); + } + + + /** + * @param \HttpServer\Server $socket + * @throws Exception + */ + public function stop($socket) + { + $this->_shutdown($socket); + } + + /** + * @param $server + * @return void + * @throws Exception + */ + private function _shutdown($server) + { + $socket = storage('socket.sock'); + if (!file_exists($socket)) { + $this->close($server); + } else { + $pathId = file_get_contents($socket); + @unlink($socket); + + if (empty($pathId)) { + $this->close($server); + } else { + exec("kill -TERM $pathId"); + $this->close($server); + } + } + } + + /** + * @param \HttpServer\Server $server + * @return void + * @throws Exception + */ + private function close($server) + { + echo 'waite.'; + while ($server->isRunner()) { + echo '.'; + $pods = glob(storage('workerIds') . '/*'); + if (count($pods) < 1) { + break; + } + foreach ($pods as $pid) { + if (!file_exists($pid)) { + continue; + } + $content = file_get_contents($pid); + exec("ps -ax | awk '{ print $1 }' | grep -e '^{$content}$'", $output); + if (count($output) > 0) { + $this->closeByPid($content); + } else { + file_exists($pid) && @unlink($pid); + } + } + usleep(100); + } + echo PHP_EOL; + } + + + /** + * @param $port + * @return bool|array + */ + private function isUse($port) + { + if (empty($port)) { + return false; + } + exec('netstat -tunlp tcp | grep ' . $port, $output); + if (empty($output)) { + return false; + } + return $output; + } + + /** + * @param $pid + */ + private function closeByPid($pid) + { + shell_exec('kill -TERM ' . $pid); + } + + +} diff --git a/HttpServer/Command.php b/HttpServer/Command.php index 1fade6ca..fc8e9d9b 100644 --- a/HttpServer/Command.php +++ b/HttpServer/Command.php @@ -6,6 +6,7 @@ namespace HttpServer; use Console\Dtl; use Snowflake\Exception\ComponentException; +use Snowflake\Exception\ConfigException; use Snowflake\Snowflake; /** @@ -28,7 +29,8 @@ class Command extends \Console\Command /** * @param Dtl $dtl - * @throws ComponentException + * @throws ComponentException|ConfigException + * @throws \Exception */ public function handler(Dtl $dtl) { @@ -36,7 +38,18 @@ class Command extends \Console\Command /** @var Server $server */ $server = Snowflake::app()->get('server'); - $server->start(); + switch ($action) { + case 'restart': + $server->shutdown(); + $server->start(); + break; + case 'stop': + $server->shutdown(); + break; + case 'start': + default: + $server->start(); + } } } diff --git a/HttpServer/Server.php b/HttpServer/Server.php index d2eca66b..0aa548cf 100644 --- a/HttpServer/Server.php +++ b/HttpServer/Server.php @@ -41,6 +41,8 @@ use Swoole\Runtime; */ class Server extends Application { + use Action; + const HTTP = 'HTTP'; const TCP = 'TCP'; const PACKAGE = 'PACKAGE'; @@ -58,7 +60,6 @@ class Server extends Application /** @var Http|Websocket|Packet|Receive */ private $baseServer; - /** * @param array $configs * @return Http|Packet|Receive|Websocket @@ -92,10 +93,48 @@ class Server extends Application { $configs = Config::get('servers', true); $baseServer = $this->initCore($configs); + + foreach ($configs as $config) { + if ($this->isUse($config['port'])) { + return $this->error('Port ' . $config['host'] . '::' . $config['port'] . ' is already.'); + } + } $baseServer->start(); } + /** + * @return bool + */ + public function isRunner() + { + if (empty($this->port)) { + return false; + } + if (Snowflake::isLinux()) { + exec('netstat -tunlp | grep ' . $this->port, $output); + } else { + exec('lsof -i :' . $this->port . ' | grep -i "LISTEN"', $output); + } + if (!empty($output)) { + return true; + } + return false; + } + + + /** + * @return void + * + * start server + * @throws Exception + */ + public function shutdown() + { + $this->stop($this); + } + + /** * @param bool $isEnable */