Easyswoole源码分析-4-start



//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//         佛祖保佑       永无BUG       永不修改                     //

1.简介

启动算是框架的核心部分了,阅读起来有些地方理解起来还是有点困难的,这些部分单独拿出来解析。

2.知识点

1.apc_clear_cache
2.opcache_reset
3.final
4.PHP中Closure类详解

3. 核心代码

start类下的exec方法的核心代码

public function exec(array $args): ?string
{
        // TODO: Implement exec() method.
        //---------------------------------1.清理apc缓存------------------------------
        Utility::opCacheClear();
        //---------------------------------2.展示Logo------------------------------
        $response = Utility::easySwooleLog();
        $mode = 'develop';
        //---------------------------------3.线上|开发配置------------------------------
        if(!Core::getInstance()->isDev()){
            $mode = 'produce';
        }
        $conf = Config::getInstance();
        //---------------------------------4.是否daemon化------------------------------
        if(in_array("d",$args) || in_array("daemonize",$args)){
            $conf->setConf("MAIN_SERVER.SETTING.daemonize", true);
        }
        //---------------------------------5.创建主服务------------------------------
        Core::getInstance()->createServer();
        $serverType = $conf->getConf('MAIN_SERVER.SERVER_TYPE');
        //---------------------------------6.cli展示信息------------------------------
        ·
        · 省略
        ·
        //---------------------------------7.启动------------------------------
        Core::getInstance()->start();
        return null;
}

3.清理apc缓存

核心代码

public static function opCacheClear()
{
        if (function_exists('apc_clear_cache')) {
            // https://www.php.net/manual/zh/function.apc-clear-cache.php
            // 1.根据官方手册来看,apc_clear_cache函数如果传递的参数为omitted或者其它字符将会清除系统缓存
            // 2.如果运行在cli则只清除命令行缓存
            // 3.如果http请求则清除的是http缓存
            apc_clear_cache();
        }
        // https://www.jianshu.com/p/f089b6d19382
        if (function_exists('opcache_reset')) {
            opcache_reset();
        }
}

展示logo略略略
线上|开发配置略略略
是否daemon化略略略

额。都略略略了,,,,其实核心部分在创建主服务。。。。

4. 创建主服务

Core::getInstance()->createServer();

function createServer()
{
        $conf = Config::getInstance()->getConf('MAIN_SERVER');
        //---------------------------------1.创建swoole server------------------------------
        ServerManager::getInstance()->createSwooleServer(
            $conf['PORT'],$conf['SERVER_TYPE'],$conf['LISTEN_ADDRESS'],$conf['SETTING'],$conf['RUN_MODEL'],$conf['SOCK_TYPE']
        );
        //---------------------------------2.注册默认的回调事件------------------------------
        $this->registerDefaultCallBack(ServerManager::getInstance()->getSwooleServer(),$conf['SERVER_TYPE']);
        //---------------------------------3.hook mainServerCreate方法------------------------------
        EasySwooleEvent::mainServerCreate(ServerManager::getInstance()->getMainEventRegister());
        //---------------------------------4.注册Console和crontab(这两个以后单独拿出来分析)------------------------------
        $this->extraHandler();
        return $this;
}

创建swoole server

这里面的Dispatcher、Request、Response类后面单独拿出来介绍。写文章的时候会把人绕晕

/**
     *  根据type创建不同的swoole服务,详细参数参考swoole手册
     *
     * @param $port
     * @param $type
     * @param string $address
     * @param array $setting
     * @param array ...$args
     * @return bool
     * CreateTime: 2019/5/27 下午3:11
     */
    function createSwooleServer($port,$type ,$address = '0.0.0.0',array $setting = [],...$args):bool
    {
        switch ($type){
            // https://wiki.swoole.com/wiki/page/p-server.html
            case EASYSWOOLE_SERVER:{
                $this->swooleServer = new \swoole_server($address,$port,...$args);
                break;
            }
            // https://wiki.swoole.com/wiki/page/327.html
            case EASYSWOOLE_WEB_SERVER:{
                $this->swooleServer = new \swoole_http_server($address,$port,...$args);
                break;
            }
            // https://wiki.swoole.com/wiki/page/397.html
            case EASYSWOOLE_WEB_SOCKET_SERVER:{
                $this->swooleServer = new \swoole_websocket_server($address,$port,...$args);
                break;
            }
            default:{
                Trigger::getInstance()->error('"unknown server type :{$type}"');
                return false;
            }
        }
        if($this->swooleServer){
            // https://wiki.swoole.com/wiki/page/13.html
            $this->swooleServer->set($setting);
        }
        return true;
    }

注册默认的回调事件

private function registerDefaultCallBack(\swoole_server $server,int $serverType)
    {
        //---------------------------------1.非swoole_server------------------------------
        if($serverType !== EASYSWOOLE_SERVER){
                     ···
            //---------------------------------1.1具体这里的Dispatcher有啥用还不清楚,等用到的时候再分析------------------------------
            $dispatcher = new Dispatcher($namespace,$depth,$max);
            $dispatcher->setControllerPoolWaitTime($waitTime);
            $httpExceptionHandler = Di::getInstance()->get(SysConst::HTTP_EXCEPTION_HANDLER);
            if(!is_callable($httpExceptionHandler)){
                $httpExceptionHandler = function ($throwable,$request,$response){
                    $response->withStatus(Status::CODE_INTERNAL_SERVER_ERROR);
                    $response->write(nl2br($throwable->getMessage()."\n".$throwable->getTraceAsString()));
                    Trigger::getInstance()->throwable($throwable);
                };
                Di::getInstance()->set(SysConst::HTTP_EXCEPTION_HANDLER,$httpExceptionHandler);
            }
            //---------------------------------1.2设置异常处理------------------------------
            $dispatcher->setHttpExceptionHandler($httpExceptionHandler);
            //---------------------------------1.3注册回调onRequest方法------------------------------
            EventHelper::on($server,EventRegister::onRequest,function (\swoole_http_request $request,\swoole_http_response $response)use($dispatcher){
                $request_psr = new Request($request);
                $response_psr = new Response($response);
                try{
                    //---------------------------------1.4 hook EasySwooleEvent的onRequest方法------------------------------
                    if(EasySwooleEvent::onRequest($request_psr,$response_psr)){
                        $dispatcher->dispatch($request_psr,$response_psr);
                    }
                }catch (\Throwable $throwable){
                    call_user_func(Di::getInstance()->get(SysConst::HTTP_EXCEPTION_HANDLER),$throwable,$request_psr,$response_psr);
                }finally{
                    try{
                        //---------------------------------1.5 hook EasySwooleEvent的afterRequest方法------------------------------
                        EasySwooleEvent::afterRequest($request_psr,$response_psr);
                    }catch (\Throwable $throwable){
                        call_user_func(Di::getInstance()->get(SysConst::HTTP_EXCEPTION_HANDLER),$throwable,$request_psr,$response_psr);
                    }
                }
                $response_psr->__response();
            });
        }
        //---------------------------------2 注册onTask方法------------------------------
        EventHelper::on($server,EventRegister::onTask,function (\swoole_server $server, Task $task){
            $finishData = null;
            $taskObj = $task->data;

            //---------------------------------2.1 判断是否为使用快速任务模板------------------------------
            // 可通过继承EasySwoole\EasySwoole\Swoole\Task\QuickTaskInterface,增加run方法,即可实现一个任务模板,通过直接投递类名运行任务:
            if(is_string($taskObj) && class_exists($taskObj)){
                          ···
            }
            //---------------------------------2.2 判断是否为异步任务模板------------------------------
            // 当任务比较复杂,逻辑较多而且固定时,可以预先创建任务模板,并直接投递任务模板,以简化操作和方便在多个不同的地方投递相同的任务,首先需要创建一个任务模板
            if($taskObj instanceof AbstractAsyncTask){
                         ···
            //---------------------------------2.3 SuperClosure是否继承SuperClosure(这里的知识点很重要,也不是很好理解,Closure类)------------------------------
            }else if($taskObj instanceof SuperClosure){
                        ···
            //---------------------------------2.4如果传递的为方法 ------------------------------
            }else if(is_callable($taskObj)){
                        ···
            }
            finish :{
                $task->finish($finishData);
            }
        });
        //---------------------------------3 注册onFinish方法 ------------------------------
        EventHelper::on($server,EventRegister::onFinish,function (\swoole_server $serv, int $task_id,$data){
            return $data;
        });

        //---------------------------------4 注册默认的worker start ------------------------------
        EventHelper::registerWithAdd(ServerManager::getInstance()->getMainEventRegister(),EventRegister::onWorkerStart,function (\swoole_server $server,$workerId){
          ···
        });
    }

5.cli展示信息

额。这里自己去看吧。

6. 启动

Core::getInstance()->start();

function start()
    {
        //给主进程也命名
        $serverName = Config::getInstance()->getConf('SERVER_NAME');
        if(PHP_OS != 'Darwin'){
            cli_set_process_title($serverName);
        }
        //启动
        ServerManager::getInstance()->start();
    }

ServerManager::getInstance()->start();

function start()
    {
        // 将EventHelper::registerWithAdd注册的回调绑定到服务,启动的时候只注册了workerStart
        $events = $this->getMainEventRegister()->all();
        foreach ($events as $event => $callback){
            $this->getSwooleServer()->on($event, function (...$args) use ($callback) {
                foreach ($callback as $item) {
                    call_user_func($item,...$args);
                }
            });
        }
        //  子服务,启动的时候只有CONSOLE(这里单独拿出来讲)
        $this->registerSubPortCallback();
        $this->isStart = true;
        // 启动
        $this->getSwooleServer()->start();
    }

7.结语

主要记录学习,不当地方请指出

8.相关连接

Easyswoole手册
Swoole手册

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值