WebRTC成為HTML5標準?SDP、STUN、TURN你想知道的都在這裡!

web前端分享 發佈 2022-12-16T21:26:20.306175+00:00

大家好,很高興又見面了,我是"web 前端分享",由我帶著大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點讚、收藏、轉發!上一篇文章《WebRTC已成為HTML5標準?是時候開始學習了?

大家好,很高興又見面了,我是"web 前端分享",由我帶著大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點讚、收藏、轉發!

上一篇文章《WebRTC已成為HTML5標準?是時候開始學習了?》發布後反響不錯,特定再出一文詳細論述WebRTC、SDP、STUN、TURN等諸多內容,創作不易,拒絕轉發到其他平台,萬望理解!

1.前言

1.1 什麼是 WebRTC?

下圖展示了不同協議出現的時間線:

在計算機網絡中,協議是一組規則,用於管理數據在設備之間的交換方式。 協議定義了通信的規則、語法、語義和同步以及可能的錯誤恢復方法,本文中討論的 WebRTC 協議定義了應用層軟體如何相互交互。

WebRTC(Web Real-Time Communication)也被稱為網絡實時通信,是由 Google、Mozilla 和其他公司推動的一個開源項目,它通過 Javascript API 實現無插件的實時通信,建立瀏覽器之間點對點(Peer-to-Peer)的連接。

1.2 WebRTC 的優點?

WebRTC 的優點可以歸納為以下幾個方面:

  • 開源、免費,開發者不需要承擔高昂的專利費用
  • 基於瀏覽器,不需要安裝插件,只要調用 API 就可以實現音視頻互動
  • 被納入了 HTML5 標準,主流瀏覽器全面支持 WebRTC
  • 不僅支持 Web 之間的音視頻通訊,還支持 Android 以及 IOS 端,由於該項目是開源的,我們也可以通過編譯 C++代碼,從而達到全平台的互通

在 WebRTC 誕生之前,開發實時音視頻應用的成本是非常高,需要考慮的技術問題很多,如音視頻的編解碼,數據傳輸延時、丟包、網絡抖動、回音處理和消除等,如果要兼容瀏覽器端的實時音視頻通信,還需要額外安裝插件。可喜的是,本文的主角 WebRTC 在 2021 年 1 月被 W3C 和 IETF 發布為正式標準,而且得到了大多數主流瀏覽器的支持。

WebRTC 項目的願景:實時通信 web 化,讓 WebRTC 成為網際網路音視頻實時通信的規範,讓開發者基於此規範快速開發出安全、可靠的應用。WebRTC 必須在 HTTPS 環境下運行,你可以在https://appr.tc/、https://snapdrop.net/體驗WebRTC應用,或者在https://nashaofu.github.io/webrtc-demo/,https://webrtc.github.io/samples/查看WebRTC示例。

2.了解SDP和Offer-Answer模型

2.1 什麼是Rtp/Rtcp?

大多數人已經了解 TCP 和 UDP 等傳輸協議,當您要保證傳輸數據準確(例如:郵件)時,TCP 協議更好,而 UDP則更加偏向傳輸速度(例如:YouTube 視頻)。

實時傳輸協議 (Real-time Transport Protocol,RTP) 又是一種用於通過 IP 網絡傳送音頻和視頻的網絡協議。 RTP 廣泛用於涉及流媒體的通信和娛樂系統,例如電話、視頻電話會議、電視服務等。 作為一種電信標準,WebRTC 正在使用 RTP 傳輸實時數據。

RTP 控制協議 (RTP Control Protocol ,即RTCP) 是實時傳輸協議 (RTP) 的兄弟協議。 RTCP 為 RTP 會話提供額外統計和控制信息。 使用 RTCP您可以獲得有關數據傳輸成功的數據,例如「傳輸過程中發生了多少數據包丟失」、「數據包延遲是多少」或「視頻通話的解析度是多少」等等。

