自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

WebRTC第一課:從信令、ICE到NAT穿透的連接建立全流程

網(wǎng)絡 通信技術
在實際的網(wǎng)絡環(huán)境中,建立WebRTC這樣的端到端連接的確并非易事。因此,在這篇文章中,我將繼續(xù)上一篇文章的內容,全面探討一下WebRTC連接建立的全流程,涵蓋信令交換、ICE候選信息采集和選擇、NAT穿透的各個關鍵步驟,希望能給大家理解WebRTC技術棧帶去幫助。

在上一篇文章《WebRTC第一課:網(wǎng)絡架構與NAT工作原理》中,我們介紹了WebRTC的網(wǎng)絡架構和NAT的基本概念,學習了WebRTC采用端對端(P2P)的通信模型,知道了NAT(網(wǎng)絡地址轉換)的概念以及給像WebRTC這樣的直接P2P通信帶來的挑戰(zhàn)。

在實際的網(wǎng)絡環(huán)境中,建立WebRTC這樣的端到端連接的確并非易事。因此,在這篇文章中,我將繼續(xù)上一篇文章的內容,全面探討一下WebRTC連接建立的全流程,涵蓋信令交換、ICE候選信息采集和選擇、NAT穿透的各個關鍵步驟,希望能給大家理解WebRTC技術棧帶去幫助。

1. WebRTC連接建立概覽

在深入細節(jié)之前,我們先用一個時序圖來概覽WebRTC連接建立的主要步驟:

圖片圖片

注:上圖由mermaid[1]生成,對應的腳本在webrtc-first-lesson/part2/process-overview.mermaid。

這個過程可以概括為以下幾個主要步驟:

  • 信令交換:客戶端通過信令服務器交換必要的連接信息,包括會話描述協(xié)議(SDP)數(shù)據(jù)。
  • ICE候選收集:每個客戶端收集可能的連接方式(稱為ICE候選)。
  • 候選交換:通過信令服務器交換ICE候選信息。
  • 連通性檢查:客戶端嘗試各種可能的連接方式。
  • 建立P2P連接:選擇最佳的連接路徑,建立直接的端到端連接。

在這個過程中,我們會涉及到幾個關鍵概念:

  • 信令(Signaling):用于協(xié)調通信并交換元數(shù)據(jù)的過程。
  • ICE(Interactive Connectivity Establishment):一種用于在各種網(wǎng)絡情況下協(xié)助建立端到端連接的框架。
  • NAT穿透(NAT Traversal):克服網(wǎng)絡地址轉換帶來的通信障礙的技術。

接下來,我們將詳細探討這些概念,并基于這些概念詳細說明WebRTC建連的全流程。

我們先來看看信令(Signaling)。

2. 信令:WebRTC連接的基礎

WebRTC技術棧中**唯一沒有標準化的就是信令(Signaling)**,但信令卻又是WebRTC連接的基礎和必不可少的部分。

信令是WebRTC中用于協(xié)調通信過程的“指令”,它負責在對等端之間交換建立連接所需的元數(shù)據(jù),但不會直接傳輸音視頻數(shù)據(jù)。信令的主要作用包括:

  • 交換會話描述協(xié)議(SDP)信息
  • 交換網(wǎng)絡配置信息(ICE候選)
  • 協(xié)調會話的開始和結束
  • 處理錯誤和會話狀態(tài)變化

WebRTC本身并未定義信令協(xié)議標準,這主要考慮的是信令的設計與實現(xiàn)依賴于具體應用的需求,同時也有兼容性方面的考慮,比如:使WebRTC能夠與現(xiàn)有的通信系統(tǒng)集成。在安全性方面,自定義信令也可以允許應用層來控制如何交換敏感信息。

目前用于WebRTC信令協(xié)議實現(xiàn)的常見方案主要包括基于WebSocket的自定義協(xié)議、SIP協(xié)議(Session Initiation Protocol)以及一些像XMPP(eXtensible Messaging and Presence Protocol)這樣的成熟的即時通訊協(xié)議等。

