WebRTC的誕生背景
我們知道現在實時視頻通信很普遍,基于FaceTime和Skype等視頻通話工具,用戶可以很方便地與他人進行視頻對話,開發者們為了將用戶體驗優化到極致,通過大量的技術手段保障視頻質量,比如減少丟包、斷網恢復、即時回應用戶網路變化等等,實時音視頻通信對開發者的技術要求比較高,而且專利持有公司向開發者征收授權費,并構筑起巨大的技術壁壘,另一方面,對用戶來說,需要去額外安裝相應的插件或者應用程式,降低了用戶體驗,而且還有被捆綁流氓軟體的風險,這時候一種叫WebRTC的技術應運而生了,
在講WebRTC之前,我們先回顧一下Web通信的演化歷史,在AJAX出現之前,也就是05年之前,如果需要更新內容,必須多載整個網頁頁面,AJAX出現之后,通過在后臺與服務器進行少量資料交換,AJAX 可以使網頁實作異步更新,但AJAX不能與服務器進行雙工通信,因此服務器無法主動推訊息給瀏覽器,只能通過瀏覽器進行輪詢,Websocket的出現使這個局面得到改觀,瀏覽器與服務器能進行全雙工通信,不管是AJAX還是Websocket,都需要將資料發送給服務端,為了在兩個用戶間傳送資料,開發者需要購買服務器網路,這方面的成本是非常龐大的,由谷歌支持的一項新技術——WebRTC徹底改變了這個局面,WebRTC是Web Real-Time Communication的縮寫,實作了瀏覽器之間直接的實時通訊,而不再需要服務器中轉,谷歌致力于讓其成為HTML5的標準之一,目前大部分瀏覽器也已經支持,
WebRTC與P2P的結合
12年谷歌的chrome瀏覽器正式原生支持WebRTC,web開發者只需要幾行javascript代碼就可以開發出豐富的實時多媒體應用,而用戶也無需安裝插件,直接打開瀏覽器就可以與對方實時聊天,這時候有些嗅覺敏銳的開發者開始利用WebRTC的資料通道技術做P2P流媒體,例如國外一家公司叫做peer5,我們公司的創始人也從很早之前就投入到這方面的研究,但失望的發現用WebRTC做P2P流媒體還有一些問題難以解決,主要是支持的瀏覽器有限,互相之間也有很大的兼容問題,隨后在13年和14年,Firefox和Opera也相繼宣布支持WebRTC,更重要的是HLS這樣的基于分片傳輸、適合P2P分發的協議越來越流行,這時我們發現時機已經越來越成熟了,只要某個直播流或者點播頻道有足夠的人在線(通常只要數十人在線就可以達到很好的P2P效果),加上良好設計的網路拓撲演算法(比如網狀拓撲,對節點的上下線并不敏感),就可以讓P2P效果達到某個穩定的水平,并且可以跟HTTP源形成很好的互補,我們都知道在看視頻期間,用戶的上行帶寬大部分時間是處于閑置狀態,如果能把這些計算能力和網路帶寬利用起來,這樣相當于千家萬戶都是節點,你的鄰居甚至你的舍友也許就在為你看視頻提供加速,想想都是很酷的事情!因此我們成立了公司,開始持續數年的耕耘,
可能大家會有疑問,WebRTC將來真的會成為一種主流技術嗎?我們用事實說話,看看各大瀏覽器的支持情況就知道了,從圖中可以看出,大部分瀏覽器都已支持WebRTC,包括chrome、firefox和opera,微軟基于chromium內核的edge瀏覽器也支持WebRTC,另外,蘋果的safari也已經支持WebRTC,未來基于WebRTC的應用將越來越多,這是可以肯定的,

WebRTC媒體會話原理
我們假設現在有兩個瀏覽器A和B要建立WebRTC對等連接,對等連接就是兩個Web瀏覽器之間的直接媒體連接,如果A要主動聯系B,需要先通過HTTP向信令服務器發送一個SDP,SDP可以理解為一個電腦名片,全稱是Session Description Protocol,會話描述協議,用于描述對等連接的媒體特征,那么信令服務器又是什么呢?它就像一個紅娘,幫兩個互相不認識的人牽線,瀏覽器A發過來的SDP叫做offer,信令服務器將其傳給瀏覽器B,后者收到后回應一個SDP物件,叫做answer,也通過信令服務器中轉給A,交換完SDP后,兩個對等端就開始嘗試ICE打洞,打洞成功后開始協商密鑰,之后就可以開始安全的媒體或資料會話了,

