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

102 lines
3.9 KiB
PHP
Raw Normal View History

2020-09-29 15:07:43 +08:00
<?php
declare(strict_types=1);
2020-09-29 15:07:43 +08:00
namespace ZM\Command;
2020-10-03 23:00:18 +08:00
use Swoole\Atomic;
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;
use ZM\Framework;
2020-11-03 21:02:24 +08:00
use ZM\Store\ZMAtomic;
use ZM\Utils\DataProvider;
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');
$this->addOption('host', 'H', InputOption::VALUE_REQUIRED, '启动监听地址');
$this->addOption('port', 'P', InputOption::VALUE_REQUIRED, '启动监听地址的端口');
2020-09-29 15:07:43 +08:00
// ...
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$tty_width = explode(' ', trim(exec('stty size')))[1];
2021-02-09 17:09:09 +08:00
if (realpath($input->getArgument('dir') ?? '.') === false) {
$output->writeln('<error>Directory error(' . ($input->getArgument('dir') ?? '.') . '): no such file or directory.</error>');
2020-11-03 21:02:24 +08:00
return self::FAILURE;
}
2021-06-16 00:17:30 +08:00
ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config');
$global = ZMConfig::get('global');
$host = $input->getOption('host') ?? $global['host'];
$port = $input->getOption('port') ?? $global['port'];
$index = ['index.html', 'index.htm'];
$out = [
'listen' => $host . ':' . $port,
'version' => ZM_VERSION,
'web_root' => realpath($input->getArgument('dir') ?? '.'),
'index' => implode(',', $index),
];
Framework::printProps($out, $tty_width);
2020-09-29 15:07:43 +08:00
$server = new Server($host, $port);
$server->set(ZMConfig::get('global', 'swoole'));
Console::init(2, $server);
ZMAtomic::$atomics['request'] = [];
2020-10-03 23:00:18 +08:00
for ($i = 0; $i < 32; ++$i) {
ZMAtomic::$atomics['request'][$i] = new Atomic(0);
2020-10-03 23:00:18 +08:00
}
$server->on('request', function (Request $request, Response $response) use ($input, $index, $server) {
ZMAtomic::$atomics['request'][$server->worker_id]->add(1);
2020-09-29 15:07:43 +08:00
HttpUtil::handleStaticPage(
$request->server['request_uri'],
2020-09-29 15:07:43 +08:00
$response,
[
'document_root' => realpath($input->getArgument('dir') ?? '.'),
'document_index' => $index,
]
);
// echo "\r" . Coroutine::stats()["coroutine_peak_num"];
2020-09-29 15:07:43 +08:00
});
$server->on('start', function ($server) {
2020-10-03 23:00:18 +08:00
Process::signal(SIGINT, function () use ($server) {
echo "\r";
Console::warning('Server interrupted by keyboard.');
2020-10-03 23:00:18 +08:00
for ($i = 0; $i < 32; ++$i) {
$num = ZMAtomic::$atomics['request'][$i]->get();
if ($num != 0) {
echo "[{$i}]: " . $num . "\n";
}
2020-10-03 23:00:18 +08:00
}
2020-09-29 15:07:43 +08:00
$server->shutdown();
$server->stop();
});
Console::success('Server started. Use Ctrl+C to stop.');
2020-09-29 15:07:43 +08:00
});
$server->start();
// return this if there was no problem running the command
// (it's equivalent to returning int(0))
2021-04-06 01:19:56 +08:00
return 0;
2020-09-29 15:07:43 +08:00
// or return this if some error happened during the execution
// (it's equivalent to returning int(1))
2021-04-06 01:19:56 +08:00
// return 1;
2020-09-29 15:07:43 +08:00
}
}