就我個人而言,SIP和XMPP這樣的傳統(tǒng)協(xié)議都太重了,協(xié)議自身理解起來就有門檻!基于WebSocket的自定義協(xié)議,既簡單又靈活,適合大多數(shù)業(yè)務不那么復雜的場景,在本文中,我們的信令協(xié)議就基于WebSocket自定義協(xié)議來實現(xiàn)。

Why Websocket?用WebSocket承載自定義信令協(xié)議的主要原因是幾乎所有現(xiàn)代瀏覽器和后端框架都支持WebSocket,并且它是全雙工通信,允許服務器和客戶端隨時發(fā)送消息,并且建立連接后,消息交換的開銷也很小。

在設計信令語義時,我們通常會采用“Room”這個抽象模型來管理參與通信的客戶端,這與WebRTC常用于互聯(lián)網(wǎng)音視頻應用不無關系。Room模型有助于組織和管理多個參與者,控制消息的廣播范圍,并可以實現(xiàn)更復雜的通信場景(如多人會議系統(tǒng))。

下面是基于Room模型設計的信令交互的典型流程:

圖片圖片

注:上圖由mermaid[2]生成,對應的腳本在webrtc-first-lesson/part2/signaling-room-model-flow.mermaid。

下面對圖中幾個關鍵流程做一些簡要說明:

  • 房間創(chuàng)建

Client1向SignalingServer發(fā)送創(chuàng)建房間的請求,SignalingServer創(chuàng)建房間并返回房間ID給Client1。

  • 客戶端加入

Client2使用房間ID向SignalingServer發(fā)送加入房間的請求,SignalingServer通知Client1有新客戶端加入。SignalingServer向Client2確認加入成功,并返回房間信息。重復相同的過程,Client3也如此加入了房間。

  • WebRTC連接建立(以Client1和Client2為例)

Client1創(chuàng)建Offer并通過SignalingServer向Client2發(fā)送Offer,SignalingServer將Offer轉發(fā)給Client2。Client2創(chuàng)建Answer,并通過SignalingServer向Client1轉發(fā)Answer。之后,Client1和Client2還會以類似的方式互相交換ICE候選信息,通過SignalingServer進行轉發(fā)。

注:offer是由發(fā)起者(通常是調用方)創(chuàng)建的SDP(Session Description Protocol)消息,表示希望建立的媒體會話的描述。answer是由接收者(通常是被叫方)回復的SDP消息,表示其對offer的響應。SDP中通常包含媒體格式、網(wǎng)絡信息、編解碼器等詳細信息,供雙方協(xié)商和確認,具體可參考我之前的文章《使用Go和WebRTC data channel實現(xiàn)端到端實時通信[3]》。

  • 客戶端離開(以Client2離開為例)

Client2向SignalingServer發(fā)送離開房間的請求,SignalingServer通知房間內的其他客戶端(Client1 和 Client3)有客戶端離開。

  • 房間關閉

Client1(假設是房主)向SignalingServer發(fā)送關閉房間的請求。SignalingServer通知剩余的客戶端(Client3)房間已關閉。

我們看到:這個流程展示了Room模型在WebRTC信令過程中的典型應用:

  • Room作為一個邏輯單元,管理多個參與者之間的通信。
  • SignalingServer負責轉發(fā)所有的信令消息,包括房間管理消息和WebRTC相關的SDP和ICE候選信息。
  • 客戶端可以動態(tài)地加入和離開房間,SignalingServer會及時通知房間內的其他客戶端。
  • 房間可以由創(chuàng)建者(通常是第一個加入的客戶端)來關閉。

由此來看,支持Room模型的信令服務器要支持房間創(chuàng)建、加入房間、轉發(fā)Offer和Answer、離開房間、房間關閉等關鍵API。同時我們也能看出這種模型非常適合于實現(xiàn)多人音視頻通話、在線教室、游戲大廳等應用場景,它提供了一種結構化的方式來管理復雜的多方實時通信。