ICE打洞原理
由于IPv4提供的IP資源有限,IPv6還沒有推廣開來,大部分網路設備還處于內網中,需要通過NAT設備來與外部internet連接,NAT全稱Network Address Translation,網路地址轉換,裝有NAT軟體的路由器叫做NAT路由器,它至少有一個有效的外部全球IP地址,這樣,所有使用本地地址的主機在和外界通信時,都要在NAT路由器上將其本地地址轉換成全球IP地址,才能和因特網連接,當兩個對等端處于不同的局域網中時,需要先知道對方的公網IP和埠,這時候可以先向STUN服務器發送測驗資料包,后者做出回應,指示其在測驗資料包中監測到的IP地址,此地址將成為潛在的候選地址回傳,拿到候選地址的瀏覽器將其通過信令服務器發送給對等端,對等端也進行同樣的操作,之后雙方用所有得到的候選地址嘗試連接,如果都沒有成功的情況下,會用TURN服務器來作為中轉服務器,TURN服務器是在所有替代方案都無效的情況下才有采取的,因為成本比較高昂,為了加速通話建立時間,有一個叫trickle ice的方案,其思想是客戶端一邊收集candidate一邊發送給對方,比如local candidate 不需要通過stun獲取直接就可以發起,這降低了了連通性檢測完成的時間,

