subManager = new SubscribeManager( mySipStack );
      
      if ( UaConfiguration::instance()->getSubscribeOn() )
      {
      cpLog( LOG_DEBUG, "Create Feature Thread" );
      //這里建立一個向FS發(fā)送消息的線程,關于這個部分的內容在Feature //Server的部分再做詳細介紹.
      featureThread = new FeatureThread( subManager );
      assert( featureThread != 0 );
      uaBuilder->setSubscribeManager( subManager );
      }
      }
      else
      {
      … … 
      }
      
      // 是否打開重傳機制?
      if (UaCommandLine::instance( ) -> getBoolOpt( "retransmit" ) )
      {
      SipTransceiver::reTransOn();
      }
      else
      {
      SipTransceiver::reTransOff();
      }
      
      // 定義接收代理服務器(Proxy)發(fā)出的消息所儲存的容器
      myCallContainer = new UaCallContainer;
      assert( myCallContainer != 0 );
      //綁定容器到用戶端
      uaBuilder->setCallContainer( myCallContainer );
      //設置SIP的消息堆棧
      uaBuilder->setSipStack( mySipStack );
      //開始向注冊服務器發(fā)送注冊(Register)消息。
      uaBuilder->startRegistration();
      }
      2.3 HeartLessProxy的創(chuàng)建:
      HeartLessProxy
      ( 
      const Sptr < Builder > builder,
      unsigned short defaultSipPort,
      Data applName,
      bool filterOn, 
      bool nat,
      SipAppContext aContext
      )
      {
      myCallContainer = new CallContainer;
      
      myBuilder = builder;
      myBuilder->setCallContainer(myCallContainer);
      //這里創(chuàng)建了一個消息的輸出隊列,在前面的創(chuàng)建一個UserAgent的實體的過程中已經
      //闡述過會把它綁定到相關的設備上去
      myCallProcessingQueue = new Fifo < Sptr < SipProxyEvent > >;
      //這里創(chuàng)建一個WorkThread線程在該線程中的myBuilder->process(nextEvent)
      //檢查消息隊列myFifo中的返回消息(調用Uabuilder->process進行檢查),從而
      //得到返回的消息。
      //很明顯,這里新創(chuàng)建了一個 myWorkerThread工作線程,我們等一下就會看到如何把它Run
      //起來
      myWorkerThread = new WorkerThread(myCallProcessingQueue, myBuilder);
      
      //創(chuàng)建一個SIP消息收發(fā)器的實體,在這個實體的構建里主要是把收發(fā)SIP消息的TCP/UDP
      //的收發(fā)通道創(chuàng)建(SipUdpConnection和SipUdpConnection)。同時會構造一個SNMP的
      //SipAgent.他的主要作用是向SNMP網關發(fā)送SNMP消息,描述網絡的運行狀態(tài)
      if ( filterOn == true )
      {
      mySipStack = new SipTransceiverFilter(applName, defaultSipPort, nat, aContext);
      }
      else
      {
      mySipStack = new SipTransceiver(applName, defaultSipPort, nat, aContext);
      }
      myBuilder->setSipStack(mySipStack);
      //創(chuàng)建一個SIP消息的解析線程 。
      mySipThread = new SipThread(mySipStack, myCallProcessingQueue); 
      
      … …
      }
      
      2.4 讓User Agent Run起來:
      
        構建User Agent的工作已經完畢,現在應該讓調用它的Run方法了;從下面的程序可以看到,Run方法的調用,讓整個程序進入一種"Idle"的狀態(tài),等待命令輸入和狀態(tài)的產生,這個過程我們可以看到在Ua.CXX的Main程序中調用(ua.run())。
      
      Void UserAgent::run()
      {
      //調用HeartLessProxy的Run方法,稍后做詳細的介紹
      HeartLessProxy::run();
      … … 
      deviceThread->run(); //調用SoundcardDevice::hardwareMain(0)
      … … 
      rtpThread->run();//調用SoundCardDevice::processRTP()進行RTP流的處理
      … …
      //在這里向FS發(fā)送隊列(myQ = new Fifo < Sptr < SubscribeMsg > >)中的各種消息,不
      //過在Ua1001.cfg中,參數Subscribe_on設置為OFF所以,本章我們對FS暫不予以分析,
      //在最后一章詳細分析FS的時候回著重分析它.
      featureThread->run();//調用subscribeManager::subscribeMain()
      … …
      //后臺監(jiān)測線程開啟.
      loadGenThread->run();//調用LoadGenMonitor::lgMain()
      
      // User TimerEvent to kick start the load generator
      … …
      } // UserAgent::run
      
      (未完待續(xù))
      作者供稿 CTI論壇編輯
      作者聯系方法:lu_zheng@21cn.com
        
        在Vovida的基礎上實現自己的SIP協(xié)議棧(二) 
       
曲松县|
延川县|
大港区|
枣阳市|
钟山县|
芒康县|
布拖县|
固镇县|
睢宁县|
罗甸县|
汾西县|
灌南县|
寿阳县|
泽普县|
大厂|
浪卡子县|
阿拉善左旗|
清远市|
十堰市|
阜宁县|
临湘市|
霍城县|
淅川县|
泽库县|
聊城市|
九龙坡区|
黄陵县|
庄河市|
滨海县|
达尔|
嘉黎县|
多伦县|
临西县|
巴南区|
朔州市|
库车县|
五指山市|
阿荣旗|
仙居县|
乌海市|
江孜县|