有了信令服務器,WebRTC通信兩端就可以交換元信息了,這其中就包含用于建立端到端通信的ICE候選信息。接下來,我們就來看看WebRTC端到端建連的關鍵流程:交互式連接建立(ICE, Interactive Connectivity Establishment),以及這個過程中可能發(fā)生的NAT穿透。

3. ICE、NAT穿透與連接最終建立

ICE是一種用于在NAT(網(wǎng)絡地址轉換)環(huán)境中建立對等連接的協(xié)議,它允許兩個agent(在RFC8445[4]中用AgentL和AgentR指代,如下圖)發(fā)現(xiàn)彼此的最佳通信路徑,進而完成端到端的連接。

圖:ICE典型部署場景(from RFC8445)圖:ICE典型部署場景(from RFC8445)

在這個過程中,我們還會涉及兩個概念,一個是STUN(Session Traversal Utilities for NAT)服務器,一個是ICE Candidiate。

STUN服務器是幫助上述agent(AgentL和AgentR)發(fā)現(xiàn)其公網(wǎng)IP地址和端口的服務網(wǎng)元,這對于NAT穿透至關重要。而ICE Candidiate則是agent采集并與對端交換的、可能用于通信的潛在端點地址(IP地址和端口的組合)。

為了更直觀的理解,下面我們來看一下通過ICE選擇最佳通信路徑的一般流程:

圖片圖片

注:上圖由mermaid[5]生成,對應的腳本在webrtc-first-lesson/part2/ice-protocol-sequence.mermaid。

在信令流程發(fā)起和轉發(fā)Offer/Answer之后,兩個端都會開啟ICE最佳通信路徑選擇的流程。

3.1 ICE Candidate Gathering

這第一步就是ICE Candidate Gathering,即收集ICE候選者(端點)信息。

在這個過程中,每個agent收集可能的候選者類型包括如下幾種:

  • 主機候選者(Host Candidate)

主機候選者,即本地接口的地址。通過直接使用本地網(wǎng)絡接口的IP地址和端口即可獲得,比如:192.168.1.2:5000。

  • 反射候選者(Server Reflexive Candidate)

反射候選者是通過STUN服務器查詢公網(wǎng)IP地址和端口獲得的,比如203.0.113.1:6000。

STUN通常是位于公網(wǎng)的一個服務器,比如最知名的公共stun是Google的“stun:stun.l.google.com:19302”。在收集反射候選者時,Agent(客戶端)會向STUN服務器發(fā)送Binding Request(綁定請求),STUN服務器會響應一個Binding Response(綁定響應),其中包含客戶端的公共IP地址和端口信息。

  • 中繼候選者(Relay Candidate)

中繼候選者是通過TURN服務器(Traversal Using Relays around NAT)獲得的端點地址(在上圖中未顯示),是在開啟中繼模式的情況下,由客戶端向TURN服務器發(fā)送請求以獲取中繼地址。只有在WebRTC通信雙方(AgentL和AgentR)無法直連的情況下(通常是NAT穿透失敗導致的),才會使用中繼候選者,并通過TURN服務器進行數(shù)據(jù)中繼來實現(xiàn)兩端的數(shù)據(jù)通信。

注:在本文中,我們暫不考慮中繼模式。

  • 對端反射候選者(Peer Reflexive Candidates)

嚴格來說,對端反射候選者并非是在這個環(huán)節(jié)能獲取到的候選者。對端反射是在ICE連接檢查過程中動態(tài)發(fā)現(xiàn)的候選者,只有在連接檢查過程中才能發(fā)現(xiàn),且不太可預測,取決于網(wǎng)絡拓撲和NAT行為。對比反射候選者,反射后選者是通過STUN服務器發(fā)現(xiàn)的。當一個端點向STUN服務器發(fā)送請求時,STUN服務器會回復該端點在公網(wǎng)上的IP地址和端口。而對端反射候選者是在兩個端點嘗試直接通信時發(fā)現(xiàn)的。當一個端點通過其已知的候選者(如主機候選者或反射候選者)向另一個端點發(fā)送數(shù)據(jù)時,如果成功到達,接收端會發(fā)現(xiàn)一個新的、之前未知的遠程地址。這個新發(fā)現(xiàn)的地址就成為了對端反射候選者。