RTP 和 RTCP 數據包的傳輸發生在媒體通道上,而WebRTC 負責媒體通道上的媒體傳輸。作為應用程式開發人員,您的責任是管理信令通道。 所以你通常不知道這些概念,而且大多數時候你不需要它們,但在開始 SDP 和 Offer-Answer 模型之前有必要先了解下 RTP/RTCP 。

2.2 什麼是SDP(session Description Protocol)?

現實生活中,如果您想讓人們聯繫到您,您會分享您的聯繫信息,比如電子郵件、電話號碼、Instagram 帳戶、家庭住址等。 分享此類信息的最簡單方法是向他們提供您的名片,而為了能夠找到對方, 網際網路數字名片可能包含以下信息:

  • 主叫方和被叫方IP 地址
  • 支持哪些媒體類型(音頻、視頻、屏幕共享等)
  • 當前啟用或禁用了哪些媒體類型(視頻開/關保持/取消保持等)
  • 對方都支持哪些編解碼器類型

在電信領域,稱這種數字名片為會話描述協議 (SDP), SDP 包含對等點相互交談所需的信息。WebRTC 也使用 SDP 作為通信標準來發起呼叫, SDP 只是一個可以被端點解析和操作的文本。

例如,如果用戶想要保持通話,您可以通過將 SDP 作為應用程式進行操作來禁用/啟用視頻和音頻流。 或者您的系統需要特定的視頻編解碼器,比方說 H.264,您可以刪除除 H.264 之外的任何其他編解碼器。

這就是 SDP 的強大之處,它很容易根據您的要求進行操作

下面是一個 SDP 示例,可能包含以下信息:

o=alice 2890844526 2890844526 IN IP4 10.48.1.2
//O=表示呼叫的發起者、會話ID和發起者的IP位址
t=0 0
//t= 表示會話結束時間。如果為 0,則表示會話不受時間限制
m=audio 49170 UDP/TLS/RTP/SAVPF 111 0
// m=表示media line,是session中可以存在的媒體屬性。 在這種情況下,它表示音頻媒體線。 此行還包含將在會話中使用的傳輸協議 (UDP/TLS/RTP/SAVPF)。 最後,此行包含將在會話中使用的編解碼器有效載荷編號 (111, 0)
c=IN IP4 217.345.789.123
// c=表示連接信息,比如你要調用的遠程設備的IP位址
a=sendrecv
a=rtpmap:111 Opus/48000/2
a=rtpmap:0 PCMU/8000
//a= 表示屬性線。 它定義會話和媒體行屬性。 在第一行中,a=sendrcv 屬性表示設備願意發送和接收音頻媒體,他還 可以有其他值,如 recvonly、sendonly 或 inactive用於不同的場景,如保持或視頻關閉
// Rtpmap 屬性指示音頻編解碼器編號的映射。 在這種情況下,111 映射到具有 48,000 bps 帶寬的 Opus,而 0 映射到具有 8,000 bps 帶寬的 PCMU 編解碼器, 標準 SDP 中可以有更多的屬性行。
m=video 51372 UDP/TLS/RTP/SAVPF 98 100
//m= 也表示媒體行,在這種情況下,它表示視頻媒體線。同樣,它包含傳輸協議和編解碼器有效負載編號。
a=sendrecv
a=rtpmap:98 VP9/90000
a=rtpmap:100 H264/90000
//a= 表示屬性行。 在第一行中,a=sendrcv 屬性表示設備願意發送和接收視頻媒體
//rtpmap 值,98 映射到具有 90,000 bps 帶寬的 VP9 視頻編解碼器,100 映射到具有 90,000 bps 帶寬的 H.264 視頻編解碼器

SDP的更多屬性配置可以閱讀文末資料,這裡不再展開。

2.3 什麼是Offer-Answer模型?

到目前為止,解釋了「WebRTC 如何在媒體通道中傳輸數據?」(RTP/RTCP)和「如何在信令通道中根據需要指定會話屬性?」(SDP)。 接下來回答「應用程式應該如何相互傳輸會話屬性 (SDP)?」。

