subManager = new SubscribeManager( mySipStack );
if ( UaConfiguration::instance()->getSubscribeOn() )
{
cpLog( LOG_DEBUG, "Create Feature Thread" );
//這里建立一個(gè)向FS發(fā)送消息的線程,關(guān)于這個(gè)部分的內(nèi)容在Feature //Server的部分再做詳細(xì)介紹.
featureThread = new FeatureThread( subManager );
assert( featureThread != 0 );
uaBuilder->setSubscribeManager( subManager );
}
}
else
{
… …
}
// 是否打開重傳機(jī)制?
if (UaCommandLine::instance( ) -> getBoolOpt( "retransmit" ) )
{
SipTransceiver::reTransOn();
}
else
{
SipTransceiver::reTransOff();
}
// 定義接收代理服務(wù)器(Proxy)發(fā)出的消息所儲(chǔ)存的容器
myCallContainer = new UaCallContainer;
assert( myCallContainer != 0 );
//綁定容器到用戶端
uaBuilder->setCallContainer( myCallContainer );
//設(shè)置SIP的消息堆棧
uaBuilder->setSipStack( mySipStack );
//開始向注冊(cè)服務(wù)器發(fā)送注冊(cè)(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)建了一個(gè)消息的輸出隊(duì)列,在前面的創(chuàng)建一個(gè)UserAgent的實(shí)體的過(guò)程中已經(jīng)
//闡述過(guò)會(huì)把它綁定到相關(guān)的設(shè)備上去
myCallProcessingQueue = new Fifo < Sptr < SipProxyEvent > >;
//這里創(chuàng)建一個(gè)WorkThread線程在該線程中的myBuilder->process(nextEvent)
//檢查消息隊(duì)列myFifo中的返回消息(調(diào)用Uabuilder->process進(jìn)行檢查),從而
//得到返回的消息。
//很明顯,這里新創(chuàng)建了一個(gè) myWorkerThread工作線程,我們等一下就會(huì)看到如何把它Run
//起來(lái)
myWorkerThread = new WorkerThread(myCallProcessingQueue, myBuilder);
//創(chuàng)建一個(gè)SIP消息收發(fā)器的實(shí)體,在這個(gè)實(shí)體的構(gòu)建里主要是把收發(fā)SIP消息的TCP/UDP
//的收發(fā)通道創(chuàng)建(SipUdpConnection和SipUdpConnection)。同時(shí)會(huì)構(gòu)造一個(gè)SNMP的
//SipAgent.他的主要作用是向SNMP網(wǎng)關(guān)發(fā)送SNMP消息,描述網(wǎng)絡(luò)的運(yùn)行狀態(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)建一個(gè)SIP消息的解析線程 。
mySipThread = new SipThread(mySipStack, myCallProcessingQueue);
… …
}
2.4 讓User Agent Run起來(lái):
構(gòu)建User Agent的工作已經(jīng)完畢,現(xiàn)在應(yīng)該讓調(diào)用它的Run方法了;從下面的程序可以看到,Run方法的調(diào)用,讓整個(gè)程序進(jìn)入一種"Idle"的狀態(tài),等待命令輸入和狀態(tài)的產(chǎn)生,這個(gè)過(guò)程我們可以看到在Ua.CXX的Main程序中調(diào)用(ua.run())。
Void UserAgent::run()
{
//調(diào)用HeartLessProxy的Run方法,稍后做詳細(xì)的介紹
HeartLessProxy::run();
… …
deviceThread->run(); //調(diào)用SoundcardDevice::hardwareMain(0)
… …
rtpThread->run();//調(diào)用SoundCardDevice::processRTP()進(jìn)行RTP流的處理
… …
//在這里向FS發(fā)送隊(duì)列(myQ = new Fifo < Sptr < SubscribeMsg > >)中的各種消息,不
//過(guò)在Ua1001.cfg中,參數(shù)Subscribe_on設(shè)置為OFF所以,本章我們對(duì)FS暫不予以分析,
//在最后一章詳細(xì)分析FS的時(shí)候回著重分析它.
featureThread->run();//調(diào)用subscribeManager::subscribeMain()
… …
//后臺(tái)監(jiān)測(cè)線程開啟.
loadGenThread->run();//調(diào)用LoadGenMonitor::lgMain()
// User TimerEvent to kick start the load generator
… …
} // UserAgent::run
(未完待續(xù))
作者供稿 CTI論壇編輯
作者聯(lián)系方法:lu_zheng@21cn.com
在Vovida的基礎(chǔ)上實(shí)現(xiàn)自己的SIP協(xié)議棧(二)
亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩
万年县|
炉霍县|
金湖县|
迁安市|
东安县|
盐城市|
陇川县|
河北区|
太湖县|
泾源县|
朝阳市|
呈贡县|
句容市|
女性|
福泉市|
淮南市|
兴业县|
旺苍县|
钟山县|
沭阳县|
连南|
韩城市|
万年县|
通化县|
鹿泉市|
潍坊市|
托克托县|
吐鲁番市|
开江县|
库伦旗|
大邑县|
西贡区|
巴东县|
德令哈市|
长乐市|
汉川市|
双柏县|
黄骅市|
武城县|
合江县|
邮箱|
http://444
http://444
http://444
http://444
http://444
http://444