在ICE候選者信息收集的過程中,兩端的Agent還要通過定期發(fā)送的STUN Binding請求,確保收集到的ICE反射/中繼候選者信息在連接建立期間保持有效。這個過程在RFC 8445中被稱為“Keeping Candidates Alive”,它可以幫助檢測網(wǎng)絡環(huán)境的變化,比如IP地址或端口的變化。通過定期的STUN請求,ICE可以確保候選者在NAT設備中的映射保持活躍,避免因長時間沒有通信而被關閉。

3.2 Candidate Priorization

兩端的Agent在收集完候選者信息后,會通過信令服務器交換他們收集到的候選者信息,這個流程在前面的信令交互流程圖中也是有的,是信令協(xié)議要支持的功能的一部分。

一旦ICE Candidate Gathering以及candidate交換結束,兩端的agent會對自己收集到的candidate以及收到的對端的candidate信息進行"Candidate Priorization",即對自己收集到候選者集合和交換得到的對端候選者集合分別按優(yōu)先級進行排序。

RFC8445中給出推薦的候選者的優(yōu)先級公式如下:

priority = (2^24)*(type preference) +
           (2^8)*(local preference) +
           (2^0)*(256 - component ID)

在公式中有三個名詞:type preference、local preference和component ID。下面分別介紹一下這三個名詞的含義:

  • type preference

Type preference一個表示候選者類型優(yōu)先級的值。不同類型的候選者會被賦予不同的type preference值,以反映它們在ICE過程中的相對重要性。

它的取值范圍通常是0到126之間的整數(shù),值越大,優(yōu)先級越高。 RFC8445中常見候選者類型及其推薦值如下:

主機候選者 (Host candidates): 126
反射候選者 (Server Reflexive candidates): 100
對端反射候選者 (Peer Reflexive candidates): 110
中繼候選者 (Relay candidates): 0

通過不同類型的候選者的推薦值,我們也能看出:主機候選者 > 對端反射候選者 > 反射候選者 > 中繼候選者。

注:Peer Reflexive candidates被賦予比Server Reflexive candidates更高的優(yōu)先級,前面提過,是因為它不是在ICE候選者收集階段就能發(fā)現(xiàn)的,而是在后面的連接檢查階段才能發(fā)現(xiàn),因此可能代表更直接的連接路徑。

  • local preference

local preference是一個表示本地優(yōu)先級的數(shù)值,其取值范圍0~65535。這個值由本地ICE agent根據(jù)自己的策略來設置。

RFC 8421(Guidelines for Multihomed and IPv4/IPv6 Dual-Stack Interactive Connectivity Establishment (ICE))[6]進一步補充了關于local preference的使用建議,特別是在多宿主和雙棧(IPv4/IPv6)環(huán)境下。建議為IPv6候選地址分配比IPv4更高的local preference值,比如:IPv6地址可以分配65535(最高優(yōu)先級),IPv4地址可以分配65535-1=65534(次高優(yōu)先級)。在多宿主(Multihomed)環(huán)境中,可以根據(jù)網(wǎng)絡接口的特性(如帶寬、延遲、成本等)來分配不同的local preference值。

注:多宿主環(huán)境(Multihomed)指的是一個設備或系統(tǒng)通過多個網(wǎng)絡接口連接到網(wǎng)絡的情況。這些接口可以連接到同一個網(wǎng)絡,也可以連接到不同的網(wǎng)絡。多宿主環(huán)境下,每個網(wǎng)絡接口都可能產(chǎn)生多個ICE候選者,需要為不同接口的候選者分配合適的優(yōu)先級,可能需要考慮不同網(wǎng)絡接口的特性(如帶寬、延遲、成本)。

  • Component ID

