diff --git a/README.md b/README.md index 1aff9e3..5c1921b 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ swoole 用 C 写的, 看不懂... 那现在有用 PHP 实现的 workerman 了, * swoole 任务投递的优化 * 增加单元测试 -* swoole 管理脚本的完善 +* 兼容swoole ## 使用方法 diff --git a/demo/index.php b/demo/index.php index 631d194..76a7de5 100644 --- a/demo/index.php +++ b/demo/index.php @@ -8,9 +8,7 @@ require_once __DIR__ . '/../vendor/autoload.php'; require_once __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; -/** @var HttpServer $server */ -$server = new HttpServer; -$server->run([ +Yii::$app->params['workermanHttp']['demo'] = [ 'host' => '127.0.0.1', 'port' => '6688', 'root' => __DIR__, @@ -28,4 +26,6 @@ 'server' => [ 'count' => 4, ], -]); +]; + +\tourze\workerman\yii2\server\Server::runApp('demo'); diff --git a/src/async/Task.php b/src/async/Task.php index 0bbcdf6..b619c23 100644 --- a/src/async/Task.php +++ b/src/async/Task.php @@ -58,7 +58,8 @@ public static function addTask($function, $params = []) * 执行任务 * * @param string $data - * @param int $taskId + * @param int $taskId + * @return mixed */ public static function runTask($data, $taskId) { @@ -66,6 +67,6 @@ public static function runTask($data, $taskId) $function = array_shift($data); //echo "$taskId Run task: $function\n"; $params = array_shift($data); - call_user_func_array($function, $params); + return call_user_func_array($function, $params); } } diff --git a/src/commands/ServerController.php b/src/commands/ServerController.php index 2061adb..9cc11e1 100644 --- a/src/commands/ServerController.php +++ b/src/commands/ServerController.php @@ -2,8 +2,7 @@ namespace tourze\workerman\yii2\commands; -use tourze\workerman\yii2\server\HttpServer; -use Yii; +use tourze\workerman\yii2\server\Server; use yii\console\Controller; class ServerController extends Controller @@ -22,11 +21,7 @@ public function actionHttp($app) unset($argv[0]); unset($argv[2]); $argv = array_values($argv); - //print_r($argv); - //return; - /** @var HttpServer $server */ - $server = new HttpServer; - $server->run($app); + Server::runApp($app); } } diff --git a/src/server/HttpServer.php b/src/server/HttpServer.php index e570da6..65b44c5 100644 --- a/src/server/HttpServer.php +++ b/src/server/HttpServer.php @@ -2,15 +2,11 @@ namespace tourze\workerman\yii2\server; -use tourze\workerman\yii2\Application; -use tourze\workerman\yii2\Container; -use tourze\workerman\yii2\log\Logger; use Workerman\Connection\ConnectionInterface; use Workerman\Protocols\Http; use Workerman\Worker; use Yii; use yii\base\ErrorException; -use yii\helpers\ArrayHelper; use yii\helpers\FileHelper; /** @@ -31,11 +27,6 @@ class HttpServer extends Server */ public $indexFile = 'index.php'; - /** - * @var bool 是否开启xhprof调试 - */ - public $xhprofDebug = false; - /** * @var bool */ @@ -59,23 +50,10 @@ class HttpServer extends Server /** * @inheritdoc */ - public function run($app) + public function run($config) { - $this->config = is_array($app) ? $app : (array) Yii::$app->params['workermanHttp'][$app]; - if (isset($this->config['xhprofDebug'])) - { - $this->xhprofDebug = $this->config['xhprofDebug']; - } - if (isset($this->config['debug'])) - { - $this->debug = $this->config['debug']; - } - $this->root = $this->config['root']; - - Worker::$logFile = $this->config['logFile']; - - $this->server = new Worker("http://{$this->config['host']}:{$this->config['port']}"); - foreach ($this->config['server'] as $k => $v) + $this->server = new Worker("http://{$this->host}:{$this->port}"); + foreach ($this->config as $k => $v) { $this->server->{$k} = $v; } @@ -122,46 +100,7 @@ public function onWorkerStart($worker) $_SERVER['DOCUMENT_ROOT'] = $this->root; $_SERVER['SCRIPT_NAME'] = $_SERVER['DOCUMENT_URI'] = '/' . $this->indexFile; - // 关闭Yii2自己实现的异常错误 - defined('YII_ENABLE_ERROR_HANDLER') || define('YII_ENABLE_ERROR_HANDLER', false); - // 每个worker都创建一个独立的app实例 - - // 加载文件和一些初始化配置 - if (isset($this->config['bootstrapFile'])) - { - foreach ($this->config['bootstrapFile'] as $file) - { - require $file; - } - } - $config = []; - foreach ($this->config['configFile'] as $file) - { - $config = ArrayHelper::merge($config, include $file); - } - - if (isset($this->config['bootstrapRefresh'])) - { - $config['bootstrapRefresh'] = $this->config['bootstrapRefresh']; - } - - // 为Yii分配一个新的DI容器 - if (isset($this->config['persistClasses'])) - { - Container::$persistClasses = ArrayHelper::merge(Container::$persistClasses, $this->config['persistClasses']); - Container::$persistClasses = array_unique(Container::$persistClasses); - } - Yii::$container = new Container(); - - if ( ! isset($config['components']['assetManager']['basePath'])) - { - $config['components']['assetManager']['basePath'] = $this->root . '/assets'; - } - $config['aliases']['@webroot'] = $this->root; - $config['aliases']['@web'] = '/'; - $this->app = Application::$workerApp = new Application($config); - Yii::setLogger(new Logger()); - $this->app->setRootPath($this->root); + $this->app = clone $this->app; $this->app->setServer($this->server); $this->app->prepare(); } @@ -198,7 +137,7 @@ public function onMessage($connection, $data) //xdebug_start_trace(); - if ($this->xhprofDebug) + if ($this->debug) { xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU); } @@ -285,7 +224,7 @@ public function onMessage($connection, $data) //xdebug_stop_trace(); //xdebug_print_function_stack(); - if ($this->xhprofDebug) + if ($this->debug) { $xhprofData = xhprof_disable(); $xhprofRuns = new \XHProfRuns_Default(); diff --git a/src/server/Server.php b/src/server/Server.php index 1693a44..1711066 100644 --- a/src/server/Server.php +++ b/src/server/Server.php @@ -4,15 +4,19 @@ use tourze\workerman\yii2\Application; use tourze\workerman\yii2\async\Task; +use tourze\workerman\yii2\Container; +use tourze\workerman\yii2\log\Logger; use Workerman\Worker; -use yii\base\Component; +use Yii; +use yii\base\Object; +use yii\helpers\ArrayHelper; /** * 基础的server实现 * * @package tourze\workerman\yii2\server */ -abstract class Server extends Component +abstract class Server extends Object { /** @@ -25,6 +29,16 @@ abstract class Server extends Component */ public $pidFile; + /** + * @var string 主机名 + */ + public $host; + + /** + * @var int 监听端口 + */ + public $port; + /** * @var Worker */ @@ -46,21 +60,129 @@ protected function setProcessTitle($name) } /** - * 运行服务器 + * 运行 * - * @param string $app + * @param array $config */ - abstract public function run($app); + abstract public function run($config); /** * 投递任务 * - * @param mixed $data - * @param int $dst_worker_id - * @return bool + * @param string $data + * @param int $dst_worker_id + * @return mixed */ public function task($data, $dst_worker_id = -1) { - Task::runTask($data, $dst_worker_id); + return Task::runTask($data, $dst_worker_id); + } + + /** + * 初始化APP + * + * @param array $config + */ + protected static function prepareApp($config) + { + // 关闭Yii2自己实现的异常错误 + defined('YII_ENABLE_ERROR_HANDLER') || define('YII_ENABLE_ERROR_HANDLER', false); + + // 为Yii分配一个新的DI容器 + if (isset($config['persistClasses'])) + { + Container::$persistClasses = ArrayHelper::merge(Container::$persistClasses, $config['persistClasses']); + Container::$persistClasses = array_unique(Container::$persistClasses); + } + Yii::$container = new Container; + + $yiiConfig = self::loadConfigFile((array) ArrayHelper::getValue($config, 'configFile')); + if (isset($config['bootstrapRefresh'])) + { + $yiiConfig['bootstrapRefresh'] = $config['bootstrapRefresh']; + } + + $root = ArrayHelper::getValue($config, 'root'); + if ( ! isset($yiiConfig['components']['assetManager']['basePath'])) + { + $yiiConfig['components']['assetManager']['basePath'] = $root . '/assets'; + } + $yiiConfig['aliases']['@webroot'] = $root; + $yiiConfig['aliases']['@web'] = '/'; + + Application::$workerApp = new Application($yiiConfig); + Yii::setLogger(new Logger()); + Application::$workerApp->setRootPath($root); + } + + /** + * 加载配置文件 + * + * @param array $configFile + * @return array + */ + public static function loadConfigFile($configFile) + { + $yiiConfig = []; + foreach ($configFile as $file) + { + $yiiConfig = ArrayHelper::merge($yiiConfig, include $file); + } + return $yiiConfig; + } + + /** + * 加载bootstrap文件 + * + * @param array $bootstrapFile + */ + public static function loadBootstrapFile($bootstrapFile) + { + foreach ($bootstrapFile as $file) + { + require $file; + } + } + + /** + * 执行指定的APP配置 + * + * @param string $app + */ + final public static function runApp($app) + { + // 加载配置信息 + $config = (array) Yii::$app->params['workermanHttp'][$app]; + + // 加载文件和一些初始化配置 + self::loadBootstrapFile((array) ArrayHelper::getValue($config, 'bootstrapFile')); + + // 准备APP信息 + self::prepareApp($config); + + // 日志文件 + Worker::$logFile = ArrayHelper::getValue($config, 'logFile'); + + // 是否开启调试 + $isDebug = ArrayHelper::getValue($config, 'debug', false); + + $root = ArrayHelper::getValue($config, 'root'); + $host = ArrayHelper::getValue($config, 'host'); + $port = ArrayHelper::getValue($config, 'port'); + + // 执行 HTTP SERVER + /** @var HttpServer $server */ + $server = new HttpServer([ + 'app' => Application::$workerApp, + 'host' => $host, + 'port' => $port, + 'debug' => $isDebug, + 'root' => $root, + ]); + $server->run(ArrayHelper::getValue($config, 'server', [])); + + // 执行 TASK SERVER + + Worker::runAll(); } }