WebRTC資料通道
接下來介紹一個比較重要的概念——WebRTC data channel,我們基于WebRTC來做P2P流媒體,實際上就是用的data channel能力,那么data channel到底是什么呢?雖然有關WebRTC的宣傳主要側重于它對于實時音視頻通訊的支持,但設計師一直都希望它也支持實時資料傳輸,相比Websocket和HTTP,資料通道支持流量大、延遲低的連接,具有穩定可靠等優點,而且data channel的介面和websocket一樣,也是通過send來發送資料,通過ommessage來接收資料,那么如何對data channel資料傳輸的可靠性進行控制呢?通過剛才所講的dataChannelOptions這個javascript物件,可以讓data channel在UDP或者TCP的優勢之間進行切換,比如讓資料傳輸得更加穩定可靠,或者傳輸得更快,其中有幾個比較重要的欄位:ordered:設定資料的接受是否需要按照發送時的順序,maxRetransmitTime:設定資料發送失敗時,多久重新發送,maxRetransmits:設定資料發送失敗時,最多重發次數,主要是配置ordered,當設定為true時資料通道表現更像TCP,false時表現更像UDP,
WebRTC與P2P流媒體
把WebRTC的data channel搞清楚后,我們就可以用用它來做P2P流媒體了,這方面已經有國外大神開發的知名開源專案:WebTorrent,在github上有1萬多顆星,WebTorrent是一個開源的基于WebRTC 和BT協議的js框架,完全用javascript撰寫,可以同時運行于 Node.js 和瀏覽器,由于基于WebRTC,因此WebTorrent不需要安裝任何插件,就可以跑在瀏覽器上,同時支持Chrome, Firefox 和 Opera瀏覽器,但是由于是基于BT協議,所以是一種pull-based的演算法,這種演算法是一種隨機抓取的策略,隨機抓取其它節點的buffer,但這樣會存在一個問題:抓取的buffer不一定是目前需要的,也不一定是其他節點需要的,而且還會浪費下行帶寬和其它節點的上行帶寬,因此同時造成了“帶寬饑餓”和“內容饑餓”問題,下面介紹一種改進版的pull-based演算法——FirstAid演算法,FirstAid是基于視窗滑動的,每隔一段時間觸發一次視窗滑動,每個視窗又可以分成三段:urgent、normal和prefetch,urgent顧名思義,是離播放時間最近的buffer,所以優先級別最高,normal和prefetch優先級遞減,當父節點為子節點傳輸buffer時,會優先滿足urgent級別的要求,而暫停normal級別的,所以最緊迫的需求會優先得到滿足,當子節點的urgent需求得到滿足后,需要回過頭來彌補他的競爭對手的需求,以達到一種互惠互利的狀態,和剛才pull-based演算法思想截然相反的是push-based演算法,其中比較有代表性的是FashMesh演算法,由港科大的學者提出來的一種P2P演算法,FashMesh是基于一種叫Streaming Mesh的演算法,將源節點的資料流分成多個子流,通過多棵生成樹構成mesh來源源不斷的傳輸給子節點,這種演算法的優勢是延遲低,帶寬利用率高,Fast Mesh還可以根據每個子節點的上行帶寬來動態的調整網路拓撲結構,讓上行帶寬大的節點更加接近源節點,從而充分利用網路的現有能力,根據一項對比試驗,FastMesh可能是目前眾多P2P演算法中效果最好的,但這個演算法也有缺點,當節點進入或離開網路時,都需要重新調整拓撲結構,因此不適合節點變化較大的情況,
我們自行研發的演算法——Push-Pull演算法則綜合了push-based和pull-based兩種演算法的優勢,用pull的方式從父節點獲取優先級最高的buffer,由父節點以push的方式為其提供后續的buffer,另外,我們的演算法混合HTTP、HTTPS、WebRTC等多種協議,在優先保證用戶體驗的前提下最大化P2P率,經過測驗,Push-Pull演算法具備低延遲、高帶寬利用率、高P2P率、對網路拓撲結構變化魯棒性強等優勢,
SwarmCloud
SwarmCloud的web端SDK(hlsjs-p2p-engine,github地址:https://github.com/cdnbye/hlsjs-p2p-engine) 是完全用JavaScript寫的HTML5流媒體加速SDK,實作了融合HTTP、WebRTC的多協議、多源、低延遲、高帶寬利用率的無插件Web端流媒體加速能力,基于hls.js的MSE技術(Media Source Extension)將來自多個源節點的Buffer分塊喂給播放器,再加上精心設計的演算法來達到最優的調度策略及對各種邊界條件的處理,hlsjs-p2p-engine能在保證用戶流暢視頻體驗的前提下最大化P2P率,
集成我們的web端SDK也非常簡單,只需要短短幾行代碼,把js檔案引入到script標簽中,像使用hls.js或者其他web播放器一樣即可,Demo演示地址:https:// https://demo.cdnbye.com/,以下是代碼示例:
<script src="//cdn.jsdelivr.net/npm/cdnbye@latest"></script>
<video id="video" controls></video>
<p id="version"></p>
<h3>download info:</h3>
<p id="info"></p>
<script>
document.querySelector('#version').innerText = `hls.js version: ${Hls.version} cdnbye version: ${Hls.engineVersion}`;
var video = document.getElementById('video');
var source = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
if(Hls.isSupported()) {
var hls = new Hls({
p2pConfig: {
logLevel: false,
live: true, // set to false in VOD mode
// Other p2pConfig options provided by CDNBye
}
});
hls.loadSource(source);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
hls.p2pEngine.on('stats', function ({totalHTTPDownloaded, totalP2PDownloaded, totalP2PUploaded}) {
var total = totalHTTPDownloaded + totalP2PDownloaded;
document.querySelector('#info').innerText = `p2p ratio: ${Math.round(totalP2PDownloaded/total*100)}%, saved traffic: ${totalP2PDownloaded}KB, uploaded: ${totalP2PUploaded}KB`;
});
}
// This is using the built-in support of the plain video element, without using hls.js.
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = source;
video.addEventListener('loadedmetadata',function() {
video.play();
});
}
</script>
結語
相對于傳統的模式,SwarmCloud可以說是站在共享經濟的風口上,我們知道傳統的CDN廠商會先以批發價從ISP買進帶寬,然后再以零售價賣給CP,CP買入帶寬后進行內容分發,為終端用戶提供CDN服務,我們則是基于Daas模式(Device as a Service),每個設備既是資料消耗者,同時又是分享者,從而在千家萬戶擁有了分布廣泛的節點,不僅大幅提升了用戶的播放流暢度,BGP機房、ISP骨干網的壓力也得以緩解,從而實作多贏局面,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/295676.html
標籤:其他
