diff --git a/README.md b/README.md index 55e8d7b..5d59bf4 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ yii2 swoole https://www.jianshu.com/p/9c2788ccf3c0 4. 当你做完123 并且使用过yii2-swoole之后 可以去了解一下swoft 对比一下为协程而设计的框架和yii2这种的区别 +5. 需要php7+ 安装 --------------- @@ -41,32 +42,48 @@ yii2 swoole 'swoole-backend' => [ 'class' => feehi\console\SwooleController::class, 'rootDir' => str_replace('console/config', '', __DIR__ ),//yii2项目根路径 - 'app' => 'backend', - 'host' => '127.0.0.1', - 'port' => 9998, - 'web' => 'web',//默认为web。rootDir app web目的是拼接yii2的根目录,如果你的应用为basic,那么app为空即可。 - 'debug' => true,//默认开启debug,上线应置为false - 'env' => 'dev',//默认为dev,上线应置为prod - 'swooleConfig' => [ - 'reactor_num' => 2, - 'worker_num' => 4, - 'daemonize' => false, - 'log_file' => __DIR__ . '/../../backend/runtime/logs/swoole.log', - 'log_level' => 0, - 'pid_file' => __DIR__ . '/../../backend/runtime/server.pid', + 'appSettingRoot' => 'swoole', //保存应用设置文件夹,须为yii2项目根路径 ], ] ...//其他配置 ] ...//其他配置 ``` +下一步新建保存应用设置文件夹“swoole”(对应appSettingRoot),并在swoole文件夹中新建新的应用文件,如web_pc.php +例: +```bash + return [ + 'app' => 'app_web', + 'host' => '127.0.0.1', + 'port' => 9001, + 'web' => 'web_pc',//默认为web。rootDir app web目的是拼接yii2的根目录,如果你的应用为basic,那么app为空即可。 + 'debug' => true,//默认开启debug,上线应置为false + 'env' => 'dev',//默认为dev,上线应置为prod + 'swooleConfig' => [ + 'reactor_num' => 1, + 'worker_num' => 4, + 'daemonize' => false, + 'log_file' => __DIR__ . '/../app_web/runtime/logs/swoole_pc.log', + 'log_level' => 1, + 'pid_file' => __DIR__ . '/../app_web/runtime/server_pc.pid', + ], + //自定义调用设置文件,当此项不为空时调用当前设置 + 'customConfigFilenames' =>[ + __DIR__ . '/../common/config/main.php', + __DIR__ . '/../common/config/main-local.php', + __DIR__ . '/../app_web/config/main.php', + __DIR__ . '/../app_web/config/main-local.php', + __DIR__ . '/../app_web/config/main-pc.php', + ], + ]; +``` 启动命令 ------------- - * 启动 /path/to/php /path/to/yii swoole-backend/start - * 关闭 /path/to/php /path/to/yii swoole-backend/stop - * 重启 /path/to/php /path/to/yii swoole-backend/restart + * 启动web_pc应用 /path/to/php /path/to/yii swoole-backend/start web_pc + * 关闭web_pc应用 /path/to/php /path/to/yii swoole-backend/stop web_pc + * 重启web_pc应用 /path/to/php /path/to/yii swoole-backend/restart web_pc 使用systemd管理yii2-swoole的启动关闭 @@ -89,7 +106,7 @@ yii2 swoole 方法二 在/etc/rc.local中加入 - /path/to/php /path/to/yii2app/yii swoole-backend/start + /path/to/php /path/to/yii2app/yii swoole-backend/start web_pc Nginx配置 diff --git a/src/console/SwooleController.php b/src/console/SwooleController.php index 74c5d2b..afb9b83 100644 --- a/src/console/SwooleController.php +++ b/src/console/SwooleController.php @@ -27,7 +27,8 @@ class SwooleController extends \yii\console\Controller { - public $host = '0.0.0.0'; + + public $host = "0.0.0.0"; public $port = 9999; @@ -35,69 +36,79 @@ class SwooleController extends \yii\console\Controller public $socketType = SWOOLE_TCP; - /** yii2项目根目录 */ - public $rootDir = ''; + public $rootDir = ""; + + public $appSettingRoot = 'swoole'; - public $type = 'advanced'; + public $type = "advanced"; - public $app = 'frontend'; //如果type为basic,这里默认为空 + public $app = "frontend";//如果type为basic,这里默认为空 - public $web = 'web'; + public $web = "web"; - public $debug = true; //是否开启debug + public $debug = true;//是否开启debug - public $env = 'dev'; //环境,dev或者prod... + public $env = 'dev';//环境,dev或者prod... public $swooleConfig = []; - public $gcSessionInterval = 60000; //启动session回收的间隔时间,单位为毫秒 + public $customConfigFilenames = []; + + public $gcSessionInterval = 60000;//启动session回收的间隔时间,单位为毫秒 + + - public function actionStart() + public function actionStart(string $AppName) { - if ($this->getPid() !== false) { - $this->stderr('server already started'); + $this->assign($AppName); + if( $this->getPid() !== false ){ + $this->stderr("server already started"); exit(1); } $pidDir = dirname($this->swooleConfig['pid_file']); - if (!file_exists($pidDir)) { - FileHelper::createDirectory($pidDir); - } + if( !file_exists($pidDir) ) FileHelper::createDirectory($pidDir); $logDir = dirname($this->swooleConfig['log_file']); - if (!file_exists($logDir)) { - FileHelper::createDirectory($logDir); - } + if( !file_exists($logDir) ) FileHelper::createDirectory($logDir); - $rootDir = $this->rootDir; - $web = $rootDir . $this->app . DIRECTORY_SEPARATOR . $this->web; + $rootDir = $this->rootDir;//yii2项目根目录 + $web = $rootDir . $this->app . DIRECTORY_SEPARATOR . $this->web;; defined('YII_DEBUG') or define('YII_DEBUG', $this->debug); defined('YII_ENV') or define('YII_ENV', $this->env); - require $rootDir . '/vendor/autoload.php'; - if ($this->type == 'basic') { - $config = require $rootDir . '/config/web.php'; - } else { - require $rootDir . '/common/config/bootstrap.php'; - require $rootDir . $this->app . '/config/bootstrap.php'; - - $config = ArrayHelper::merge( - require($rootDir . '/common/config/main.php'), - require($rootDir . '/common/config/main-local.php'), - require($rootDir . $this->app . '/config/main.php'), - require($rootDir . $this->app . '/config/main-local.php') - ); + require($rootDir . '/vendor/autoload.php'); + //require($rootDir . '/vendor/yiisoft/yii2/Yii.php'); + if( $this->type == 'basic' ){ + $config = require($rootDir . '/config/web.php'); + }else { + require($rootDir . '/common/config/bootstrap.php'); + require($rootDir . $this->app . '/config/bootstrap.php'); + + if(!empty($this->customConfigFilenames)){ + foreach ($this->customConfigFilenames as $con){ + $configs[] = require($con); + } + }else{ + $configs = [ + require($rootDir . '/common/config/main.php'), + require($rootDir . '/common/config/main-local.php'), + require($rootDir . $this->app . '/config/main.php'), + require($rootDir . $this->app . '/config/main-local.php') + ]; + } + $config = ArrayHelper::merge(...$configs); } - + $this->swooleConfig = array_merge([ 'document_root' => $web, 'enable_static_handler' => true, ], $this->swooleConfig); - $server = new SwooleServer($this->host, $this->port, $this->mode, $this->socketType, $this->swooleConfig, ['gcSessionInterval' => $this->gcSessionInterval]); + $server = new SwooleServer($this->host, $this->port, $this->mode, $this->socketType, $this->swooleConfig, ['gcSessionInterval'=>$this->gcSessionInterval]); - /* + /** * @param \swoole_http_request $request * @param \swoole_http_response $response */ @@ -110,72 +121,63 @@ public function actionStart() $config['aliases'] = isset($config['aliases']) ? array_merge($aliases, $config['aliases']) : $aliases; $requestComponent = [ - 'class' => Request::class, + 'class' => Request::className(), 'swooleRequest' => $request, ]; $config['components']['request'] = isset($config['components']['request']) ? array_merge($config['components']['request'], $requestComponent) : $requestComponent; $responseComponent = [ - 'class' => Response::class, + 'class' => Response::className(), 'swooleResponse' => $response, ]; $config['components']['response'] = isset($config['components']['response']) ? array_merge($config['components']['response'], $responseComponent) : $responseComponent; - $config['components']['session'] = isset($config['components']['session']) ? array_merge(['savePath' => $web . '/../runtime/session'], $config['components']['session'], ['class' => Session::class]) : ['class' => Session::class, 'savePath' => $web . '/../session']; + $config['components']['session'] = isset($config['components']['session']) ? array_merge(['savePath'=>$web . '/../runtime/session'], $config['components']['session'], ["class" => Session::className()]) : ["class" => Session::className(), 'savePath'=>$web . '/../session']; - $config['components']['errorHandler'] = isset($config['components']['errorHandler']) ? array_merge($config['components']['errorHandler'], ['class' => ErrorHandler::class]) : ['class' => ErrorHandler::class]; + $config['components']['errorHandler'] = isset($config['components']['errorHandler']) ? array_merge($config['components']['errorHandler'], ["class" => ErrorHandler::className()]) : ["class" => ErrorHandler::className()]; - if (isset($config['components']['log'])) { - $config['components']['log'] = array_merge($config['components']['log'], ['class' => Dispatcher::class, 'logger' => Logger::class]); + if( isset($config['components']['log']) ){ + $config['components']['log'] = array_merge($config['components']['log'], ["class" => Dispatcher::className(), 'logger' => Logger::className()]); } - if (isset($config['modules']['debug'])) { + if( isset($config['modules']['debug']) ){ $config['modules']['debug'] = array_merge($config['modules']['debug'], [ - 'class' => Module::class, + "class" => Module::className(), 'panels' => [ - 'profiling' => ['class' => ProfilingPanel::class], - 'timeline' => ['class' => TimelinePanel::class], - ], + 'profiling' => ['class' => ProfilingPanel::className()], + 'timeline' => ['class' => TimelinePanel::className()], + ] ]); } try { $application = new Application($config); - // 这里将全局的logger替换成单个子app的logger 理论上其他的组件也需要做类似处理 - Yii::setLogger(Yii::$app->log->logger); - Yii::$app->log->yiiBeginAt = $yiiBeginAt; - Yii::$app->setAliases($aliases); + yii::$app->getLog()->yiiBeginAt = $yiiBeginAt; + yii::$app->setAliases($aliases); try { $application->state = Application::STATE_BEFORE_REQUEST; $application->trigger(Application::EVENT_BEFORE_REQUEST); $application->state = Application::STATE_HANDLING_REQUEST; - $tempResponse = $application->handleRequest($application->getRequest()); + $yiiresponse = $application->handleRequest($application->getRequest()); $application->state = Application::STATE_AFTER_REQUEST; $application->trigger(Application::EVENT_AFTER_REQUEST); $application->state = Application::STATE_SENDING_RESPONSE; - $tempResponse->send(); + $yiiresponse->send(); $application->state = Application::STATE_END; } catch (ExitException $e) { - $application->end($e->statusCode, isset($tempResponse) ? $tempResponse : null); + $application->end($e->statusCode, isset($yiiresponse) ? $yiiresponse : null); } - Yii::$app->getDb()->close(); + yii::$app->getDb()->close(); UploadedFile::reset(); - // 这里刷新当前work app的log - /* - Yii::$app->getLog()->getLogger()->flush(); - Yii::$app->getLog()->getLogger()->flush(true); - */ - - // 这里刷新master app的log 也就是console里的log 避免出现console常驻而看不到log的情况 - Yii::getLogger()->flush(); - Yii::getLogger()->flush(true); - } catch (\Exception $e) { - Yii::$app->getErrorHandler()->handleException($e); + yii::$app->getLog()->getLogger()->flush(); + yii::$app->getLog()->getLogger()->flush(true); + }catch (\Exception $e){ + yii::$app->getErrorHandler()->handleException($e); } }; @@ -183,52 +185,54 @@ public function actionStart() $server->run(); } - public function actionStop() + public function actionStop($AppName) { - $this->sendSignal(SIGTERM); + $this->sendSignal(SIGTERM, $AppName); $this->stdout("server is stopped, stop listening {$this->host}:{$this->port}" . PHP_EOL); } - public function actioReloadTask() + public function actioReloadTask($AppName) { - $this->sendSignal(SIGUSR2); + $this->sendSignal(SIGUSR2, $AppName); } - public function actionRestart() + public function actionRestart($AppName) { - $this->sendSignal(SIGTERM); + $this->sendSignal(SIGTERM, $AppName); $time = 0; while (posix_getpgid($this->getPid()) && $time <= 10) { usleep(100000); $time++; } if ($time > 100) { - $this->stderr('Server stopped timeout' . PHP_EOL); + $this->stderr("Server stopped timeout" . PHP_EOL); exit(1); } - if ($this->getPid() === false) { - $this->stdout('Server is stopped success' . PHP_EOL); - } else { - $this->stderr('Server stopped error, please handle kill process' . PHP_EOL); + if( $this->getPid() === false ){ + $this->stdout("Server is stopped success" . PHP_EOL); + }else{ + $this->stderr("Server stopped error, please handle kill process" . PHP_EOL); } - $this->actionStart(); + $this->actionStart($AppName); } - public function actionReload() + public function actionReload($AppName) { - $this->actionRestart(); + $this->actionRestart($AppName); } - private function sendSignal($sig) + private function sendSignal($sig,$AppName) { + $this->assign($AppName); if ($pid = $this->getPid()) { posix_kill($pid, $sig); } else { - $this->stdout('server is not running!' . PHP_EOL); + $this->stdout("server is not running!" . PHP_EOL); exit(1); } } + private function getPid() { $pid_file = $this->swooleConfig['pid_file']; @@ -242,4 +246,22 @@ private function getPid() } return false; } -} + + private function assign($AppName){ + if(!empty($AppName)){ + $configInfo = require($this->rootDir . '/' . $this->appSettingRoot . '/' . $AppName . '.php'); + if(empty($configInfo)){ + $this->stderr($this->rootDir . '/' . $this->appSettingRoot . '/' . $AppName . '.php content is null'); + exit(1); + } + foreach ($configInfo as $key=>$value){ + if(property_exists($this, $key)){ + $this->$key = $value; + } + } + }else{ + $this->stderr("input ApplocationName is Null"); + exit(1); + } + } +} \ No newline at end of file