   'phpDocumentor\Descriptor\FileDescriptor * hash f99d35b16a2d5e9ea8fc49e5cc70573a * path
Server.php	 * sourceS<?php
/**
 * SwooleServer
 *
 * @author camera360_server@camera360.com
 * @copyright Chengdu pinguo Technology Co.,Ltd.
 */

namespace PG\MSF;

use Exception;
use Noodlehaus\Config;
use PG\Log\PGLog;
use PG\MSF\Base\Child;
use PG\MSF\Base\Core;
use PG\MSF\Pack\IPack;
use PG\MSF\Route\IRoute;
use PG\MSF\Helpers\Context;
use PG\MSF\Coroutine\Scheduler;
use PG\MSF\Base\AOPFactory;
use PG\MSF\Base\Pool;
use PG\MSF\Route\NormalRoute;

/**
 * Class Server
 * @package PG\MSF
 */
abstract class Server extends Child
{
    /**
     * 版本
     */
    const version = "3.0.0";

    /**
     * 运行方式（web/console）
     */
    const mode = 'web';

    /**
     * @var int 进程类型，worker,tasker,user
     */
    public $processType = Marco::PROCESS_USER;

    /**
     * @var Server 实例
     */
    protected static $instance;

    /**
     * @var bool Daemonize.
     */
    public static $daemonize = false;

    /**
     * @var string pid文件
     */
    public static $pidFile = '';

    /**
     * @var int Master进程ID
     */
    protected static $_masterPid = 0;

    /**
     * @var mixed 日志文件
     */
    protected static $logFile = '';

    /**
     * @var string Start file.
     */
    protected static $_startFile = '';

    /**
     * @var Server worker instance.
     */
    protected static $_worker = null;

    /**
     * @var Scheduler 协程调度器
     */
    public $scheduler;

    /**
     * @var string server name
     */
    public $name = '';

    /**
     * @var string server user
     */
    public $user = '';

    /**
     * @var int Worker数量
     */
    public $workerNum = 0;

    /**
     * @var int Tasker数量
     */
    public $taskNum = 0;

    /**
     * @var int 服务器到现在的毫秒数
     */
    public $tickTime;

    /**
     * @var IRoute|NormalRoute 路由器
     */
    protected $route;

    /**
     * @var IPack 数据打包与解包
     */
    public $pack;

    /**
     * @var callback 错误回调
     */
    public $onErrorHandle = null;

    /**
     * @var \swoole_server Server运行实例
     */
    public $server;

    /**
     * @var Config 配置对象
     */
    public $config;

    /**
     * @var PGLog 日志对象
     */
    public $log;

    /**
     * @var \stdClass|null 对象模板
     */
    protected static $stdClass = null;

    /**
     * @var \Yac 系统共享对象操作句柄
     */
    public $sysCache;

    /**
     * 系统注册的定时器列表
     *
     * @var array
     */
    public $sysTimers;

    /**
     * @var string 框架目录
     */
    public $MSFSrcDir;

    /**
     * @var Pool 对象池
     */
    public $objectPool;

    /**
     * Server constructor.
     *
     * @throws Exception
     */
    public function __construct()
    {
        $this->MSFSrcDir = __DIR__;
        $this->onErrorHandle = [$this, 'onErrorHandle'];
        self::$_worker = $this;
        // 加载配置 支持加载环境子目录配置
        $this->config = new Config(defined('CONFIG_DIR') ? CONFIG_DIR : [
            ROOT_PATH . '/config',
            ROOT_PATH . '/config/' . APPLICATION_ENV
        ]);
        $this->setConfig();

        // 日志初始化
        $this->log = new PGLog($this->name, $this->config->get('server.log', ['handlers' => []]));

        register_shutdown_function(array($this, 'checkErrors'));
        set_error_handler(array($this, 'displayErrorHandler'));

        // 初始化路由器
        $routeTool = $this->config->get('server.route_tool', 'NormalRoute');
        if (class_exists($routeTool)) {
            $routeClassName = $routeTool;
        } else {
            $routeClassName = "\\App\\Route\\" . $routeTool;
            if (!class_exists($routeClassName)) {
                $routeClassName = "\\PG\\MSF\\Route\\" . $routeTool;
                if (!class_exists($routeClassName)) {
                    throw new Exception("class {$routeTool} is not exist.");
                }
            }
        }
        $this->route  = new $routeClassName;

        // 初始化打包和解包对象
        $packTool = $this->config->get('server.pack_tool', 'JsonPack');
        if (class_exists($packTool)) {
            $packClassName = $packTool;
        } else {
            $packClassName = "\\App\\Pack\\" . $packTool;
            if (!class_exists($packClassName)) {
                $packClassName = "\\PG\\MSF\\Pack\\" . $packTool;
                if (!class_exists($packClassName)) {
                    throw new Exception("class {$packTool} is not exist.");
                }
            }
        }
        $this->pack = new $packClassName;
    }