你可能有一張華麗的名片,但如果你不把它送給任何人,它就毫無用處, 此規則也適用於 SDP。 我們需要在對等點之間交換 SDP 以發起呼叫。 Offer-Answer 模型是在 WebRTC 中用作電信標準的 SDP 交換過程,交換方式由申請時決定。 應用程式可以通過 HTTP/HTTPS 請求、Web 套接字、推送通知等方式發送它。這完全取決於應用程式。

Offer-Answer模型顧名思義,在這個模型中有一個 Offerer 和一個 Answerer。 提供者是啟動信令過程的人,例如開始撥出電話或發送通話事件的人,包括保持和關閉視頻開關。 回答者是回答傳入提議的人, 例如接聽來電或向通話中事件發送合適的數據。

Offer-Answer 模型有 4 個基本步驟;

  • Offerer 創建一個 Offer SDP 並將其發送到遠程節點。
  • 應答者收到提議者的 SDP,並自行設置。
  • Answerer 創建一個 Answer SDP 並將其發送給 offerer
  • 提供者收到應答者的 SDP,並自行設置。

之後,如果一切正常,呼叫開始。

2.4 WebRTC的Offer-Answer模型交換流程

下圖顯示了 WebRTC 上使用 Offer-Answer 模型的 SDP(Session Description Protocol,即會話描述協議) 交換過程:

接下來一一說明這些步驟:

  • Peer-1 獲取用戶媒體,然後從 WebRTC 創建一個 PeerConnection 對象
  • 創建PeerConnection後,應用程式需要調用WebRTC的createOffer接口
  • WebRTC 創建一個Offer SDP ,並且可以根據需要操作 SDP
  • 應用程式應將 Offer SDP 設置回 WebRTC
  • 應用程式應向 Peer-2 發送Offer SDP
  • Peer-2 上的應用程式收到Offer SDP, Peer-2 應該獲取用戶媒體並創建 PeerConnection 對象(如果目前尚未創建)
  • Peer-2 上的應用程式將Offer SDP 設置給 WebRTC
  • Peer-2 上的應用程式使用 WebRTC 的 createAnswer API 生成應答 SDP
  • WebRTC 創建一個應答 SDP 並將其提供給應用程式,應用程式可以根據需要操作SDP
  • 應用程式應將 Answer SDP 設置給 WebRTC
  • Peer-2 上的應用程式應將應答 SDP 發送給 Peer-1
  • Peer-1 上的應用程式設置應答 SDP
  • 如果一切正常,RTP 媒體流將通過 WebRTC 在媒體通道上啟動。

上面可能有很多步驟,但其中大部分都是重複性任務。WebRTC 交換 offer 與網絡參數之後,就會嘗試直接使用對方的 IP 地址與埠進行直連,這個過程會根據雙方網絡情況,使用的不同的方式建立連接,後文 NAT(Network Address Translation,即網絡地址轉換)打洞就是介紹這部分內容。

3.什麼是信令伺服器?什麼是STUN?什麼是TURN?

A 與 B 在建立 WebRTC 連接過程中,需要互相知道對方的 IP 與通信埠。那麼 A 與 B 要如何知道對方的 IP 與埠呢?答案就是通過信令伺服器。 信令伺服器的作用是作為一個中間人幫助雙方在儘可能少的暴露隱私的情況下建立連接。WebRTC 並沒有提供信令傳遞機制,你可以使用任何方式如 WebSocket 或者 XMLHttpRequest 等,來交換彼此的令牌信息。

STUN 和 TURN 伺服器是兩種類型的 WebRTC 信令伺服器,可用於在構建實時通信應用程式時創建對等 (P2P) 連接。

3.1 什麼是STUN?

STUN(NAT 會話遍歷實用程序)使用 UDP 協議通過 NAT 來實現 ICE能力。 STUN 允許應用程式發現它們之間和公共網際網路上的 NAT 、防火牆的存在和類型。 任何設備都可以使用它來確定 NAT 分配給它的 IP 地址和埠。

