標籤:

互動式連接建立(ICE)

互動式連接建立是一種標準穿透協議,利用Stun和Turn伺服器來幫助端點建立連接。市面上已有不少介紹ICE的資料,像《WebRTC權威指南(第三版)》中的「9.2n n互動式連接建立」。但看了那些後,有人還是不能理解,這裡試著用一個實例來描述整個過程。ICE協議只是制定規範,沒規定怎麼實現細節,在細節實現上這裡參考Google的WebRTC。

n圖1 ICE呼叫流程

n  上圖就是《WebRTC權威指南(第三版)》中的圖9.1。呼叫要交換兩種信息,一是候選地址,二是媒體信息。候選地址用於建立網路連接,它存儲著和網路連接相關的參數。媒體信息(SDP)用於描述要在對等連接上傳輸的數據,包括音頻、視頻和數據。用路和車來比喻的話,候選地址用於造路,媒體信息於用指定要跑什麼車。

n  在圖中,雙方是串列處理媒體、候選地址,但實際中是並發的。舉個例子,主叫收到Answer後,它仍可能在收集候選地址,然後通過信令伺服器發向被叫。

  除了主叫必須創建Offer才開始收集候選地址、被叫必須創建Answer才開始收集候選地址外,ICE代理是相互獨立地處理媒體和候選地址。(這結論細節參考底下的「四:選定候選地址,並啟動媒體」)。

n  和「9.2 互動式連接建立」一樣, 這裡也把ICE分為六個步驟。下圖是例子使用的網路拓撲結構。

一:收集候選地址

n  候選地址是或許可用於接收媒體以建立對等連接的<IP地址, 埠>對,它分四種類型。

  具體到例子,以下是此階段將至少能收集到的候選地址。為簡單,不再寫A的IP2、B的IP2的伺服器反射地址。

二:交換候選地址

n  A通過信令伺服器把A$Cand1、A$Cand2、A$Cand3發向B,相應地,B通過信令伺服器把B$Cand1、B$Cand2、B$Cand3發向A。對端收到一個候選地址後會做什麼?深入它之前讓引入兩種對象:P2PTransportChannel、Connection。

n  ICE代理用P2PTransportChannel管理通道(Component)上的網路傳輸。什麼是通道?Webrtc有個概念叫軌道(Track),常見有視頻軌、音頻軌,而要發送一條軌道中數據,最多可能使用兩個通道,分別是Rtp、Rtcp。肯定會有Rtp,Rtcp則可選。一個P2PTransportChannel對應一條通道,如果當前會話要同時處理音頻、視頻,每條軌道又都包括Rtp、Rtcp,那會話中就存在四個P2PTransportChannel對象。P2PTransportChannel用維護一張連接狀態表來管理網路傳輸,表中一條記錄對應一個Connection對象。這裡讓具體到A的視頻Rtp對應的P2PTransportChannel,看它在收到B$Cand1後會做什麼。

n  當A收到B發來的B$Cand1後,P2PTransportChannel會向連接狀態表新增兩條記錄,即兩個Connection。這時已到通道,地址須是ip:port對。

n  此時A不知道該用哪個網卡IP才能把數據成功發向192.168.0.204,於是它只要在有可能的地址對就創建Connection。注意Connection只會基於網卡IP,即host,因為對發送源來說,host才可能是源,其它的只是中間轉換出的地址,像srflx。當然,創建時會放棄明顯不可能的<網卡地址,n 對端地址>對,舉個例子,網卡地址是ipv4,而對端地址是ipv6。

n  當收全B$Cand1、B$Cand2、B$Cand3,狀態表中就有6條記錄。

n  表中有一條、或多條、或沒有,能夠把A的視頻Rtp數據發向B的視頻Rtp通道,到底怎麼個可能性就要執行接下的Stun檢查。

三:STUN檢查

n  在狀態表新建一條記錄,即一個Connection,很快就會在此Connection上進行Stun檢查。Stun檢查具體操作是在此Connection上發Stun Binding請求。由於要能支持Stun應答,每個ICE代理必須內置Stun伺服器功能。Stun檢查具體步驟見下圖。

n  為什麼說Stun檢查會發現prflx候選項?假如A和Stun伺服器之間連接狀態不好,在它收到B發來的srflx(11.92.14.8)之後還沒得出自個的srflx(211.161.240.181)。雖然A沒得到自個的srflx,但這不妨礙對B的srflx這個候選地址進行Stun檢查,於是會向11.92.14.8發Stun請求。B收到這個請求,從請求解析出211.161.240.181。雖然這個地址在值上等於A的srflx,但不是從信令伺服器得到,而是來自對端的Stun請求。此時B就會以這個prflx向狀態表新建Connection。

n  A在之後終於向Stun伺服器拿到了自個的srflx,並通過信令伺服器發向B。B發現這個srflx值對應的Connection已存在,就不會再創建了。

n  到此可得出個結論:兩種原因會導致新建Connection,一是從信令伺服器收到候選地址,二是Stun檢查發現prflx。不同於從信令伺服器得到地址而創建的Connection,Stun檢查時創建的Connection一開始就基本能確定連接是暢通的。

四:選定候選地址,並啟動媒體

n  P2PTransportChannel會維護連接狀態表,並排序表中記錄(SortConnectionsAndUpdateState)。排序指的是計算每條記錄的連接「成本」,把成本最低的排在第一條。如何計算成本?這涉及到很多因素,比如發出Stun請求到收到應答經過了的時間,用時越少的「成本」自然會低些。

  當A有視頻Rtp數據要發送時,它檢查狀態表的第一條記錄,如果判斷出它的狀態是發送就緒,就會用此Connection進行發送。否則直接放棄這個發送任務。媒體模塊在處理數據的採集、編碼任務時,不用考慮候選地址方面進展怎樣了,只是要到發送時才關注下,而即使不能發送也不會影響自個進度;同樣,候選地址處理模塊也不會關注媒體處理模塊的進度。這正是之前寫的一個結論:「除了主叫必須創建Offer才開始收集候選地址、被叫必須創建Answer才開始收集候選地址外,ICE代理是相互獨立地處理媒體和候選地址」。

n  維護表任務包括新建、刪除記錄,以及修改記錄中的狀態欄位。刪除記錄、修改狀態都涉及到「長連接」。

五:長連接

n  為確保NAT映射和過濾規則不在媒體會話期間超時,ICE會不斷通過使用中的候選項對發送Stun連接檢查。具體到P2PTransportChannel,表現出來的是對狀態表中所有記錄隔段時間就要發送個Stunn nBinding請求。如果檢測到本來是暢通的Connection上Stun應答超時了,那它就會更改該Connection狀態,執行表排序時就有可能會向下掉,嚴重時會從狀態表刪除該記錄。

n  一記錄被刪除後,如果之後那候選地址的連接又恢復了,則會基於該候選地址重新創建Connection。

六:ICE重新啟動

n  分析長連接時,我們已能得出個結論,如果是網路擁堵或通斷導致的狀態表變化,P2PTransportChannel內部就能處理。但是,如果基地址發生改變,像一網卡被禁用,這就超出P2PTransportChannel可處理範圍了,需重啟ICE。


推薦閱讀:

基於 WebRTC 的視頻聊天技術在 iOS 端的實現
Kurento是否可以讓客戶端選擇不同的實時監控視頻?
WebRTC有前途嗎?
webRTC : HTML5 視頻 直播 技術

TAG:WebRTC |