    /**
     * 创建用户自定义定时进程的上下文对象
     *
     * @return NULL|Context
     */
    public function getTimerContext()
    {
        $context = new Context();
        $PGLog   = null;
        $PGLog   = clone getInstance()->log;
        $PGLog->accessRecord['beginTime'] = time();
        $PGLog->accessRecord['uri']       = '/timerTick';
        $PGLog->logId = $this->genLogId(null);
        defined('SYSTEM_NAME') && $PGLog->channel = SYSTEM_NAME;
        $PGLog->init();
        $PGLog->pushLog('controller', 'timerTick');
        $PGLog->pushLog('method', 'timerTick');

        // 构造请求上下文成员
        $context->setLogId($PGLog->logId);
        $context->setLog($PGLog);
        $context->setObjectPool(AOPFactory::getObjectPool(getInstance()->objectPool, $this));
        $context->setControllerName('timerTick');
        $context->setActionName('timerTick');
        $this->setContext($context);

        return $this->getContext();
    }
    /**
     * 获取运行的Server实例
     *
     * @return Server|MSFServer
     */
    public static function &getInstance()
    {
        return self::$instance;
    }

    /**
     * 配置初始化
     *
     * @return mixed
     */
    public function setConfig()
    {
        $this->user = $this->config->get('server.set.user', '');

        //设置异步IO模式
        swoole_async_set($this->config->get('server.async_io', [
            'thread_num'         => $this->config->get('server.set.worker_num', 4),
            'aio_mode'           => SWOOLE_AIO_BASE,
            'use_async_resolver' => true,
            'dns_lookup_random'  => true,
        ]));
    }

    /**
     * 运行所有的服务进程
     *
     * @return void
     */
    public static function run()
    {
        static::init();
        static::parseCommand();
        static::initWorkers();
        static::displayUI();
        static::startSwooles();
    }

    /**
     * 服务初始化
     *
     * @return void
     */
    protected static function init()
    {
        $backtrace        = debug_backtrace();
        self::$_startFile = $backtrace[count($backtrace) - 1]['file'];

        if (empty(self::$pidFile)) {
            self::$pidFile = self::$_worker->config->get('server.pid_path') . str_replace('/', '_', self::$_startFile) . ".pid";
            if (!is_dir(self::$_worker->config->get('server.pid_path'))) {
                mkdir(self::$_worker->config->get('server.pid_path'), 0777, true);
            }
        }

        self::setProcessTitle(self::$_worker->config->get('server.process_title'));
        self::$stdClass = new \stdClass();
        Core::$stdClass = self::$stdClass;
    }

    /**
     * 设置服务进程名称
     *
     * @param string $title
     * @return void
     */
    public static function setProcessTitle($title)
    {
        if (function_exists('cli_set_process_title') && PHP_OS == 'Darwin') {
            @cli_set_process_title($title);
        } else {
            @swoole_set_process_name($title);
        }
    }

