httpEnable = $this->config->get('http_server.enable', true); $this->httpSocketName = $this->config['http_server']['socket']; $this->httpPort = $this->config['http_server']['port']; return $this; } /** * 启动服务 * * @return $this */ public function start() { if (!$this->httpEnable) { parent::start(); return $this; } if (static::mode == 'console') { $this->beforeSwooleStart(); $this->onWorkerStart(null, null); } else { //开启一个http服务器 $this->server = new \swoole_http_server($this->httpSocketName, $this->httpPort); $this->server->on('Start', [$this, 'onStart']); $this->server->on('WorkerStart', [$this, 'onWorkerStart']); $this->server->on('WorkerStop', [$this, 'onWorkerStop']); $this->server->on('Task', [$this, 'onTask']); $this->server->on('Finish', [$this, 'onFinish']); $this->server->on('PipeMessage', [$this, 'onPipeMessage']); $this->server->on('WorkerError', [$this, 'onWorkerError']); $this->server->on('ManagerStart', [$this, 'onManagerStart']); $this->server->on('ManagerStop', [$this, 'onManagerStop']); $this->server->on('request', [$this, 'onRequest']); $set = $this->setServerSet(); $set['daemonize'] = self::$daemonize ? 1 : 0; $this->server->set($set); $this->beforeSwooleStart(); $this->server->start(); } return $this; } /** * Swoole Worker进程启动回调 * * @param \swoole_server $serv server实例 * @param int $workerId worker id */ public function onWorkerStart($serv, $workerId) { parent::onWorkerStart($serv, $workerId); $this->setTemplateEngine(); } /** * 设置模板引擎 * * @return $this */ public function setTemplateEngine() { $this->templateEngine = new Engine(); return $this; } /** * HTTP请求回调 * * @param \swoole_http_request $request 请求对象 * @param \swoole_http_response $response 响应对象 */ public function onRequest($request, $response) { $error = ''; $code = 500; $controllerInstance = null; $this->route->handleHttpRequest($request); do { if ($this->route->getPath() == '') { $error = 'Index not found'; $code = 404; break; } $controllerName = $this->route->getControllerName(); $controllerClassName = $this->route->getControllerClassName(); if ($controllerClassName == '') { $error = 'Api not found controller(' . $controllerName . ')'; $code = 404; break; } $methodPrefix = $this->config->get('http.method_prefix', 'action'); $methodName = $methodPrefix . $this->route->getMethodName(); try { /** * @var \PG\MSF\Controllers\Controller $controllerInstance */ $controllerInstance = $this->objectPool->get($controllerClassName, [$controllerName, $methodName]); $controllerInstance->__useCount++; if (empty($controllerInstance->getObjectPool())) { $controllerInstance->setObjectPool(AOPFactory::getObjectPool(getInstance()->objectPool, $controllerInstance)); } if (!method_exists($controllerInstance, $methodName)) { $error = 'Api not found method(' . $methodName . ')'; $code = 404; break; } $controllerInstance->context = $controllerInstance->getObjectPool()->get(Context::class); // 初始化控制器 $controllerInstance->requestStartTime = microtime(true); $PGLog = null; $PGLog = clone getInstance()->log; $PGLog->accessRecord['beginTime'] = $controllerInstance->requestStartTime; $PGLog->accessRecord['uri'] = $this->route->getPath(); $PGLog->logId = $this->genLogId($request); defined('SYSTEM_NAME') && $PGLog->channel = SYSTEM_NAME; $PGLog->init(); $PGLog->pushLog('controller', $controllerName); $PGLog->pushLog('method', $methodName); $PGLog->pushLog('verb', $this->route->getVerb()); // 构造请求上下文成员 $controllerInstance->context->setLogId($PGLog->logId); $controllerInstance->context->setLog($PGLog); $controllerInstance->context->setObjectPool($controllerInstance->getObjectPool()); /** * @var $input Input */ $input = $controllerInstance->context->getObjectPool()->get(Input::class); $input->set($request); /** * @var $output Output */ $output = $controllerInstance->context->getObjectPool()->get(Output::class, [$controllerInstance]); $output->set($request, $response); $controllerInstance->context->setInput($input); $controllerInstance->context->setOutput($output); $controllerInstance->context->setControllerName($controllerName); $controllerInstance->context->setActionName($methodName); $controllerInstance->setRequestType(Marco::HTTP_REQUEST); $init = $controllerInstance->__construct($controllerName, $methodName); if ($init instanceof \Generator) { $this->scheduler->start( $init, $controllerInstance->context, $controllerInstance, function () use ($controllerInstance, $methodName) { $generator = $controllerInstance->$methodName(...array_values($this->route->getParams())); if ($generator instanceof \Generator) { $this->scheduler->taskMap[$controllerInstance->context->getLogId()]->resetRoutine($generator); $this->scheduler->schedule($this->scheduler->taskMap[$controllerInstance->context->getLogId()]); } } ); } else { $generator = $controllerInstance->$methodName(...array_values($this->route->getParams())); if ($generator instanceof \Generator) { $this->scheduler->start($generator, $controllerInstance->context, $controllerInstance); } } if ($this->route->getEnableCache() && !$this->route->getRouteCache($this->route->getPath())) { $this->route->setRouteCache( $this->route->getPath(), [$controllerName, $this->route->getMethodName(), $controllerClassName] ); } break; } catch (\Throwable $e) { $controllerInstance->onExceptionHandle($e); } } while (0); if ($error !== '') { if ($controllerInstance != null) { $controllerInstance->destroy(); } $response->status($code); $response->end($error); } } /** * 产生日志ID * * @param \swoole_http_request $request 请求对象 * @return string */ public function genLogId($request) { static $i = 0; $i || $i = mt_rand(1, 0x7FFFFF); $logId = $request->header['log_id'] ?? '' ; if (!$logId) { $logId = sprintf("%08x%06x%04x%06x", time() & 0xFFFFFFFF, crc32(substr((string)gethostname(), 0, 256)) >> 8 & 0xFFFFFF, getmypid() & 0xFFFF, $i = $i > 0xFFFFFE ? 1 : $i + 1 ); } return $logId; } }