Component ID用于區(qū)分同一媒體流中的不同組件。在ICE中,一個媒體流可能包含多個組件,例如RTP和RTCP。Component ID通常是從1開始的連續(xù)整數(shù)。在公式中使用(256 - component ID)是為了確保值較小的component ID得到較高的優(yōu)先級。RTP組件通常被賦值為1,RTCP組件(如果存在)通常被賦值為2。Component ID在優(yōu)先級計算中的作用相對較小,主要用于在其他因素相同的情況下,為同一流的不同組件提供細微的優(yōu)先級區(qū)分。

下面我們用一個示例來演示一下候選者計算優(yōu)先級的過程。示例將展示一個ICE agent如何計算自己的candidates和對端candidates的優(yōu)先級。我們假設這是一個音頻流的情況,涉及RTP組件。假設我們有兩個agent:AgentL和AgentR,我們將關注AgentL的視角。

AgentL的收集的候選者集合如下:

Host candidate (IPv4): 192.168.1.10:50000
Server Reflexive candidate: 203.0.113.5:50000
Relay candidate: 198.51.100.1:50000

AgentL通過信令交換獲得的AgentR的候選者集合如下:

Host candidate (IPv6): 2001:db8::1:5000
Host candidate (IPv4): 192.168.2.20:5000
Server Reflexive candidate: 203.0.113.10:5000

上面優(yōu)先級計算公式中各個參數(shù)值選擇如下:

Type preferences:

- Host: 126
- Server Reflexive: 100
- Relay: 0

Local preferences:

- IPv6: 65535
- IPv4: 65534

Component ID: 1 (RTP)

下面是AgentL的候選者優(yōu)先級的計算過程:

- Host (IPv4): (2^24) * 126 + (2^8) * 65534 + (256 - 1) = 658871
- Server Reflexive: (2^24) * 100 + (2^8) * 65534 + (256 - 1) = 658195
- Relay: (2^24) * 0 + (2^8) * 65534 + (256 - 1) = 655595

AgentR的候選者優(yōu)先級(從AgentL的角度計算)計算過程:

- Host (IPv6): (2^24) * 126 + (2^8) * 65535 + (256 - 1) = 658881
- Host (IPv4): (2^24) * 126 + (2^8) * 65534 + (256 - 1) = 658871
- Server Reflexive: (2^24) * 100 + (2^8) * 65534 + (256 - 1) = 658195

最終優(yōu)先級排序(從高到低):

AgentR: Host (IPv6) - 658881
AgentR: Host (IPv4) - 658871
AgentL: Host (IPv4) - 658871
AgentR: Server Reflexive - 658195
AgentL: Server Reflexive - 658195
AgentL: Relay - 655595

這個優(yōu)先級排序將用于指導下一階段的ICE連接檢查(ICE Connectivity Checks)順序,但最終的連接選擇還會考慮連接檢查的結果。在實際場景中,可能會有更多的候選者,包括不同網(wǎng)絡接口的多個Host候選者等等。

3.3 ICE Connectivity Checks

有了兩端的候選者集合以及優(yōu)先級值后,兩個Agent就可以進入下一階段ICE Connectivity Checks(連接檢查)了。

連接檢查實際也可以劃分為三個階段,我們逐一來看一下。

3.3.1 確定角色(Determining Role)

在 WebRTC 的 ICE(Interactive Connectivity Establishment)連接過程中,角色的確定對于連接檢查非常重要。ICE 的角色分為兩種:控制方(Controlling)和被控方(Controlled)。這些角色用于決定在多個候選路徑中選擇哪一條作為最終的連接路徑。控制方(Controlling Agent) 負責最終選擇使用哪個候選對進行通信,而受控方(Controlled Agent)則需遵循控制方的決定。