    /**
     * 解析命令行参数
     *
     * @return void
     */
    protected static function parseCommand()
    {
        global $argv;
        // Check argv;
        $startFile = $argv[0];
        if (!isset($argv[1])) {
            $argv[1] = 'start';
        }

        // Get command.
        $command = trim($argv[1]);
        $command2 = isset($argv[2]) ? $argv[2] : '';

        // Start command.
        $mode = '';
        if (file_exists(self::$pidFile)) {
            $pids = explode(',', file_get_contents(self::$pidFile));
            // Get master process PID.
            $masterPid = $pids[0];
            $managerPid = $pids[1];
            $masterIsAlive = $masterPid && @posix_kill($masterPid, SIG_BLOCK);
        } else {
            $masterIsAlive = false;
        }
        // Master is still alive?
        if ($masterIsAlive) {
            if ($command === 'start' || $command === 'test') {
                writeln("{$startFile} already running");
                exit;
            }
        } elseif ($command !== 'start' && $command !== 'test') {
            writeln("{$startFile} not run");
            exit;
        }

        // execute command.
        switch ($command) {
            case 'start':
                if ($command2 === '-d') {
                    self::$daemonize = true;
                }
                break;
            case 'stop':
                @unlink(self::$pidFile);
                writeln("$startFile is stoping ...");
                // Send stop signal to master process.
                $masterPid && posix_kill($masterPid, SIGTERM);
                // Timeout.
                $timeout = 5;
                $startTime = time();
                // Check master process is still alive?
                while (1) {
                    $masterIsAlive = $masterPid && posix_kill($masterPid, SIG_BLOCK);
                    if ($masterIsAlive) {
                        // Timeout?
                        if (time() - $startTime >= $timeout) {
                            writeln("{$startFile} stop fail");
                            exit;
                        }
                        // Waiting amoment.
                        usleep(10000);
                        continue;
                    }
                    // Stop success.
                    writeln("{$startFile} stop success");
                    break;
                }
                exit(0);
                break;
            case 'reload':
                posix_kill($managerPid, SIGUSR1);
                writeln("{$startFile} reload");
                exit;
            case 'restart':
                @unlink(self::$pidFile);
                writeln("{$startFile} is stoping ...");
                // Send stop signal to master process.
                $masterPid && posix_kill($masterPid, SIGTERM);
                // Timeout.
                $timeout = 5;
                $startTime = time();
                // Check master process is still alive?
                while (1) {
                    $masterIsAlive = $masterPid && posix_kill($masterPid, SIG_BLOCK);
                    if ($masterIsAlive) {
                        // Timeout?
                        if (time() - $startTime >= $timeout) {
                            writeln("{$startFile} stop fail");
                            exit;
                        }
                        // Waiting amoment.
                        usleep(10000);
                        continue;
                    }
                    // Stop success.
                    writeln("{$startFile} stop success");
                    break;
                }
                self::$daemonize = true;
                break;
            case 'test':
                self::$testUnity = true;
                self::$testUnityDir = $command2;
                break;
            default:
        }
    }

    /**
     * 初始化worker进程
     *
     * @return void
     */
    protected static function initWorkers()
    {
        // Worker name.
        if (empty(self::$_worker->name)) {
            self::$_worker->name = 'none';
        }
        // Get unix user of the worker process.
        if (empty(self::$_worker->user)) {
            self::$_worker->user = self::getCurrentUser();
        } else {
            if (posix_getuid() !== 0 && self::$_worker->user != self::getCurrentUser()) {
                writeln('You must have the root privileges to change uid and gid.');
            }
        }
    }

    /**
     * 获取当前进程用户
     *
     * @return string
     */
    protected static function getCurrentUser()
    {
        $userInfo = posix_getpwuid(posix_getuid());
        return $userInfo['name'];
    }

    /**
     * 显示命令行控制台信息
     *
     * @return void
     */
    protected static function displayUI()
    {
        $setConfig = self::$_worker->setServerSet();
        $ascii     = file_get_contents(__DIR__ . '/../ascii.ui');
        echo $ascii, "\n";
        writeln('MSF     Version: ' . self::version);
        writeln('Swoole  Version: ' . SWOOLE_VERSION);
        writeln('PHP     Version: ' . PHP_VERSION);
        writeln('Application ENV: ' . APPLICATION_ENV);
        writeln('Worker   Number: ' . $setConfig['worker_num']);
        writeln('Task     Number: ' . $setConfig['task_worker_num'] ?? 0);
        writeln("Listen     Addr: " . self::$_worker->config->get('http_server.socket'));
        writeln("Listen     Port: " . self::$_worker->config->get('http_server.port'));
    }

    /**
     * 设置服务器配置参数
     *
     * @return mixed
     */
    abstract public function setServerSet();

    /**
     * Fork some worker processes.
     *
     * @return void
     */
    protected static function startSwooles()
    {
        self::$_worker->start();
    }

    /**
     * start前的操作
     */
    public function beforeSwooleStart()
    {
        //初始化对象池
        $this->objectPool = Pool::getInstance();
    }