通常,STUN 客戶端可以向 STUN 伺服器發送消息以獲取公共 IP 和埠信息,然後基於此公共 IP 和埠信息即可在客戶端之間通過網際網路進行點對點通信。

3.2 什麼是TURN?

TURN(Traversal Using Relays around NAT)是一種協議,可協助 webRTC 應用程式穿越網絡地址轉換器 (NAT) 或防火牆。 TURN Server 允許客戶端通過中間伺服器發送和接收數據, TURN 協議是 STUN 的擴展。

在少數情況下,客戶端通信端點在不同類型的 NAT 後面,或者當使用對稱 NAT 時,通過中繼伺服器及其稱為 TURN 伺服器發送媒體可能更容易。

4.WebRTC API 調用

4.1 RTCPeerConnection

RTCPeerConnection 用於點對點之間建立連接以傳輸音視頻數據流,這是 RTCPeerConnection 的任務,為此需要藉助一個信令伺服器(signaling server)來進行,信令包括 3 種類型的信息:

  • Session control messages: 初始化和關閉通信,及報告錯誤;
  • Network configuration: 雙方的 IP 地址和埠號(區域網內部 IP 地址需轉換為外部的 IP 地址);
  • Media capabilities: 雙方的瀏覽器支持使用何種編碼以及多高的視頻解析度。

var PeerConnection =
  window.RTCPeerConnection ||
  window.mozRTCPeerConnection ||
  window.webkitRTCPeerConnection;
navigator.getUserMedia = navigator.getUserMedia
  ? 'getUserMedia'
  : navigator.mozGetUserMedia
  ? 'mozGetUserMedia'
  : navigator.webkitGetUserMedia
  ? 'webkitGetUserMedia'
  : 'getUserMedia';
var v = document.createElement('video');
// 創建信令(createOffer)
var pc = new PeerConnection();
pc.addStream(video);
pc.createOffer(function (desc) {
  pc.setLocalDescription(desc, function () {
    // send the offer to a server that can negotiate with a remote client
  });
});
// 創建回復(createAnswer)
var pc = new PeerConnection();
pc.setRemoteDescription(new RTCSessionDescription(offer), function () {
  pc.createAnswer(function (answer) {
    pc.setLocalDescription(answer, function () {
      // send the answer to the remote connection
    });
  });
});

4.2 RTCDataChannel

RTCDataChannel 接口代表在兩者之間建立了一個雙向數據通道的連接,可以用 RTCPeerConnection.createDataChannel() 或者在現有的 RTCPeerConnection 上用 RTCDataChannelEvent 類型的 datachannel 事件接收,創建出 RTCDataChannel 類型的對象。

var pc = new RTCPeerConnection();
// 獲取 RTCPeerConnection 對象
var dc = pc.createDataChannel('my channel');
// 創建 DataChannel 對象
dc.onmessage = function (event) {
  console.log('received: ' + event.data);
};
dc.onopen = function () {
  console.log('datachannel open');
};
dc.onclose = function () {
  console.log('datachannel close');
};

4.3 訪問用戶攝像頭及麥克風 getUserMedia

