WebRTC 會話的生命週期

WebRTC 允許您將任意資料、音訊或影片(或它們的任意組合)的點對點通訊整合到瀏覽器應用程式中。在本文中,我們將探討 WebRTC 會話的生命週期,從建立連線到在不再需要時關閉連線。

本文不深入介紹建立和處理 WebRTC 連線所涉及的實際 API 細節;它概述了通用流程,並提供了一些關於為什麼需要每個步驟的資訊。有關實際示例和程式碼功能的分步說明,請參閱 信令與視訊通話

注意: 此頁面目前正在建設中,隨著 WebRTC 指南材料的構建,部分內容將移至其他頁面。敬請諒解!

建立連線

網際網路很大。非常大。它如此之大,以至於多年前,聰明人看到了它的規模、它的快速增長,以及 32 位 IP 地址系統的侷限性,並意識到必須採取措施,在我們用完地址之前,所以他們開始設計一個新的 64 位地址系統。但他們意識到,完成過渡所需的時間將比 32 位地址的壽命長,因此其他聰明人想出了一種方法,讓多個計算機共享同一個 32 位 IP 地址。網路地址轉換(NAT)是一種透過處理進出區域網裝置的資料路由來支援此地址共享的標準,這些裝置都共享一個 WAN(全域性)IP 地址。

使用者面臨的問題是,網際網路上的每個單獨計算機不再必然擁有唯一的 IP 地址,事實上,每個裝置的 IP 地址不僅可能在它們從一個網路移動到另一個網路時發生變化,而且如果它們的網路地址被NAT 和/或 DHCP 更改,也會發生變化。對於試圖進行點對點網路開發的開發者來說,這引入了一個難題:沒有每個使用者裝置的唯一識別符號,就無法即時自動地知道如何在網際網路上連線到特定裝置。即使您知道您想與誰交談,您也不一定知道如何聯絡他們,甚至不知道他們的地址是什麼。

這就好比您想給朋友 Michelle 寄包裹,但只寫著“Michelle”就把它扔進郵箱,而您不知道她的地址。您需要查詢她的地址並將其寫在包裹上,否則她會想知道為什麼您又忘了她的生日。

這就是信令的作用所在。

信令

信令是兩個裝置之間傳送控制資訊的處理過程,以確定通訊協議、通道、媒體編解碼器和格式、資料傳輸方法以及任何必需的路由資訊。關於 WebRTC 信令過程最重要的一點是:它沒有在規範中定義

您可能會想,為什麼建立 WebRTC 連線的基本過程之一會遺漏在規範之外?答案很簡單:由於兩個裝置之間沒有直接聯絡的方式,而且規範無法預測 WebRTC 的所有可能用例,因此讓開發人員選擇合適的網路技術和訊息協議更有意義。

特別是,如果開發人員已經有一種連線兩個裝置的方法,那麼為 WebRTC 強制使用另一種由規範定義的連線方式就沒有意義了。由於 WebRTC 並非孤立存在,很可能還有其他連線方式在起作用,因此如果可以使用現有通道,則避免為信令新增額外的連線通道是有意義的。

為了交換信令資訊,您可以選擇透過 WebSocket 連線來回傳送 JSON 物件,或者可以使用 XMPP 或 SIP 透過合適的通道,或者可以使用 fetch()HTTPS 進行輪詢,或者您能想到的任何其他技術組合。您甚至可以使用電子郵件作為信令通道。

另外值得注意的是,用於執行信令的通道甚至不需要透過網路。一個對等方可以輸出一個數據物件,該物件可以被打印出來,物理攜帶(步行或透過信鴿)到另一個裝置,然後輸入到該裝置,接著該裝置輸出一個響應,然後步行返回,如此迴圈,直到 WebRTC 對等連線開啟。這將有很高的延遲,但理論上是可行的。

信令過程中交換的資訊

在信令過程中需要交換三種基本型別的資訊:

  • 用於設定、開啟和關閉通訊通道以及處理錯誤的控制訊息。
  • 設定連線所需的資訊:對等方能夠相互通訊所需的 IP 地址和埠資訊。
  • 媒體能力協商:對等方能夠理解哪些編解碼器和媒體資料格式?在 WebRTC 會話開始之前需要就這些達成一致。

只有在信令成功完成後,才能開始開啟 WebRTC 對等連線的實際過程。

值得注意的是,信令伺服器實際上不需要理解或處理兩個對等方在信令過程中透過它交換的資料。信令伺服器本質上是一箇中繼:一個雙方連線的共同點,它們知道它們的信令資料可以透過它傳輸。伺服器不需要以任何方式響應此資訊。

信令過程

為了開始 WebRTC 會話,必須按順序執行一系列操作:

  1. 每個對等方建立一個 RTCPeerConnection 物件,代表其在 WebRTC 會話中的一端。
  2. 每個對等方為 icecandidate 事件建立一個處理程式,該處理程式負責透過信令通道將這些候選者傳送到另一個對等方。
  3. 每個對等方為 track 事件建立一個處理程式,當遠端對等方將軌道新增到流時會收到該事件。此程式碼應將軌道連線到其使用者,例如 <video> 元素。
  4. 呼叫者建立一種識別符號或令牌,並與接收方對等方共享,以便信令伺服器上的程式碼可以識別它們之間的通話。此識別符號的確切內容和形式由您決定。
  5. 每個對等方連線到一個約定好的信令伺服器,例如它們都知道如何與之交換訊息的 WebSocket 伺服器。
  6. 每個對等方告知信令伺服器它們想加入同一個 WebRTC 會話(透過步驟 4 中建立的令牌標識)。
  7. 描述、候選者等 — 更多內容即將釋出

ICE 重啟

有時,在 WebRTC 會話的生命週期中,網路條件會發生變化。例如,一個使用者可能從蜂窩網路切換到 Wi-Fi 網路,或者網路可能變得擁塞。當這種情況發生時,ICE 代理可能會選擇執行ICE 重啟。這是一個重新協商網路連線的過程,與初始 ICE 協商的方式完全相同,只有一個例外:媒體在新的網路連線啟動並執行時繼續透過原始網路連線傳輸。然後,媒體切換到新的網路連線,舊的連線被關閉。

注意: 不同的瀏覽器在不同的條件下支援 ICE 重啟。例如,並非所有瀏覽器都會因網路擁塞而執行 ICE 重啟。

下面對 failed ICE 連線狀態的處理程式展示瞭如何重啟連線。

js
pc.oniceconnectionstatechange = () => {
  if (pc.iceConnectionState === "failed") {
    pc.setConfiguration(restartConfig);
    pc.restartIce();
  }
};

程式碼首先使用更新後的配置物件呼叫 RTCPeerConnection.setConfiguration()。如果需要以某種方式更改連線配置(例如更改為不同的 ICE 伺服器集),則應在重啟 ICE 之前完成此操作。

然後,處理程式呼叫 RTCPeerConnection.restartIce()。這會告訴 ICE 層在下一次 createOffer() 呼叫中自動新增 iceRestart 標誌,從而觸發 ICE 重啟。它還會為 ICE 使用者名稱片段(ufrag)和密碼生成新值,這些值將用於重新協商過程和由此產生的連線。

當檢測到 ICE ufrag 和 ICE 密碼的新值時,連線的應答方將自動開始 ICE 重啟。