    /**
     * Server启动在主进程的主线程回调此函数
     *
     * @param $serv
     */
    public function onStart($serv)
    {
        self::$_masterPid = $serv->master_pid;
        file_put_contents(self::$pidFile, self::$_masterPid);
        file_put_contents(self::$pidFile, ',' . $serv->manager_pid, FILE_APPEND);
        self::setProcessTitle($this->config['server.process_title'] . '-Master');
    }

    /**
     * worker进程/task进程启动回调
     *
     * @param \swoole_server $serv server实例
     * @param int $workerId worker id
     */
    public function onWorkerStart($serv, $workerId)
    {
        if (function_exists('apc_clear_cache')) {
            apc_clear_cache();
        }

        if (function_exists('opcache_reset')) {
            opcache_reset();
        }

        file_put_contents(self::$pidFile, ',' . $serv->worker_pid, FILE_APPEND);
        if (!$serv->taskworker) {//worker进程
            $this->scheduler = new Scheduler();
            self::setProcessTitle($this->config['server.process_title'] . '-Worker');
        } else {
            self::setProcessTitle($this->config['server.process_title'] . '-Tasker');
        }
    }

    /**
     * TCP客户端连接关闭后，在worker进程中回调此函数
     *
     * @param $serv
     * @param $fd
     */
    public function onClose($serv, $fd)
    {
    }

    /**
     * 此事件在worker进程终止时发生
     *
     * @param $serv
     * @param $fd
     */
    public function onWorkerStop($serv, $fd)
    {
    }

    /**
     * 在task_worker进程内被调用
     *
     * @param $serv
     * @param $taskId
     * @param $fromId
     * @param $data
     * @return mixed
     */
    public function onTask($serv, $taskId, $fromId, $data)
    {
    }

    /**
     * 当worker进程投递的任务在task_worker中完成时调用
     *
     * @param $serv
     * @param $taskId
     * @param $data
     */
    public function onFinish($serv, $taskId, $data)
    {
    }

    /**
     * 当工作进程收到由sendMessage发送的管道消息时会触发onPipeMessage事件
     *
     * @param $serv
     * @param $fromWorkerId
     * @param $message
     */
    public function onPipeMessage($serv, $fromWorkerId, $message)
    {
    }

    /**
     * 当worker/task_worker进程发生异常后会在Manager进程内回调此函数。
     *
     * @param \swoole_server $serv server实例
     * @param int $workerId worker id
     * @param int $workerPid worker pid
     * @param int $exitCode 退出状态码
     */
    public function onWorkerError($serv, $workerId, $workerPid, $exitCode)
    {
        $data = [
            'worker_id'  => $workerId,
            'worker_pid' => $workerPid,
            'exit_code'  => $exitCode,
            'message'    => error_get_last(),
        ];
        $log = "WORKER Error ";
        $log .= json_encode($data);
        $this->log->error($log);
        if ($this->onErrorHandle != null) {
            $this->onErrorHandle('服务器进程异常退出', $log);
        }
    }

    /**
     * 当管理进程启动时调用
     *
     * @param $serv
     */
    public function onManagerStart($serv)
    {
        self::setProcessTitle($this->config['server.process_title'] . '-Manager');
    }

    /**
     * 当管理进程结束时调
     *
     * @param $serv
     */
    public function onManagerStop($serv)
    {
    }

    /**
     * __call魔术方法
     *
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        return $this->server->$name(...$arguments);
    }

    /**
     * 定时器包装（用于业务Timer进程）
     *
     * @param int $ms 定时器间隔毫秒
     * @param callable $callBack 定时器执行的回调
     * @param array $params 定时器其他参数
     */
    public function registerTimer($ms, callable $callBack, $params = [])
    {
        swoole_timer_tick($ms, function ($timerId, $params) use ($callBack) {
            $this->getTimerContext();
            $callBack($timerId, $params);
            $this->getContext()->getLog()->appendNoticeLog();
        }, $params);
    }

