加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-14 22:20:21 所属栏目:大数据 来源:网络整理
导读:OpenRTMFP/Cumulus Primer(6)CumulusServer启动流程分析(续2) 作者:柳大·Poechant(钟超) 博客:Blog.CSDN.net/Poechant 邮箱:zhongchao.ustc#gmail.com (# - @) 日期:April 14 th ,2012 1 main.cpp 中的 main() 函数中的 server main.cpp 中真正启

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,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

-

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读