在offer/answer的信令模型中,通常發(fā)起offer的一方會被指定為控制方,而應答(answer)的一方會成為受控方。有時可能會出現(xiàn)兩個agents都認為自己是控制方的情況。ICE提供了解決這種沖突的機制:每個agent生成一個隨機數(shù)(稱為tie-breaker),當發(fā)現(xiàn)沖突時,比較tie-breaker,tie-breaker較大的agent成為控制方。

ICE(Interactive Connectivity Establishment)連接檢查是由控制方和被控方的兩個ICE agent同時進行的。兩者會各自發(fā)起連接檢查,以確保雙方能夠建立有效的連接??刂品酵ㄟ^在檢查中包含USE-CANDIDATE屬性來提名(Nomination)候選對。

在某些情況下,角色可能會在ICE過程中切換,比如如果發(fā)現(xiàn)角色沖突并解決沖突后,又比如在ICE重啟(restart)的特定場景下。

3.3.2 形成檢查列表(Forming checklist)

通信的雙方,無論是控制端還是被控端都會獨立形成自己的檢查列表。

檢查列表是所有可能的候選者對(Candidate Pair)的組合。讓我們結合上面的示例,詳細說明這個過程。

在我們的例子中,以AgentL為例,每個本地候選與每個遠程候選會形成一對,這里會形成9個候選者對:

(L-Host, R-Host-IPv6)
(L-Host, R-Host-IPv4)
(L-Host, R-Server-Reflexive)
(L-Server-Reflexive, R-Host-IPv6)
(L-Server-Reflexive, R-Host-IPv4)
(L-Server-Reflexive, R-Server-Reflexive)
(L-Relay, R-Host-IPv6)
(L-Relay, R-Host-IPv4)
(L-Relay, R-Server-Reflexive)

根據(jù)之前計算的優(yōu)先級,對候選對對優(yōu)先級進行計算,并按從高到底進行排序。RFC8445中給出了候選者對優(yōu)先級計算的公式:

// Let G be the priority for the candidate provided by the controlling agent.
// Let D be the priority for the candidate provided by the controlled agent. 
pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)

具體的計算過程這里就不體現(xiàn)了,排序后的檢查列表可能如下:

(L-Host, R-Host-IPv6)
(L-Host, R-Host-IPv4)
(L-Server-Reflexive, R-Host-IPv6)
(L-Server-Reflexive, R-Host-IPv4)
(L-Host, R-Server-Reflexive)
(L-Server-Reflexive, R-Server-Reflexive)
(L-Relay, R-Host-IPv6)
(L-Relay, R-Host-IPv4)
(L-Relay, R-Server-Reflexive)

AgentR(被控方) 也會形成自己的檢查列表,與AgentL類似,但AgentR并不主動選擇最終的路徑。

有了排序后的候選者對后,我們接下來便可以執(zhí)行連接檢查了,AgentL和AgentR會各自執(zhí)行自己的檢查。

3.3.3 執(zhí)行連接檢查(Performing Connectivity Checks)

我們以AgentL為例,看看執(zhí)行連接檢查的主要步驟。

AgentL開始按照檢查列表的順序(優(yōu)先級由高到低)發(fā)送STUN Binding請求:

  • AgentL向R-Host-IPv6發(fā)送STUN Binding請求;
  • 如果第一個檢查失敗或超時,AgentL會繼續(xù)向第二個候選者對的R-Host-IPv4發(fā)送STUN Binding請求;
  • 如果失敗,繼續(xù)下一個候選對...,依次類推

同時,AgentR也會執(zhí)行類似的過程,按照他自己的檢查列表發(fā)送自己的STUN Binding請求。

當AgentL收到STUN Binding響應時,可能有以下幾種可能:

  • 如果是成功的響應,這個候選對被標記為有效。
  • 如果響應來自一個未知地址,創(chuàng)建一個新的Peer Reflexive候選。

之后,AgentL便會更新候選列表,將新候選與所有遠程候選配對,形成新的候選對,并根據(jù)ICE優(yōu)先級算法重新排序檢查和更新檢查列表。AgentL還可能對新形成的候選對立即開始連接性檢查。