WebRTC 支持直接傳輸音頻流和視頻流(https://appr.tc/):

const pc = new RTCPeerConnection() ;
// 獲取RTCPeerConnection
navigator.getUserMedia({ video: true }, stream => { 
  // 添加視頻流到會話中 
 stream.getTracks().forEach(track => pc.addTrack(track, stream)) 
  // 在網頁中預覽自己攝像頭拍攝到的內容,其中$localVideo表示一個Video對象
  $localVideo.srcObject = stream; 
}) 

navigator.getUserMedia()還可以和web Audio API相結合,用來處理音頻效果:

var range = document.querySelector('input');
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioCtx = new AudioContext();
navigator.getUserMedia({
    audio: true
}, function(stream) {
    // 創建音頻流
    var source = audioCtx.createMediaStreamSource(stream);
    // 雙二階濾波器
    var biquadFilter = audioCtx.createBiquadFilter();
    biquadFilter.type = 'lowshelf';
    biquadFilter.frequenc.value = 1000;
    biquadFilter.gain.value = range.value;
    source.connect(biquadFilter);
    biquadFilter.connect(audioCtx.destination);
}, function(error) {
    console.log(error);
});

其實,WebRTC並不只是用來做視頻、音頻,它還可以用來傳輸任意數據,包括文件,文本等。上面代碼示例可以看到,WebRTC規定了dataChannel這個雙工數據通道,而https://snapdrop.net/這個網站就是通過WebRTC進行文件分享。

const pc = new RTCPeerConnection() 
const dataChannel = pc.createDataChannel('chat') 
// 監聽datachannel事件
pc.addEventListener('datachannel', event => { 
  // 接收通信方發送過來的數據 
 event.channel.addEventListener('message', event => { 
    console.log('message', event.message) 
  }) 
}) 
dataChannel.addEventListener('open', () => { 
  // 發送數據,可發送任意數據 
  dataChannel.send('Hi!') 
}) 
dataChannel.addEventListener('close', event => { 
}) 

4.4 candidate 事件

當 RTCPeerConnection 實例執行 setLocalDescription()後,RTCPeerConnection 就會探測自己的網絡環境,然後用 candidate 事件返回候選網絡環境數據,網絡環境數據中最重要的是 IP 地址與埠組成的候選通信地址。 candidate 事件中的 event.candidate 主要包含以下幾個部分:

  • 本機 IP 地址
  • 本機用於 WebRTC 通信的埠號
  • 候選者類型,包括 host、srflx 和 relay
  • 優先級
  • 傳輸協議

具體數據結構的示例如下:

{
  address: '192.168.31.67',
  candidate:
    'candidate:2147606101 1 udp 2122260223 192.168.31.67 57959 typ host generation 0 ufrag EaWw network-id 1 network-cost 10',
  component: 'rtp',
  foundation: '2147606101',
  port: 57959,
  priority: 2122260223,
  protocol: 'udp',
  relatedAddress: null,
  relatedPort: null,
  sdpMLineIndex: 0,
  sdpMid: '0',
  tcpType: null,
  type: 'host',
  usernameFragment: 'EaWw',
};

candidate 事件 type 欄位取值分別為 host、srflx、relay:

  • host(Host candidate):從本地網卡上獲取的地址
  • srflx(Server reflexive candidate):STUN(Session Traversal Utilities for NAT,即 NAT 會話穿越應用程式) 返回的該客戶端的地址
  • Relay(Relay reflexive candidate)::TURN (Traversal Using Relay NAT,即通過 Relay 方式穿越 NAT)伺服器為該客戶端分配的中繼地址

本地的 candidate 與遠端 candidate 構成的每一對都有一定的優先級,按優先級排序進行連通性檢查。最後從有效的 candidate 組合中選擇優先級最高的作為傳輸地址,用於建立 P2P 連接。

5.網絡地址轉換(NAT)

網絡地址轉換(英語:Network Address Translation,縮寫:NAT;又稱網絡掩蔽、IP 掩蔽)在計算機網絡中是一種在 IP 數據包通過路由器或防火牆時重寫來源 IP 地址或目的 IP 地址的技術。這種技術被普遍使用在有多台主機但只通過一個公有 IP 地址訪問網際網路的私有網絡中。 要建立一個連接需要知道對方的 IP 地址和埠號,在區域網裡面一台路由器(基站)可能會連接著很多台設備,例如家庭路由器接入寬帶的時候,寬帶服務商會分配一個公網的 IP 地址,所有連到這個路由器的設備都共用這個公網 IP 地址。如果兩台設備都用了同一個公網 IP:port 去發送請求,伺服器返回數據在經過路由器時它就不知道應該轉發給哪一個設備。因此路由器需要重寫 IP 地址/埠號進行區分,如下圖所示:

NAT 設備通常會自動設置各個設備的映射關係,也可以在路由器端去手動設置。如上圖的 NAT 維護的映射關係還會和要訪問的目標 IP 地址進行綁定,例如同一終端使用同一埠訪問不同的目標 IP,就會建立不同的映射關係。

如上示例 NAT 上建立的映射關係如下:

內網 IP 埠

外網 IP 埠

NAT 對外 IP 與埠

192.168.1.2:8080

39.182.39.30:443

10.188.20.10:8000

192.168.1.2:8080

39.182.39.40:443

10.188.20.10:8001

所以實際存儲的映射關係會包含上面 3 部分內容,這樣做的目的是保證網絡安全。想像如下例子,終端 192.168.1.2:8080 通過路由器使用 10.188.20.10:8000 訪問伺服器 A,建立 NAT 映射如果為 192.168.1.2:8080-->10.188.20.10:8000,那麼如果有人向 10.188.20.10:8000 發送數據就會轉發到 192.168.1.2:8080,這樣就會導致內網的服務被外部隨意訪問,所以 NAT 映射會記錄目標地址。當然,由於 NAT 有多種類型,NAT 映射也會存不同,更多內容可參考維基百科或者 WebRTC 網絡基礎 九、第二節 NAT 打洞原理,下表進行一個簡單的歸納。

5.1 NAT 打洞

由於 NAT 有上面 4 種類型,所以兩個設備要建立 P2P 連接就要使用不同的方式。

5.1.1 完全錐型 NAT

完全錐型是非常簡單的 ,左邊是內網的主機,它有自己的內網 IP 地址和埠 ,通過防火牆之後,它形成一個外網的 IP 地址,那麼外網的主機要想與內網的主機進行通信的時候,首先要由內網的主機向外發送一個請求,請求外網中的其中一台主機,這樣會形成的結果就是它會在 NAT 服務上打一個洞,這樣會形成一個外網的 IP 地址和埠。 形成了外網的 IP 地址和埠之後,其他的主機只要獲得了這個 IP 地址和埠它都可以向它發送數據。並且可以順利的通過防火牆發送給內網的主機。這樣就可以進行通訊了,這是完全錐型,也是最好穿越的一種 NAT 類型。但是安全性就差很多。

NAT內網計算機IP位址為10.0.0.1,其在埠 8000 上收發消息,映射到 NAT 上的外部IP和埠為 202.123.211.25:8000。 這樣Internet 上的任何人都可以向 NAT 上的內網 IP: 埠發送數據包,這些數據包將被傳遞到 10.0.0.1:8000 的客戶端機器。

5.1.2 地址限制錐型 NAT

它的安全性好一些,它會在防火牆上形成一個五元組,即內網主機的 IP 地址和埠、映射後的公網 IP 地址和埠、請求的主機 IP 地址。他們首先有一個公共的步驟,第一步就是要先由內網的主機向外網發送一個請求,在這個防火牆上或者 NAT 服務上形成一個映射表,那形成之後外網的主機就可以和內網的主機進行通訊了。

客戶端向伺服器 1(IP - 192.248.22.100)發送數據包,然後NAT將客戶端的10.0.0.1:8000映射到外網的202.123.211.25:8000, 現在 server1 可以將數據包發送到目的地。 但是,NAT 將阻止來自伺服器 2(IP - 192.248.22.200)的數據包,直到客戶端向伺服器 2 的 IP 地址發送數據包。 一旦客戶端將數據包發送到伺服器 2,伺服器 1 和伺服器 2 都可以將數據包發送回客戶端。

5.1.3 埠限制錐型 NAT

埠限制型就更加嚴格一些了,不光是對 IP 地址,還要對埠做限制,所以在防火牆上就形成了六元組,不光有內網的 IP 地址和埠、映射後的公網的 IP 地址和埠、還有你請求的主機的 IP 地址和埠。

如果客戶端將數據包發送到 192.248.22.100:10100(包含IP 和埠),NAT 將只允許來自 192.248.22.131:10100 的數據包(到客戶端),它丟棄來自 192.248.22.131:10200(相同 ip 但不同埠)的數據包。

5.1.4 對稱型 NAT

對稱限制型就更加嚴格了,以前的類型是在防火牆上形成映射後的公網的 IP 地址是保持不變的,大家要找還是能找到它的,雖然不通,但是對於 這個對稱型它就不一樣了,它就發生了變化,不光是形成了一個 IP 地址和埠,而且還會形成多個,對於每一台主機都會形成一個不同的 IP 地址和埠對

如果客戶端從 10.0.0.1:8000 發送數據到 server1,其外網地址被映射為 202.123.211.25:12345,而如果客戶端從同一個埠(10.0.0.1:8000)發送到不同的 IP,則映射的外網地址也會不同(即外網地址被映射為 202.123.211.25:45678)。 server1 只能響應自己的映射,server2也 只能響應自己的映射,兩者無法公用。 如果任何一個地址嘗試發送到另一個映射的 IP:port,這些數據包將被丟棄。

5.2 WebRTC 打洞這麼複雜麼?

WebRTC 本身就已經實現 NAT 打洞功能,只需要連接的雙方交換了網絡埠和 IP 之後,WebRTC 就會自動進行打洞。WebRTC 使用一個叫做交互式連接設施(ICE,Interactive Connectivity Establishment,即交互式連接建立)協議框架,ICE 整合了 STUN 與 TURN。STUN 是用來探測終端 NAT 類型、IP 和埠的服務,WebRTC 獲取到 NAT 類型、IP 和埠後就會觸發 candidate 事件,然後連接雙方交換 IP 與埠,開始打洞。如果打洞失敗,那麼就會使用 TURN 伺服器轉發流量。

由於 WebRTC 提供了 ICE,所以使用非常簡單,只需在 new RTCPeerConnection 時傳入 iceServers 參數即可。googel 提供了免費的 STUN 伺服器去幫助打洞,也可以自己架設伺服器。

const pc = new RTCPeerConnection({
  // 可以傳入多個 stun 伺服器或者 turn 伺服器
  iceServers: [
    { url: 'stun:stun.l.google.com:19302' },
    { url: 'stun:stun1.l.google.com:19302' },
    { url: 'stun:stun2.l.google.com:19302' },
    { url: 'stun:stun3.l.google.com:19302' },
    { url: 'stun:stun4.l.google.com:19302' },
  ],
});

6.WebRTC vs WebSocket 區別

  1. 用途區別
  • WebSocket允許瀏覽器和Web伺服器之間進行全雙工通信.
  • WebRTC允許兩個瀏覽器之間的全雙工通信。

2. 協議區別

  • WebSocket使用TCP協議
  • WebRTC使用UDP協議

3. 流量路徑

  • WebSocket瀏覽需要經過伺服器
  • WebRTC是直接連接,瀏覽不會經過第三方伺服器,是一個去中心化的架構模型,簡單說就是省帶寬。

4. 實時性

  • WebSocket延遲高(不是直接連接)
  • WebRTC延遲低

通常WebRTC會與WebSocket配合使用,WebSocket的作用主要是用來交換客戶端的SDP與網絡信息,Websocket傳輸的內容與真正通信數據無關,只是協助WebRTC建立連接。

參考資料

https://medium.com/orion-innovation-turkey/webrtc-in-a-nutshell-ep-ii-ca8cb33f8ff3

https://datatracker.ietf.org/doc/html/rfc4566

https://medium.com/rahasak/network-address-translation-nat-df84dc1cb06c

https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel

https://caniuse.com/?search=WebRTC

https://www.jianshu.com/p/1022f559a805

https://zhuanlan.zhihu.com/p/421503695

https://github.com/nashaofu/webrtc-demo

https://blog.csdn.net/xyphf/article/details/107297616

https://medium.com/av-transcode/what-is-webrtc-and-how-to-setup-stun-turn-server-for-webrtc-communication-63314728b9d0

https://webrtc.ventures/2020/12/webrtc-signaling-stun-vs-turn/

關鍵字: