首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

OpenRTMFP/Cumulus Primer(六)CumulusServer启动流程分析(续2)

2012-09-28 
OpenRTMFP/Cumulus Primer(6)CumulusServer启动流程分析(续2)OpenRTMFP/Cumulus Primer(6)CumulusServer启

OpenRTMFP/Cumulus Primer(6)CumulusServer启动流程分析(续2)

OpenRTMFP/Cumulus Primer(6)CumulusServer启动流程分析(续2)
  • 作者:柳大·Poechant(钟超)
  • 博客:Blog.CSDN.net/Poechant
  • 邮箱:zhongchao.ustc#gmail.com (# -> @)
  • 日期:April 14th, 2012

    1 main.cpp 中的main()函数中的server

    main.cpp 中真正启动的是server,它继承自Cumulus::RTMFPServer,而Cumulus::RTMFPServer?又继承自Cumulus::StartableCumulus::GatewayCumulus::Handler。而Cumulus::Startable继承自Poco::Runnable,所以其是一个可以运行的线程。在OpenRTMFP/CumulusServer中,这是主线程。

    Server server(config().getString("application.dir", "./"), *this, config());server.start(params);

    这是CumulusServer/Server.h中定义的,其构造函数的原型为:

    Server(const std::string& root,       ApplicationKiller& applicationKiller,       const Poco::Util::AbstractConfiguration& configurations);

    个参数含义如下:

    1. The Path Root for the Server Application
    2. Killer for Termanting the Server Application
    3. Server Configuration

    距离来说,在我的 Worksapce 中:

    • root/Users/michael/Development/workspace/eclipse/OpenRTMFP-Cumulus/Debug/

      构造函数的初始化列表极长:

      Server::Server(const std::string& root,               ApplicationKiller& applicationKiller,               const Util::AbstractConfiguration& configurations)     : _blacklist(root + "blacklist", *this),      _applicationKiller(applicationKiller),      _hasOnRealTime(true),      _pService(NULL),      luaMail(_pState=Script::CreateState(),              configurations.getString("smtp.host","localhost"),              configurations.getInt("smtp.port",SMTPSession::SMTP_PORT),              configurations.getInt("smtp.timeout",60)) {

      下面调用Poco::File创建目录:

          File((string&)WWWPath = root + "www").createDirectory();

      因为roor/Users/michael/Development/workspace/eclipse/OpenRTMFP-Cumulus/Debug/目录,所以WWWPath就是/Users/michael/Development/workspace/eclipse/OpenRTMFP-Cumulus/Debug/www目录。然后初始化GlobalTable,这个GlobalTable是和 Lua 有关的东东,这里暂不细说,先知道与 Lua 相关就好。

          Service::InitGlobalTable(_pState);

      下面就涉及到了 Lua script 了:

          SCRIPT_BEGIN(_pState)        SCRIPT_CREATE_PERSISTENT_OBJECT(Invoker,LUAInvoker,*this)        readNextConfig(_pState,configurations,"");        lua_setglobal(_pState,"cumulus.configs");    SCRIPT_END}

      其中SCRIPT_BEGINSCRIPT_CREATE_PERSISTENT_OBJECTSCRIPT_END都是宏,其定义在Script.h文件中,如下:

      #define SCRIPT_BEGIN(STATE) \    if (lua_State* __pState = STATE) { \        const char* __error=NULL;#define SCRIPT_CREATE_PERSISTENT_OBJECT(TYPE,LUATYPE,OBJ) \    Script::WritePersistentObject<TYPE,LUATYPE>(__pState,OBJ); \    lua_pop(__pState,1);#define SCRIPT_END }

      SCRIPT_BEGINSCRIPT_END经常用到,当与 Lua 相关的操作出现时,都会以这两个宏作为开头和结尾。

      2 main.cpp 中main()函数的server.start()
      void RTMFPServer::start(RTMFPServerParams& params) {

      如果OpenRTMFP/CumulusServer正在运行,则返回并终止启动。

          if(running()) {        ERROR("RTMFPServer server is yet running, call stop method before");        return;    }

      设定端口号,如果端口号为 0,则返回并终止启动。

          _port = params.port;    if (_port == 0) {        ERROR("RTMFPServer port must have a positive value");        return;    }

      设定OpenRTMFP/CumulusEdge的端口号,如果其端口号与OpenRTMFP/CumulusSever端口号相同,则返回并终止启动:

          _edgesPort = params.edgesPort;    if(_port == _edgesPort) {        ERROR("RTMFPServer port must different than RTMFPServer edges.port");        return;    }

      Cirrus:

          _freqManage = 2000000; // 2 sec by default    if(params.pCirrus) {        _pCirrus = new Target(*params.pCirrus);        _freqManage = 0; // no waiting, direct process in the middle case!        NOTE("RTMFPServer started in man-in-the-middle mode with server %s \             (unstable debug mode)", _pCirrus->address.toString().c_str());    }

      middle:

          _middle = params.middle;    if(_middle)        NOTE("RTMFPServer started in man-in-the-middle mode between peers \              (unstable debug mode)");

      UDP Buffer:

          (UInt32&)udpBufferSize =         params.udpBufferSize==0 ?             _socket.getReceiveBufferSize() : params.udpBufferSize;    _socket.setReceiveBufferSize(udpBufferSize);    _socket.setSendBufferSize(udpBufferSize);    _edgesSocket.setReceiveBufferSize(udpBufferSize);    _edgesSocket.setSendBufferSize(udpBufferSize);    DEBUG("Socket buffer receving/sending size = %u/%u",        udpBufferSize,        udpBufferSize);    (UInt32&)keepAliveServer =         params.keepAliveServer < 5 ? 5000 : params.keepAliveServer * 1000;    (UInt32&)keepAlivePeer =         params.keepAlivePeer < 5 ? 5000 : params.keepAlivePeer * 1000;    (UInt8&)edgesAttemptsBeforeFallback = params.edgesAttemptsBeforeFallback;    setPriority(params.threadPriority);

      启动线程,进入循环运行:

          Startable::start();}

      上句具体的源码实现为:

      void Startable::start() {    if (running())        return;

      如果在运行则返回并终止启动。然后加一个局部锁。

          ScopedLock<FastMutex> lock(_mutex);

      如果不得不join()到主线程中,那就join()

          if(_haveToJoin) {        _thread.join();        _haveToJoin=false;    }

      然后就运行这个线程吧:

          _terminate = false;    _thread.start(*this);    _haveToJoin = true;}

      -

      转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant

      -

热点排行