    /**
     * 全局错误监听
     *
     * @param int $error 错误码
     * @param string $errorString 错误描述
     * @param string $filename 文件名
     * @param int $line 文件行
     * @param array $symbols 符号表
     */
    public function displayErrorHandler($error, $errorString, $filename, $line, $symbols)
    {
        // 如果表达式前面有@时忽略错误
        if (0 == error_reporting()) {
            return;
        }

        $log = "WORKER Error ";
        $log .= "$errorString ($filename:$line)";
        $this->log->error($log);
        if ($this->onErrorHandle != null) {
            $this->onErrorHandle('服务器发生严重错误', $log);
        }
    }

    /**
     * 致命错误回调
     *
     * @return void
     */
    public function checkErrors()
    {
        if ($this->processType == Marco::PROCESS_WORKER) {
            // exit统计
            $key = Marco::SERVER_STATS . getInstance()->server->worker_id . '_exit';
            $exitStat = $this->sysCache->get($key);
            if (!$exitStat) {
                $exitStat = 1;
            } else {
                $exitStat++;
            }
            $this->sysCache->set($key, $exitStat);
        }

        // 错误信息
        $logMsg  = "WORKER EXIT UNEXPECTED ";
        $error   = error_get_last();

        if (isset($error['type'])) {
            switch ($error['type']) {
                case E_ERROR:
                case E_PARSE:
                case E_CORE_ERROR:
                case E_COMPILE_ERROR:
                    $message = $error['message'];
                    $file = $error['file'];
                    $line = $error['line'];
                    $logMsg .= "$message ($file:$line)\nStack trace:\n";
                    $trace = debug_backtrace();
                    foreach ($trace as $i => $t) {
                        if (!isset($t['file'])) {
                            $t['file'] = 'unknown';
                        }
                        if (!isset($t['line'])) {
                            $t['line'] = 0;
                        }
                        if (!isset($t['function'])) {
                            $t['function'] = 'unknown';
                        }
                        $logMsg .= "#$i {$t['file']}({$t['line']}): ";
                        if (isset($t['object']) and is_object($t['object'])) {
                            $logMsg .= get_class($t['object']) . '->';
                        }
                        $logMsg .= "{$t['function']}()\n";
                    }
                    if (isset($_SERVER['REQUEST_URI'])) {
                        $logMsg .= '[QUERY] ' . $_SERVER['REQUEST_URI'];
                    }
                    $this->log->alert($logMsg);
                    if ($this->onErrorHandle != null) {
                        $this->onErrorHandle('服务器发生崩溃', $logMsg);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 是否是task进程
     * @return bool
     */
    public function isTaskWorker()
    {
        return !empty($this->server) && $this->server->taskworker;
    }

    /**
     * 服务器主动关闭链接
     *
     * @param int $fd
     */
    public function close($fd)
    {
        $this->server->close($fd);
    }

    /**
     * 错误处理函数
     * @param $msg
     * @param $log
     */
    public function onErrorHandle($msg, $log)
    {
        writeln($msg . ' ' . $log);
    }
}
 * namespaceAliases#phpDocumentor\Descriptor\Collection * items	Exception
\ExceptionConfig\Noodlehaus\ConfigPGLog\PG\Log\PGLogChild\PG\MSF\Base\ChildCore\PG\MSF\Base\CoreIPack\PG\MSF\Pack\IPackIRoute\PG\MSF\Route\IRouteContext\PG\MSF\Helpers\Context	Scheduler\PG\MSF\Coroutine\Scheduler
AOPFactory\PG\MSF\Base\AOPFactoryPool\PG\MSF\Base\PoolNormalRoute\PG\MSF\Route\NormalRoute * includes	  * constants	  * functions	 
 * classes	\PG\MSF\Server(phpDocumentor\Descriptor\ClassDescriptor	 * parent * implements	  * abstract * final#	version+phpDocumentor\Descriptor\ConstantDescriptor(" * types  * value"3.0.0" * fqsen\PG\MSF\Server::version * name, * namespace\PG\MSF
 * package
 * summary版本 * description * fileDescriptor  * line! * tags	 	 * errors	  * inheritedElement mode-(". /'web'1\PG\MSF\Server::mode3?4567运行方式（web/console）9: ;&<	 =	 >  * properties	processType+phpDocumentor\Descriptor\PropertyDescriptor(". 
 * default\PG\MSF\Marco::PROCESS_USER	 * static * visibilitypublic1\PG\MSF\Server::processType3D4 679: ;+<	var	 *phpDocumentor\Descriptor\Tag\VarDescriptor * variableName.	 /phpDocumentor\Descriptor\Type\IntegerDescriptor 3L9!进程类型，worker,tasker,user=	 =	 > instanceE(". F HI	protected1\PG\MSF\Server::instance3Q4 679: ;0<	L	 MN.	 3phpDocumentor\Descriptor\Type\UnknownTypeDescriptor3&3L9实例=	 =	 > 	daemonizeE(". FfalseHIJ1\PG\MSF\Server::daemonize3V4 679: ;5<	L	 MN.	 /phpDocumentor\Descriptor\Type\BooleanDescriptor 3L9
Daemonize.=	 =	 > pidFileE(". F''HIJ1\PG\MSF\Server::pidFile3[4 679: ;:<	L	 MN.	 .phpDocumentor\Descriptor\Type\StringDescriptor 3L9	pid文件=	 =	 > 
_masterPidE(". F0HIR1\PG\MSF\Server::_masterPid3`4 679: ;?<	L	 MN.	 O 3L9Master进程ID=	 =	 > logFileE(". F\HIR1\PG\MSF\Server::logFile3d4 679: ;D<	L	 MN.	 T3mixed3L9日志文件=	 =	 > 
_startFileE(". F\HIR1\PG\MSF\Server::_startFile3h4 679: ;I<	L	 MN.	 ^ 3L9Start file.=	 =	 > _workerE(". FnullHIR1\PG\MSF\Server::_worker3k4 679: ;N<	L	 MN.	 T3&3L9worker instance.=	 =	 > 	schedulerE(". F HIJ1\PG\MSF\Server::scheduler3o4 679: ;S<	L	 MN.	 T33L9协程调度器=	 =	 > nameE(". F\HIJ1\PG\MSF\Server::name3r4 679: ;X<	L	 MN.	 ^ 3L9server name=	 =	 > userE(". F\HIJ1\PG\MSF\Server::user3u4 679: ;]<	L	 MN.	 ^ 3L9server user=	 =	 > 	workerNumE(". FaHIJ1\PG\MSF\Server::workerNum3x4 679: ;b<	L	 MN.	 O 3L9Worker数量=	 =	 > taskNumE(". FaHIJ1\PG\MSF\Server::taskNum3{4 679: ;g<	L	 MN.	 O 3L9Tasker数量=	 =	 > tickTimeE(". F HIJ1\PG\MSF\Server::tickTime3~4 679: ;l<	L	 MN.	 O 3L9服务器到现在的毫秒数=	 =	 > routeE(". F HIR1\PG\MSF\Server::route34 679: ;q<	L	 MN.	 T3T3!3L9	路由器=	 =	 > packE(". F HIJ1\PG\MSF\Server::pack34 679: ;v<	L	 MN.	 T33L9数据打包与解包=	 =	 > onErrorHandleE(". FlHIJ1\PG\MSF\Server::onErrorHandle34 679: ;{<	L	 MN.	 T3callback3L9错误回调=	 =	 > serverE(". F HIJ1\PG\MSF\Server::server34 679: ;<	L	 MN.	 T3\swoole_server3L9Server运行实例=	 =	 > configE(". F HIJ1\PG\MSF\Server::config34 679: ;<	L	 MN.	 T33L9配置对象=	 =	 > logE(". F HIJ1\PG\MSF\Server::log34 679: ;<	L	 MN.	 T33L9日志对象=	 =	 > stdClassE(". FlHIR1\PG\MSF\Server::stdClass34 679: ;<	L	 MN.	 T3	\stdClassT3l3L9对象模板=	 =	 > sysCacheE(". F HIJ1\PG\MSF\Server::sysCache34 679: ;<	L	 MN.	 T3\Yac3L9系统共享对象操作句柄=	 =	 > 	sysTimersE(". F HIJ1\PG\MSF\Server::sysTimers34 67系统注册的定时器列表9: ;<	L	 MN.	 T3array3L9=	 =	 > 	MSFSrcDirE(". F HIJ1\PG\MSF\Server::MSFSrcDir34 679: ;<	L	 MN.	 ^ 3L9框架目录=	 =	 > 
objectPoolE(". F HIJ1\PG\MSF\Server::objectPool34 679: ;<	L	 MN.	 T33L9	对象池=	 =	 > 
 * methods	__construct)phpDocumentor\Descriptor\MethodDescriptor("*+HIJ * arguments	 1\PG\MSF\Server::__construct()34 67Server constructor.9: ;<	throws	 -phpDocumentor\Descriptor\Tag\ThrowsDescriptor.	 T339=	 return	 param	 =	 > getTimerContext("*+HIJ	 1!\PG\MSF\Server::getTimerContext()34 673创建用户自定义定时进程的上下文对象9: ;<		 -phpDocumentor\Descriptor\Tag\ReturnDescriptor.	 T3NULLT339=	 	 =	 > getInstance("*+HIJ	 1\PG\MSF\Server::getInstance()34 67获取运行的Server实例9: ;<		 .	 T3&T3\PG\MSF\MSFServer39=	 	 =	 > 	setConfig("*+HIJ	 1\PG\MSF\Server::setConfig()34 67配置初始化9: ;<		 .	 T3f39=	 	 =	 > run("*+HIJ	 1\PG\MSF\Server::run()34 67运行所有的服务进程9: ;<		 .	 T3void39=	 	 =	 > init("*+HIR	 1\PG\MSF\Server::init()34 67服务初始化9: ;(<		 .	 T339=	 	 =	 > setProcessTitle("*+HIJ	$title+phpDocumentor\Descriptor\ArgumentDescriptor	 * method#.	 ^ F  * byReference * isVariadic134 679: ; <	 =	 > 1!\PG\MSF\Server::setProcessTitle()34 67设置服务进程名称9: ;?<		 ,phpDocumentor\Descriptor\Tag\ParamDescriptorN.#39=	 	 .	 T339=	 =	 > parseCommand("*+HIR	 1\PG\MSF\Server::parseCommand()34 67解析命令行参数9: ;M<		 .	 T339=	 	 =	 > initWorkers("*+HIR	 1\PG\MSF\Server::initWorkers()34 67初始化worker进程9: ;<		 .	 T339=	 	 =	 > getCurrentUser("*+HIR	 1 \PG\MSF\Server::getCurrentUser()34 67获取当前进程用户9: ;<		 .	 ^ 39=	 	 =	 > 	displayUI("*+HIR	 1\PG\MSF\Server::displayUI()34 67显示命令行控制台信息9: ;<		 .	 T339=	 	 =	 > setServerSet("*+HIJ	 1\PG\MSF\Server::setServerSet()34 67设置服务器配置参数9: ;<		 .	 T3f39=	 	 =	 > startSwooles("*+HIR	 1\PG\MSF\Server::startSwooles()34 67Fork some worker processes.9: ;<		 .	 T339=	 	 =	 > beforeSwooleStart("*+HIJ	 1#\PG\MSF\Server::beforeSwooleStart()34 67start前的操作9: ;<		 	 =	 > onStart("*+HIJ	$serv#\.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onStart()34 673Server启动在主进程的主线程回调此函数9: ;<		 N.#`39=	 	 =	 > onWorkerStart("*+HIJ	#q.	 T3F 134 679server实例: ; <	 =	 > 	$workerId#q.	 O F 134 679	worker id: ; <	 =	 > 1\PG\MSF\Server::onWorkerStart()34 67#worker进程/task进程启动回调9: ;<		 N.#u39=	 N.#}39=	 	 =	 > onClose("*+HIJ	#.	 F 134 679: ; <	 =	 > $fd#.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onClose()34 67?TCP客户端连接关闭后，在worker进程中回调此函数9: ;3<		 N.#39=	 N.#39=	 	 =	 > onWorkerStop("*+HIJ	#.	 F 134 679: ; <	 =	 > #.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onWorkerStop()34 67'此事件在worker进程终止时发生9: ;=<		 N.#39=	 N.#39=	 	 =	 > onTask("*+HIJ	#.	 F 134 679: ; <	 =	 > $taskId#.	 F 134 679: ; <	 =	 > $fromId#.	 F 134 679: ; <	 =	 > $data#.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onTask()34 67 在task_worker进程内被调用9: ;J<		 N.#39=	 N.#39=	 N.#39=	 N.#39=	 	 .	 T3f39=	 =	 > onFinish("*+HIJ	#	.	 F 134 679: ; <	 =	 > #	.	 F 134 679: ; <	 =	 > #	.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onFinish()34 67>当worker进程投递的任务在task_worker中完成时调用9: ;U<		 N.#39=	 N.#39=	 N.#39=	 	 =	 > onPipeMessage("*+HIJ	#2.	 F 134 679: ; <	 =	 > $fromWorkerId#2.	 F 134 679: ; <	 =	 > $message#2.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onPipeMessage()34 67W当工作进程收到由sendMessage发送的管道消息时会触发onPipeMessage事件9: ;`<		 N.#639=	 N.#=39=	 N.#D39=	 	 =	 > onWorkerError("*+HIJ	#[.	 T3F 134 679: ; <	 =	 > #[.	 O F 134 679: ; <	 =	 > 
$workerPid#[.	 O F 134 679
worker pid: ; <	 =	 > 	$exitCode#[.	 O F 134 679退出状态码: ; <	 =	 > 1\PG\MSF\Server::onWorkerError()34 67R当worker/task_worker进程发生异常后会在Manager进程内回调此函数。9: ;l<		 N.#_39=	 N.#g39=	 N.#o39=	 N.#w39=	 	 =	 > onManagerStart("*+HIJ	#.	 F 134 679: ; <	 =	 > 1 \PG\MSF\Server::onManagerStart()34 67当管理进程启动时调用9: ;<		 N.#39=	 	 =	 > onManagerStop("*+HIJ	#.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::onManagerStop()34 67当管理进程结束时调9: ;<		 N.#39=	 	 =	 > __call("*+HIJ	$name#.	 F 134 679: ; <	 =	 > 
$arguments#.	 F 134 679: ; <	 =	 > 1\PG\MSF\Server::__call()34 67__call魔术方法9: ;<		 N.#39=	 N.#39=	 	 .	 T3f39=	 =	 > registerTimer("*+HIJ	$ms#.	 O F 134 679定时器间隔毫秒: ; <	 =	 > 	$callBack#.	 T3callableF 134 679定时器执行的回调: ; <	 =	 > $params#.	 T3Farray()134 679定时器其他参数: ; <	 =	 > 1\PG\MSF\Server::registerTimer()34 67,定时器包装（用于业务Timer进程）9: ;<		 N.#39=	 N.#39=	 N.#39=	 	 =	 > displayErrorHandler("*+HIJ	$error#.	 O F 134 679	错误码: ; <	 =	 > $errorString#.	 ^ F 13!4 679错误描述: ; <	 =	 > 	$filename#.	 ^ F 13#4 679	文件名: ; <	 =	 > $line#.	 O F 13%4 679	文件行: ; <	 =	 > $symbols#.	 T3F 13'4 679	符号表: ; <	 =	 > 1%\PG\MSF\Server::displayErrorHandler()34 67全局错误监听9: ;<		 N.#39 =	 N!.#39"=	 N#.#!39$=	 N%.#)39&=	 N'.#139(=	 	 =	 > checkErrors("*+HIJ	 1\PG\MSF\Server::checkErrors()3+4 67致命错误回调9: ;<		 .	 T339=	 	 =	 > isTaskWorker("*+HIJ	 1\PG\MSF\Server::isTaskWorker()3.4 67是否是task进程9: ;<		 .	 Y 39=	 	 =	 > close("*+HIJ	#q.	 O F 134 679: ; <	 =	 > 1\PG\MSF\Server::close()314 67服务器主动关闭链接9: ;<		 N.#u39=	 	 =	 > ("*+HIJ	$msg#.	 F 1344 679: ; <	 =	 > $log#.	 F 1354 679: ; <	 =	 > 1\PG\MSF\Server::onErrorHandle()34 67错误处理函数9: ;<		 N4.#39=	 N5.#39=	 	 =	 >  * usedTraits	 1&3Server456PG\MSF7Class Server9:" ;<	package	 &phpDocumentor\Descriptor\TagDescriptor3<9:=	 
subpackage	 =	 >  * interfaces	 	 * traits	 
 * markers	 134 6Default7SwooleServer9: ; <	author	 -phpDocumentor\Descriptor\Tag\AuthorDescriptor3D9camera360_server@camera360.com=	 	copyright	 =3G9"Chengdu pinguo Technology Co.,Ltd.=	 <	 =3<9B=	 >	 =	 > 