WebRtc底層庫(kù)libjingle類(lèi)與類(lèi)之間的通信使用了信號(hào)和槽機(jī)制sigslot library. 信號(hào)和槽是一種非常簡(jiǎn)單的類(lèi)與類(lèi)之間的通用通信框架.通過(guò)如下方式實(shí)現(xiàn): - 發(fā)送信號(hào)類(lèi)申明一個(gè)特定參數(shù)的signal. - 監(jiān)聽(tīng)類(lèi)實(shí)現(xiàn)槽函數(shù)(solt),槽函數(shù)必須和發(fā)送信號(hào)申明的參數(shù)一致(信號(hào)發(fā)送類(lèi)和實(shí)現(xiàn)類(lèi)可以是同一個(gè)類(lèi))。槽函數(shù)無(wú)返回值,并且類(lèi)一定要繼承sigslot::has_slots<> - 監(jiān)聽(tīng)者通過(guò)調(diào)用信號(hào)的connect方法,實(shí)現(xiàn)信號(hào)和槽的綁定。 - 信號(hào)和槽綁定之后,可以通過(guò)調(diào)用信號(hào),從而直接調(diào)用槽函數(shù)(跟函數(shù)指針類(lèi)似)
一個(gè)槽能和多個(gè)信號(hào)綁定。
總體來(lái)說(shuō)libjingle分兩大線程分別為signaling thread和 worker thread。signaling thread主要負(fù)責(zé)事件和狀態(tài), worker thread主要跟各種數(shù)據(jù)流相關(guān)。 為此libjingle也是煞費(fèi)苦心,比如:
/*android/webrtc/src/talk/app/webrtc/peerconnectionfactory.cc*/bool PeerConnectionFactory::Initialize() { RTC_DCHECK(signaling_thread_->IsCurrent()); rtc::InitRandom(rtc::Time()); default_allocator_factory_ = PortAllocatorFactory::Create(worker_thread_); if (!default_allocator_factory_) return false;/* 實(shí)際上就是在worker_thread_線程中調(diào)用了CreateMediaEngine_w方法, 在libjingle庫(kù)中有很多類(lèi)似的用法*/cricket::MediaEngineInterface* media_engine = worker_thread_->Invoke<cricket::MediaEngineInterface*>(rtc::Bind( &PeerConnectionFactory::CreateMediaEngine_w, this)); channel_manager_.reset( new cricket::ChannelManager(media_engine, worker_thread_)); channel_manager_->SetVideoRtxEnabled(true); if (!channel_manager_->Init()) { return false; } dtls_identity_store_ = new RefCountedDtlsIdentityStore( signaling_thread_, worker_thread_); return true;}通常來(lái)說(shuō)有如下規(guī)律: - OnSomeMethod,以on命名的函數(shù)表示是一個(gè)信號(hào)的槽函數(shù)。 - SomeMethod_w 以”_w”結(jié)尾的函數(shù)表示此函數(shù)將在worker thread線程中運(yùn)行 - SignalSomeName 信號(hào)的申明,可以調(diào)用槽函數(shù)
每個(gè)P2PTransportChannel代表本地和遠(yuǎn)程鏈接的數(shù)據(jù)通道。Channel是一個(gè)為了健壯性和性能而抽象出的一個(gè)概念。P2PTransportChannel管理許多的Connection對(duì)象,而每一個(gè)Connection對(duì)象都表示一個(gè)特性的鏈接類(lèi)型比如UDP,TCP,RELAY ,etc。Connection實(shí)際上又封裝了一對(duì)對(duì)象,分別是Port的子類(lèi)和一個(gè)地址(an address)。Port的子類(lèi)代表本地的鏈接,an address表示遠(yuǎn)程鏈接。如果某個(gè)特定的connection斷開(kāi)了,P2PTransportChannel將會(huì)瞬間切換到另一個(gè)最佳鏈接. 下圖從一個(gè)較高的層次顯示P2P鏈接的數(shù)據(jù)流動(dòng)形式:  libjingle 應(yīng)用在跟遠(yuǎn)程端協(xié)商建立鏈接時(shí),本地端會(huì)創(chuàng)建一系列的潛在接入端,也稱(chēng)為candidates,被Port對(duì)象封裝的本地candidates是由PortAllocator子類(lèi)分配。本地Port對(duì)象要么在CreatOffer時(shí)被創(chuàng)建,要么在接受到遠(yuǎn)程的請(qǐng)求后創(chuàng)建(也就是在Answer期間)。遠(yuǎn)程端P2PTransportChannel收到offer請(qǐng)求,將會(huì)創(chuàng)建一個(gè)Connection對(duì)象封裝遠(yuǎn)程candidate和本地Port.本地端P2PTransportChannel收到Answer,也會(huì)創(chuàng)建一個(gè)Connection對(duì)象封裝遠(yuǎn)程candidate和本地Port。
 libjingle 應(yīng)用在跟遠(yuǎn)程端協(xié)商建立鏈接時(shí),本地端會(huì)創(chuàng)建一系列的潛在接入端,也稱(chēng)為candidates,被Port對(duì)象封裝的本地candidates是由PortAllocator子類(lèi)分配。本地Port對(duì)象要么在CreatOffer時(shí)被創(chuàng)建,要么在接受到遠(yuǎn)程的請(qǐng)求后創(chuàng)建(也就是在Answer期間)。遠(yuǎn)程端P2PTransportChannel收到offer請(qǐng)求,將會(huì)創(chuàng)建一個(gè)Connection對(duì)象封裝遠(yuǎn)程candidate和本地Port.本地端P2PTransportChannel收到Answer,也會(huì)創(chuàng)建一個(gè)Connection對(duì)象封裝遠(yuǎn)程candidate和本地Port。
