天天看點

WebRTC ICE 狀态與提名處理SceneCandidate's FoundationICE StatesICE Nomination1.Regular Nomination2.Aggressive nominationUpdating States When NominationScheduling ChecksCase Analyzed

作者:陣圖

審校:泰一

來源:

WebRTC ICE 狀态與提名處理

Scene

分析一個問題時候遇到這樣的場景:服務端一個 Candidate,用戶端三個不同優先級的 Candidate,但是最後居然選擇了一個優先級最低的 Pair。

服務端有一個 Relay Candidate,端口 50217。

a=candidate:3 1 udp 503316991 11.135.171.187 50217 typ relay raddr 10.101.107.25 rport 40821           

用戶端有三個 Candidate,端口 50218(中間優先級),50219(最低優先級),50220(最高優先級)。

Candidate 1:
candidate:592388294 1 udp 47563391 11.135.171.187 50219 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag fO75 network-cost 50

Candidate 2:
candidate:592388294 1 udp 48562623 11.135.171.187 50218 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag fO75 network-cost 50

Candidate 3:
candidate:592388294 1 udp 49562879 11.135.171.187 50220 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag fO75 network-cost 50           

但是最後選擇的卻是最低優先級的 Pair,50219。

Remote selected pair: 1:1 592388294 UDP 11.135.171.187:50219 RELAYED

Candidate's Foundation

Candidate 的 Foundation: 這裡先提一下 Foundation,會涉及到 Frozen 狀态。

對于一條相同的信道,可能有不同的 Candidate,比如 Relay Candidate 被發現的時候,就可以生成一個新的 Server Reflexive 類型的 Candidate,但是他們都是基于相同的本地位址(IP,端口)和協定,則可以認為這些網絡是相似的,則他們就會有相同的 Foundation。其中 Foundation 在 SDP 中為第一個字段,即下面例子中的 '7'。

a=candidate:7 1 udp 503316991 11.178.68.36 51571 typ relay raddr 30.40.198.7 rport 55896           

ICE States

ICE 主要有以下五種狀态,其中前四種是正常的狀态,第五種狀态 Frozen 涉及到

ICE Frozen Algorithm

ICE 的五種狀态:

  • Waiting: 當連通性檢查還沒有開始執行的時候(Binding Request 還沒發送)。
  • In Progress: 當連通性檢查發送了,但是相應檢查的事務仍在執行中(Binding Request 已發送)。
  • Successed: 連通性檢查執行完成且傳回結果成功(Binding Request 已完成)。
  • Failed: 連通性檢查執行完成且結果失敗(Binding Request 已完成)。
  • Frozen: ,所有 Candidate Pair 初始化完成以後就在這個狀态,對于相同的 Foundation(相似的 Candidate),會按照優先級依次選取一個 Pair,Unfreeze,并設定為 Waiting 狀态,其他則保持 Frozen。直到選取的 Pair 完成,才會繼續 Unfreeze 另一個 Pair。

ICE Nomination

ICE 有兩種提名方式:

1.Regular Nomination

對于正常提名,主要工作流程如下:

L                        R
-                        -
STUN request ->             \  L's
<- STUN response  /  check

<- STUN request  \  R's
STUN response ->            /  check

STUN request + flag ->      \  L's
<- STUN response  /  check

Regular Nomination           

Controlling 模式下的 Agent 發起 Binding Request,并且收到對端的 Response,同時對端發起的 Connective Check 完成,Controling 一端會再次發出一個攜帶 USE_CANDIDATE 标志位的 Binding Request,當 Controlled 一端收到了,就接受這次提名。

2.Aggressive nomination

除了正常提名,還有一種比較激進的提名,正常提名中會新增一次握手。

L                        R
-                        -
STUN request + flag ->      \  L's

<- STUN response  /  check
<- STUN request  \  R's
STUN response ->            /  check

Figure 5: Aggressive Nomination           

Controlling 模式下的 Agent 發起 Binding Request,但是在這個 Binding Request 中會直接攜帶 USE_CANDIDATE 的标志位,Controlled 模式下的 Agent 收到了以後就接受這次提名。在激進提名模式下,能節約一次握手過程,但是當多個 Pair 同時接受提名時,會根據這些 Pair 各自的優先級進行選擇,選擇出優先級最高的 Pair 作為實際的信道。

真實案例:

WebRTC ICE 狀态與提名處理SceneCandidate's FoundationICE StatesICE Nomination1.Regular Nomination2.Aggressive nominationUpdating States When NominationScheduling ChecksCase Analyzed