3.3.4 NAT穿透與最終候選路徑的形成

如果兩端都在NAT后面,那么Peer Reflexive候選者就是NAT穿透的關鍵!我們結合下圖詳細說說ICE過程是如何一步步的選出由新發(fā)現(xiàn)的Peer Reflexive組成的最終候選路徑的。

圖片圖片

注:上圖由mermaid[7]生成,對應的腳本在webrtc-first-lesson/part2/ice-nat-traversal-sequence.mermaid

圖中使用A、B作為兩個端點,通過stun服務器獲取的反射候選為A'和B',通過連接檢查階段發(fā)現(xiàn)的對端反射候選(Peer Reflexive)分別為A''和B''。接下來,我們詳細說明一下圖中流程。

  • ICE候選收集階段

端點A和B都收集主機候選。A和B都通過各自的NAT向STUN服務器發(fā)送請求,獲取服務器反射候選(A'和B')。

  • 候選交換

A和B交換各自的候選列表,包括主機候選和反射候選(A'和B')。

  • 連接檢查開始

A向B的反射候選B'發(fā)送STUN綁定請求,這個請求經(jīng)過A的NAT和B的NAT。

B收到請求后,發(fā)現(xiàn)源地址(A'')與A提供的候選(A')不匹配,因此創(chuàng)建一個新的Peer Reflexive候選A''。

B通過NAT鏈回復STUN綁定響應。

A收到響應后,從響應中的XOR-MAPPED-ADDRESS字段獲知并創(chuàng)建自己的Peer Reflexive候選A''。

注:STUN協(xié)議中的XOR-MAPPED-ADDRESS字段可用于幫助對等方(peer)在ICE連接檢查階段找到自己的Peer Reflexive地址。

  • B也向A發(fā)送STUN綁定請求

類似的過程在反向發(fā)生。A創(chuàng)建B的Peer Reflexive候選B''。B從A的響應中獲知并創(chuàng)建自己的Peer Reflexive候選B''。

  • 更新候選對和繼續(xù)檢查

A和B都更新各自的檢查列表,包括新的(A'', B'')對。

  • 選擇最佳路徑

最終,(A'', B'')被選為最佳路徑,實現(xiàn)雙向NAT穿透。

一旦選定了最佳候選者對,ICE過程就結束了,可以開始實際的數(shù)據(jù)傳輸。

3.4 ICE重啟

最后我們簡單說說ICE重啟(restart)。ICE restart提供了一種在不中斷現(xiàn)有應用會話的情況下重新建立和優(yōu)化網(wǎng)絡連接的機制。這通常是因為網(wǎng)絡條件發(fā)生了變化或者需要切換到更優(yōu)的連接路徑。下面序列圖展示了ICE重啟的基本流程:

圖片圖片

注:上圖由mermaid[8]生成,對應的腳本在webrtc-first-lesson/part2/ice-restart-sequence.mermaid

ICE restart可能由多種原因觸發(fā),如網(wǎng)絡變化、切換到更優(yōu)路徑、或解決連接問題。任何一方都可以發(fā)起ICE restart。

和前面的ICE流程不同之處在于重啟時,發(fā)起restart的一方會生成新的ICE ufrag和password。這些新的憑證用于區(qū)分新的ICE會話和舊的會話。

之后的流程就和正常的ICE交互選出最優(yōu)通信路徑?jīng)]有太大區(qū)別了!這里也就不重復說明了。

注:ICE restart不一定會改變控制方(controlling)和受控方(controlled)的角色。通常情況下,原有的角色分配會被保持。

4. 小結

在這篇文章中,我們深入探討了WebRTC連接建立的全流程,涵蓋了以下關鍵概念:

  • 信令:我們討論了信令的重要性,并了解了基于Room抽象的常見的信令服務器模型;
  • ICE框架:我們學習了ICE候選信息的收集、交換以及連接檢查;
  • NAT穿透:我們在ICE連接檢查過程中,詳細說明了ICE是如何實現(xiàn)NAT穿透并選出最終最優(yōu)的通信路徑的。