P2PTransportChannel創(chuàng)建和管理多個(gè)connection對(duì)象,實(shí)時(shí)第評(píng)估每個(gè)connection的性能,實(shí)時(shí)選擇性能最優(yōu)的connection作為當(dāng)前傳輸通道。
上圖沒(méi)有畫(huà)出P2PTransport,P2PTransport是整個(gè)P2P系統(tǒng)的頂層,負(fù)責(zé)創(chuàng)建銷(xiāo)毀,和監(jiān)控P2PTransportChannel對(duì)象,但是不負(fù)責(zé)實(shí)際的數(shù)據(jù)傳輸。真正負(fù)責(zé)數(shù)據(jù)傳輸?shù)氖荲oiceChannel,VideoChannel,DataChannel ,最終都是通過(guò)P2PTransportChannel實(shí)現(xiàn)數(shù)據(jù)的傳輸。
libjingle最強(qiáng)大的功能在于能夠跨越防火墻和NAT建立鏈接。libjingle使用ICE協(xié)議穿透防火墻,首先libjingle準(zhǔn)備跟遠(yuǎn)程端建立鏈接時(shí)將會(huì)產(chǎn)生一系列潛在的本地端口地址供遠(yuǎn)程端鏈接。這些潛在的地址稱(chēng)之為Candidate.Candidates就是ip:port對(duì),本地端和遠(yuǎn)程端依據(jù)Ip:port對(duì)就能建立p2p鏈接。libjingle為穿透NAT或者防火墻,發(fā)現(xiàn)能夠供遠(yuǎn)程端鏈接的candidates提供了健壯的機(jī)制。 為了盡可能的為遠(yuǎn)程端提供共鏈接的Candidate,libjingle產(chǎn)生如下三種本地接入端: 1. Local IP addresses :本地的ip地址,其他在共享局域網(wǎng)的遠(yuǎn)程端可以訪問(wèn)這個(gè)地址 2. Global addresses:這是跨越防火墻/NAT的外部地址。如果網(wǎng)關(guān)是NAT設(shè)備,libjingle使用STUN服務(wù)器將NAT綁定到本地端并且向外暴露internet地址.這個(gè)地址供外部的遠(yuǎn)程斷鏈接 3. Relay server addresses:接近8%的客戶(hù)端不能按照上面的兩種方式建立鏈接,需要通過(guò)relay server中轉(zhuǎn)的形式,實(shí)現(xiàn)跨越防火墻的數(shù)據(jù)交換
如下圖所示: 
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注