Files
zhamao-framework/src/ZM/Command/PureHttpCommand.php

95 lines
3.7 KiB
PHP
Raw Normal View History

2020-09-29 15:07:43 +08:00
<?php
namespace ZM\Command;
2020-10-03 23:00:18 +08:00
use Swoole\Atomic;
use Swoole\Coroutine;
2020-09-29 15:07:43 +08:00
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Http\Server;
use Swoole\Process;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
2020-11-03 21:02:24 +08:00
use ZM\Store\ZMAtomic;
2020-09-29 15:07:43 +08:00
use ZM\Utils\HttpUtil;
class PureHttpCommand extends Command
{
// the name of the command (the part after "bin/console")
protected static $defaultName = 'simple-http-server';
protected function configure() {
$this->setDescription("Run a simple http server | 启动一个简单的文件 HTTP 服务器");
$this->setHelp("直接运行可以启动");
2020-11-03 21:02:24 +08:00
$this->addArgument('dir', InputArgument::REQUIRED, 'Your directory');
2020-09-29 15:07:43 +08:00
$this->addOption("host", 'H', InputOption::VALUE_REQUIRED, "启动监听地址");
$this->addOption("port", 'P', InputOption::VALUE_REQUIRED, "启动监听地址的端口");
// ...
}
protected function execute(InputInterface $input, OutputInterface $output) {
$tty_width = explode(" ", trim(exec("stty size")))[1];
2020-11-03 21:02:24 +08:00
if(realpath($input->getArgument('dir') ?? '.') === false) {
$output->writeln("<error>Directory error(".($input->getArgument('dir') ?? '.')."): no such file or directory.</error>");
return self::FAILURE;
}
2020-09-29 15:07:43 +08:00
$global = ZMConfig::get("global");
$host = $input->getOption("host") ?? $global["host"];
$port = $input->getOption("port") ?? $global["port"];
$server = new Server($host, $port);
2020-10-03 23:00:18 +08:00
$server->set(ZMConfig::get("global", "swoole"));
Console::init(0, $server);
2020-11-03 21:02:24 +08:00
ZMAtomic::$atomics["request"] = [];
2020-10-03 23:00:18 +08:00
for ($i = 0; $i < 32; ++$i) {
2020-11-03 21:02:24 +08:00
ZMAtomic::$atomics["request"][$i] = new Atomic(0);
2020-10-03 23:00:18 +08:00
}
2020-09-29 15:07:43 +08:00
$index = ["index.html", "index.htm"];
2020-10-03 23:00:18 +08:00
$server->on("request", function (Request $request, Response $response) use ($input, $index, $server) {
2020-11-03 21:02:24 +08:00
ZMAtomic::$atomics["request"][$server->worker_id]->add(1);
2020-09-29 15:07:43 +08:00
HttpUtil::handleStaticPage(
$request->server["request_uri"],
$response,
[
"document_root" => realpath($input->getArgument('dir') ?? '.'),
"document_index" => $index
]);
2020-10-03 23:00:18 +08:00
echo "\r".Coroutine::stats()["coroutine_peak_num"];
2020-09-29 15:07:43 +08:00
});
2020-10-03 23:00:18 +08:00
$server->on("start", function ($server) {
Process::signal(SIGINT, function () use ($server) {
2020-09-29 15:07:43 +08:00
Console::warning("Server interrupted by keyboard.");
2020-10-03 23:00:18 +08:00
for ($i = 0; $i < 32; ++$i) {
2020-11-03 21:02:24 +08:00
$num = ZMAtomic::$atomics["request"][$i]->get();
2020-10-03 23:00:18 +08:00
if($num != 0)
echo "[$i]: ".$num."\n";
}
2020-09-29 15:07:43 +08:00
$server->shutdown();
$server->stop();
});
Console::success("Server started. Use Ctrl+C to stop.");
});
$out = [
"host" => $host,
"port" => $port,
"document_root" => realpath($input->getArgument('dir') ?? '.'),
"document_index" => implode(", ", $index)
];
Console::printProps($out, $tty_width);
$server->start();
// return this if there was no problem running the command
// (it's equivalent to returning int(0))
return Command::SUCCESS;
// or return this if some error happened during the execution
// (it's equivalent to returning int(1))
// return Command::FAILURE;
}
}