Updating States When Nomination

原文參考

當一個新的提名産生時,會對 ICE 内部狀态進行對應的變化。

當一端的 Binding Request 攜帶了 Use Candidate 的标志位時,則會産生一次提名(Nomination)。

不管 Controlling 或者 Controlled 模式下的 Agent,處理提名的狀态更新規則建議如下:

  • 如果沒有提名的 Pair,則繼續進行連通性檢查的過程。
  • 如果至少有一個有效的提名:
    • Agent 必須删除該 Component 下的所有 Waiting 狀态和 Frozen 狀态的 Pair。
    • 對于 In Progress 狀态下的 Pair,優先級低于目前提名 Pair 優先級的,停止重傳(取消)。
  • 當某一個 Stream 的所有 Compont 都至少擁有一個提名時,且檢查仍然在進行時:
    • Agent 必須将該 Stream 标記為已完成。
    • Agent 可以開始傳輸媒體流。
    • Agent 必須持續響應收到的消息。
    • Agent 必須重傳目前仍然在 In Progress 的 Pair(優先級高于目前提名的,不然已經被删除或者取消)。
  • 當檢查清單中的所有 Pair 都完成時:
    • ICE 完成。
    • Controlling Agent 根據優先級更新 Offer(貌似 WebRTC 沒有這一步)。
  • 當檢查清單檢查有失敗時:
    • 所有 Pair 都失敗時,關閉 ICE。
    • 當有某個流的檢查成功時,Controlling Agent 移出失敗的 Pair,并更新 Offer。
    • 如果有些檢查沒有完成,則 ICE 繼續。

Scheduling Checks

在描述提名時,還會涉及 ICE 對 Pair 的排程(當有效 Candidate 還在 In Progress 的時候但是其他 Candidate 的 Pair 已經收到 Binding Request)。

這裡隻讨論 Full,先不描述 Lite 模式。

ICE 的 Checks 分成兩種,Ordinary Checks And Triggered Checks。

  • Ordinary Checks 是正常的 Pair 的檢查,表示這些 Pair 的檢查是從正常流程中切換過來的狀态的檢查。
  • Triggered Check 是被動觸發的檢查,當這些 Pair 雖然還處在不可以開始檢查的狀态,但是這時候收到了對端的連通性檢查,這時候會對這個 Pair 進行提速,将其直接放入排程清單。

當 ICE 建立一個 Check List (每個 Stream 一個)後,會對每個 Check List 添加一個定時器,當定時器到來時,會進行如下排程:

注:這裡有點不能了解,整個流程看起來是串行的,激活速度有點慢。

  • 首先排程 Triggered Check 并執行。
  • 若無,排程優先級最高的 Waiting 狀态的 Pair,發送 Request,同時将狀态置為 In Progress。
  • 若無,則從 Check List 中找出優先級最高的 Frozen 狀态的 Pair,Unfreeze 之,并發送 Request,狀态設定為 In Progress。
  • 若無,終止排程。

Case Analyzed

簡單了解了 ICE 的流程後,我們回歸最開始的 Case。

首先看 Add Candidate,三個 Remote Candidate 添加順序不同,依次為 50219,50218,50220,注意,此時 50219 收到了對端的 Binding Request,激進提名,攜帶 USE_CANDIDATE,是以很快執行 Create Permission 并完成,這時候可以開始發送 Binding Request 了,屬于 Triggered Checks 優先排程,發送 Binding Request,并進入 In Progress 狀态。

注:這裡除了本地 Relay 的 Pair,還有和 Turn 通信的本地 Host 類型的 Candidate。

WebRTC ICE 狀态與提名處理SceneCandidate's FoundationICE StatesICE Nomination1.Regular Nomination2.Aggressive nominationUpdating States When NominationScheduling ChecksCase Analyzed

接着在 50219 在其他兩個 Create Permission 還沒完成時候以迅雷不及掩耳之勢完成了 Check,根據 rfc 8.1.2 中的描述,對于不是在 In Progress 狀态的 Pair,都删除,并不參考其優先級,故最後選擇了 50219 這個優先級最低的 Pair。

WebRTC ICE 狀态與提名處理SceneCandidate's FoundationICE StatesICE Nomination1.Regular Nomination2.Aggressive nominationUpdating States When NominationScheduling ChecksCase Analyzed
「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。
WebRTC ICE 狀态與提名處理SceneCandidate's FoundationICE StatesICE Nomination1.Regular Nomination2.Aggressive nominationUpdating States When NominationScheduling ChecksCase Analyzed