173 lines
4.6 KiB
PHP
173 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace think\swoole\command;
|
|
|
|
use think\console\Command;
|
|
use think\console\Input;
|
|
use think\console\input\Argument;
|
|
use think\console\Output;
|
|
use think\swoole\PidManager;
|
|
use think\swoole\RpcManager;
|
|
|
|
class Rpc extends Command
|
|
{
|
|
public function configure()
|
|
{
|
|
$this->setName('swoole:rpc')
|
|
->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload", 'start')
|
|
->setDescription('Swoole RPC Server for ThinkPHP');
|
|
}
|
|
|
|
protected function initialize(Input $input, Output $output)
|
|
{
|
|
$this->app->bind(\Swoole\Server::class, function () {
|
|
return $this->createSwooleServer();
|
|
});
|
|
|
|
$this->app->bind(PidManager::class, function () {
|
|
return new PidManager($this->app->config->get("swoole.server.options.pid_file"));
|
|
});
|
|
}
|
|
|
|
public function handle()
|
|
{
|
|
$this->checkEnvironment();
|
|
|
|
$action = $this->input->getArgument('action');
|
|
|
|
if (in_array($action, ['start', 'stop', 'reload', 'restart'])) {
|
|
$this->app->invokeMethod([$this, $action], [], true);
|
|
} else {
|
|
$this->output->writeln("<error>Invalid argument action:{$action}, Expected start|stop|restart|reload .</error>");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检查环境
|
|
*/
|
|
protected function checkEnvironment()
|
|
{
|
|
if (!extension_loaded('swoole')) {
|
|
$this->output->error('Can\'t detect Swoole extension installed.');
|
|
|
|
exit(1);
|
|
}
|
|
|
|
if (!version_compare(swoole_version(), '4.3.1', 'ge')) {
|
|
$this->output->error('Your Swoole version must be higher than `4.3.1`.');
|
|
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 启动server
|
|
* @access protected
|
|
* @param RpcManager $manager
|
|
* @param PidManager $pidManager
|
|
* @return void
|
|
*/
|
|
protected function start(RpcManager $manager, PidManager $pidManager)
|
|
{
|
|
if ($pidManager->isRunning()) {
|
|
$this->output->writeln('<error>swoole rpc server process is already running.</error>');
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('Starting swoole rpc server...');
|
|
|
|
$host = $this->app->config->get('swoole.server.host');
|
|
$port = $this->app->config->get('swoole.rpc.server.port');
|
|
|
|
$this->output->writeln("Swoole rpc server started: <tcp://{$host}:{$port}>");
|
|
$this->output->writeln('You can exit with <info>`CTRL-C`</info>');
|
|
|
|
$manager->run();
|
|
}
|
|
|
|
/**
|
|
* 柔性重启server
|
|
* @access protected
|
|
* @param PidManager $manager
|
|
* @return void
|
|
*/
|
|
protected function reload(PidManager $manager)
|
|
{
|
|
if (!$manager->isRunning()) {
|
|
$this->output->writeln('<error>no swoole rpc server process running.</error>');
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('Reloading swoole rpc server...');
|
|
|
|
if (!$manager->killProcess(SIGUSR1)) {
|
|
$this->output->error('> failure');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('> success');
|
|
}
|
|
|
|
/**
|
|
* 停止server
|
|
* @access protected
|
|
* @param PidManager $manager
|
|
* @return void
|
|
*/
|
|
protected function stop(PidManager $manager)
|
|
{
|
|
if (!$manager->isRunning()) {
|
|
$this->output->writeln('<error>no swoole rpc server process running.</error>');
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('Stopping swoole rpc server...');
|
|
|
|
$isRunning = $manager->killProcess(SIGTERM, 15);
|
|
|
|
if ($isRunning) {
|
|
$this->output->error('Unable to stop the rpc process.');
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('> success');
|
|
}
|
|
|
|
/**
|
|
* 重启server
|
|
* @access protected
|
|
* @param RpcManager $manager
|
|
* @param PidManager $pidManager
|
|
* @return void
|
|
*/
|
|
protected function restart(RpcManager $manager, PidManager $pidManager)
|
|
{
|
|
if ($pidManager->isRunning()) {
|
|
$this->stop($pidManager);
|
|
}
|
|
|
|
$this->start($manager, $pidManager);
|
|
}
|
|
|
|
/**
|
|
* Create swoole server.
|
|
*/
|
|
protected function createSwooleServer()
|
|
{
|
|
$config = $this->app->config;
|
|
$host = $config->get('swoole.server.host');
|
|
$port = $config->get('swoole.rpc.server.port');
|
|
$socketType = $config->get('swoole.server.socket_type', SWOOLE_SOCK_TCP);
|
|
$mode = $config->get('swoole.server.mode', SWOOLE_PROCESS);
|
|
|
|
/** @var \Swoole\Server $server */
|
|
$server = new \Swoole\Server($host, $port, $mode, $socketType);
|
|
|
|
$options = $config->get('swoole.server.options');
|
|
|
|
$server->set($options);
|
|
return $server;
|
|
}
|
|
}
|