add
This commit is contained in:
+172
@@ -0,0 +1,172 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace think\swoole\command;
|
||||
|
||||
use Nette\PhpGenerator\ClassType;
|
||||
use Nette\PhpGenerator\Helpers;
|
||||
use Nette\PhpGenerator\PhpFile;
|
||||
use think\console\Command;
|
||||
use think\helper\Arr;
|
||||
use think\swoole\contract\rpc\ParserInterface;
|
||||
use think\swoole\rpc\client\Gateway;
|
||||
use think\swoole\rpc\JsonParser;
|
||||
|
||||
class RpcInterface extends Command
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('rpc:interface')
|
||||
->setDescription('Generate Rpc Service Interfaces');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$clients = $this->app->config->get('swoole.rpc.client', []);
|
||||
|
||||
$file = new PhpFile;
|
||||
$file->addComment('This file is auto-generated.');
|
||||
$file->setStrictTypes();
|
||||
$services = [];
|
||||
foreach ($clients as $name => $config) {
|
||||
|
||||
$parserClass = Arr::get($config, 'parser', JsonParser::class);
|
||||
/** @var ParserInterface $parser */
|
||||
$parser = new $parserClass;
|
||||
|
||||
$gateway = new Gateway($config, $parser);
|
||||
|
||||
$result = $gateway->getServices();
|
||||
|
||||
$namespace = $file->addNamespace("rpc\\contract\\${name}");
|
||||
|
||||
foreach ($result as $interface => $methods) {
|
||||
|
||||
$services[$name][] = $namespace->getName() . "\\{$interface}";
|
||||
|
||||
$class = $namespace->addInterface($interface);
|
||||
|
||||
foreach ($methods as $methodName => ['parameters' => $parameters, 'returnType' => $returnType, 'comment' => $comment]) {
|
||||
$method = $class->addMethod($methodName)
|
||||
->setVisibility(ClassType::VISIBILITY_PUBLIC)
|
||||
->setComment(Helpers::unformatDocComment($comment))
|
||||
->setReturnType($returnType);
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
if ($parameter['type'] && (class_exists($parameter['type']) || interface_exists($parameter['type']))) {
|
||||
$namespace->addUse($parameter['type']);
|
||||
}
|
||||
$param = $method->addParameter($parameter['name'])
|
||||
->setTypeHint($parameter['type']);
|
||||
|
||||
if (array_key_exists("default", $parameter)) {
|
||||
$param->setDefaultValue($parameter['default']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$services = "return " . Helpers::dump($services) . ";";
|
||||
|
||||
file_put_contents($this->app->getBasePath() . 'rpc.php', $file . $services);
|
||||
|
||||
$this->output->writeln('<info>Succeed!</info>');
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\swoole\command;
|
||||
|
||||
use Swoole\Http\Server as HttpServer;
|
||||
use Swoole\WebSocket\Server as WebsocketServer;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\Output;
|
||||
use think\swoole\Manager;
|
||||
use think\swoole\PidManager;
|
||||
|
||||
/**
|
||||
* Swoole HTTP 命令行,支持操作:start|stop|restart|reload
|
||||
* 支持应用配置目录下的swoole.php文件进行参数配置
|
||||
*/
|
||||
class Server extends Command
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('swoole')
|
||||
->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload", 'start')
|
||||
->setDescription('Swoole HTTP 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 Manager $manager
|
||||
* @param PidManager $pidManager
|
||||
* @return void
|
||||
*/
|
||||
protected function start(Manager $manager, PidManager $pidManager)
|
||||
{
|
||||
if ($pidManager->isRunning()) {
|
||||
$this->output->writeln('<error>swoole http server process is already running.</error>');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->output->writeln('Starting swoole http server...');
|
||||
|
||||
$host = $manager->getConfig('server.host');
|
||||
$port = $manager->getConfig('server.port');
|
||||
|
||||
$this->output->writeln("Swoole http server started: <http://{$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 http server process running.</error>');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->output->writeln('Reloading swoole http 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 http server process running.</error>');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->output->writeln('Stopping swoole http server...');
|
||||
|
||||
$isRunning = $manager->killProcess(SIGTERM, 15);
|
||||
|
||||
if ($isRunning) {
|
||||
$this->output->error('Unable to stop the swoole_http_server process.');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->output->writeln('> success');
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启server
|
||||
* @access protected
|
||||
* @param Manager $manager
|
||||
* @param PidManager $pidManager
|
||||
* @return void
|
||||
*/
|
||||
protected function restart(Manager $manager, PidManager $pidManager)
|
||||
{
|
||||
if ($pidManager->isRunning()) {
|
||||
$this->stop($pidManager);
|
||||
}
|
||||
|
||||
$this->start($manager, $pidManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create swoole server.
|
||||
*/
|
||||
protected function createSwooleServer()
|
||||
{
|
||||
|
||||
$isWebsocket = $this->app->config->get('swoole.websocket.enable', false);
|
||||
|
||||
$serverClass = $isWebsocket ? WebsocketServer::class : HttpServer::class;
|
||||
$config = $this->app->config;
|
||||
$host = $config->get('swoole.server.host');
|
||||
$port = $config->get('swoole.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 $serverClass($host, $port, $mode, $socketType);
|
||||
|
||||
$options = $config->get('swoole.server.options');
|
||||
|
||||
$server->set($options);
|
||||
return $server;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user