在實際生產(chǎn)應用中,我們可能還需要考慮以下幾點:

  • 連接建立優(yōu)化:可以通過使用ICE Lite、預先收集候選信息等方式來加速連接建立過程。
  • 安全性考慮:在生產(chǎn)環(huán)境中,應該使用HTTPS和WSS來保護信令通道。
  • 錯誤處理和重連:實際應用中需要處理各種可能的錯誤情況,并實現(xiàn)自動重連機制。

在接下來的系列文章中,我將用一個相對完整的演示示例來展示W(wǎng)ebRTC應用端到端建連的所有細節(jié)(通過TRACE級別日志),希望通過這些細節(jié)的分析能幫助大家更好地理解WebRTC的建連過程。

本文涉及的Mermaid源碼在這里[9]可以下載到 - https://github.com/bigwhite/experiments/blob/master/webrtc-first-lesson/part2

5. 參考資料

  • WebRTC 1.0: Real-time Communication Between Browsers[10] - https://www.w3.org/TR/webrtc/
  • Interactive Connectivity Establishment (ICE)[11] - https://tools.ietf.org/html/rfc8445
  • Session Traversal Utilities for NAT (STUN)[12] - https://tools.ietf.org/html/rfc8489
  • Traversal Using Relays around NAT (TURN)[13] - https://tools.ietf.org/html/rfc8656

參考資料

[1] mermaid: https://mermaid.live/

[2] mermaid: https://mermaid.live/

[3] 使用Go和WebRTC data channel實現(xiàn)端到端實時通信: https://tonybai.com/2023/09/23/p2p-rtc-implementation-with-go-and-webrtc-data-channel

[4] RFC8445: https://www.rfc-editor.org/rfc/rfc8445

[5] mermaid: https://mermaid.live/

[6] RFC 8421(Guidelines for Multihomed and IPv4/IPv6 Dual-Stack Interactive Connectivity Establishment (ICE)): https://www.rfc-editor.org/rfc/rfc8421

[7] mermaid: https://mermaid.live/

[8] mermaid: https://mermaid.live/

[9] 這里: https://github.com/bigwhite/experiments/blob/master/webrtc-first-lesson/part2

[10] WebRTC 1.0: Real-time Communication Between Browsers: https://www.w3.org/TR/webrtc/

[11] Interactive Connectivity Establishment (ICE): https://tools.ietf.org/html/rfc8445

[12] Session Traversal Utilities for NAT (STUN): https://tools.ietf.org/html/rfc8489

[13] Traversal Using Relays around NAT (TURN): https://tools.ietf.org/html/rfc8656

責任編輯:武曉燕 來源: TonyBai
相關推薦

2024-06-17 09:00:08

2019-08-19 01:11:39

NAT網(wǎng)絡地址轉換內網(wǎng)

2024-12-05 10:42:51

網(wǎng)絡架構NAT

2025-03-14 08:29:49

2016-08-04 15:18:51

2021-03-17 09:51:31

網(wǎng)絡編程TCP網(wǎng)絡協(xié)議

2024-11-01 12:39:04

2019-09-28 23:30:23

信令5G無線網(wǎng)絡

2024-06-27 11:08:45

2012-11-19 13:06:56

2024-04-22 08:06:34

Rust語言

2013-02-21 15:16:58

路由器VOIPNAT穿透方式

2017-07-18 09:59:28

NATHTTP Server方式

2014-09-24 09:59:23

微信企業(yè)號開發(fā)

2025-04-22 02:00:00

芯片晶圓光刻機

2021-10-19 10:52:06

Serverless阿里云

2024-06-07 08:59:35

2025-01-13 08:09:51

Nginx管理工具DevOps

2011-12-16 14:44:55

云計算云安全
點贊
收藏

51CTO技術棧公眾號