使用 WebRTC 資料管道在瀏覽器之間傳送資料

在不同瀏覽器之間傳送通訊、遊戲或檔案傳輸等資料,有時也相當複雜。它需要設定伺服器並支付費用來轉發資料,還可能需要將資源配置擴展到多個資料中心。在這個情境中,可能會有高延遲時間的問題,而且很難確保資料的私密性。

只要使用 WebRTC 的 RTCDataChannel API,從一個對等點直接傳輸資料,就能解決這些問題。本文涵蓋設定和使用資料管道的基本知識,以及目前的網頁常見用途。

為什麼要改用其他資料管道?

我們提供 WebSocketAJAX伺服器傳送事件。為什麼需要其他通訊管道?WebSocket 是雙向的,但這些技術都是為了與伺服器之間的通訊而設計。

RTCDataChannel 採用不同方法:

  • 這項服務可與 RTCPeerConnection API 搭配使用,支援點對點連線。這可能導致延遲時間更短:沒有中介伺服器,也減少了「躍點」次數。
  • RTCDataChannel 使用串流控制傳輸通訊協定 (SCTP),可讓您可設定的傳送語意脫序傳送與重新傳送設定。

現在可以在電腦和 Android 裝置上使用 Google Chrome、Opera 和 Firefox 的 SCTP 支援 RTCDataChannel

注意事項:信號、STUN 和 TURN

WebRTC 啟用點對點通訊,但仍需透過伺服器進行訊號來交換媒體和網路中繼資料,才能啟動對等互連連線。

WebRTC 運用 NAT 和防火牆搭配:

  • ICE 架構:建立同業之間可能的最佳網路路徑。
  • STUN 伺服器來確認每個對等點的可公開存取 IP 和通訊埠。
  • 轉置伺服器:如果直接連線失敗,且必須使用資料轉送。

如要進一步瞭解 WebRTC 如何與伺服器搭配運作,以提供訊號和網路功能,請參閱「在實際環境中使用 WebRTC:STUN、TURN 和信號」。

功能

RTCDataChannel API 支援一組彈性的資料類型。這個 API 旨在完全模仿 WebSocket,RTCDataChannel 支援 字串以及 JavaScript 中的部分二進位類型,例如 BlobArrayBufferArrayBufferView。如果需要傳輸檔案或進行多人遊戲,這些類型可派上用場。

RTCDataChannel 可在不可靠和無順序的模式下運作 (類似使用者資料包通訊協定或 UDP)、可靠且排序模式 (類似傳輸控制通訊協定或 TCP),以及部分可靠的模式:

  • 可靠且排序模式可保證訊息的傳輸及傳送順序。這會增加額外負荷,因此可能會減慢這個模式。
  • 即使模式不可靠和未排序,也無法保證每則訊息都能送達另一端,也無法保證訊息的順序。這樣可以排除開銷,讓這個模式正常運作。
  • 部分可靠模式可保證在特定條件下傳送訊息,例如重新傳輸逾時或重新傳輸量上限。您也可設定訊息的排序方式。

在沒有封包遺失的情況下,前兩種模式的效能大致相同。不過,在可靠且排序模式下,遺失的封包會導致其他封包被封鎖,而且遺失的封包在重新傳輸並抵達時可能已過時。當然,您可以在同一個應用程式中使用多個資料管道,每個管道都有獨立可靠或不可靠的語意。

以下是 Ilya GrigorikHigh Performance Browser Networking 的實用表格:

TCPUDPSCTP
可靠性穩定可靠不可靠可自行設定
外送排序依據未排序可自行設定
傳染方式位元組導向訊息導向訊息導向
流量控制
壅塞控制

接下來,您將瞭解如何設定 RTCDataChannel,以使用可靠、不可靠、非排序模式。

設定資料管道

以下提供幾個簡單的「RTCDataChannel」線上示範:

在這些範例中,瀏覽器會先建立對等點連線,然後建立資料管道,並透過對等點連線傳送訊息。容器隨即建立資料管道,並透過對等點連線傳送訊息。最後,您的訊息就會出現在頁面另一側的方塊中!

要開始設定的程式碼很簡短:

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

dataChannel 物件是透過已建立的對等連線建立。在信號發生前後可建立時段。然後,您可以傳入一個標籤,以便區分此管道和其他一組選用的配置設定:

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

您也可以新增 maxRetransmits 選項 (失敗前可嘗試的次數),但只能指定 maxRetransmits 或 maxPacketLifeTime。針對 UDP 語意,請將 maxRetransmits 設為 0,並將 ordered 設為 false。詳情請參閱下列 IETF RFC:串流控制傳輸通訊協定串流控制傳輸通訊協定部分可靠性擴充功能

  • ordered:如果資料管道應保證排序
  • maxPacketLifeTime:嘗試重新傳輸失敗訊息的時間上限
  • maxRetransmits:嘗試重新傳送失敗訊息的次數上限
  • protocol:允許使用子通訊協定,為應用程式提供中繼資訊
  • negotiated:如果設為 True,系統會移除另一個對等點的資料管道自動設定,讓您在另一端以相同的 ID 建立資料管道
  • id:可讓您為自己的頻道提供自己的 ID,但該 ID 只能與設為 truenegotiated 搭配使用)

大多數使用者只能使用前三個選項:orderedmaxPacketLifeTimemaxRetransmits。根據預設,使用 SCTP (現在支援 WebRTC 的所有瀏覽器都採用) 穩定且排序為 true。如果想從應用程式層完全控制控制權,使用不可靠和未排序的機制就很合理,但在大多數情況下,部分可靠性會很有幫助。

請注意,與 WebSocket 相同,RTCDataChannel 會在建立、關閉或錯誤的連線,以及收到來自另一個對等端的訊息時觸發事件。

這個挑戰安全嗎?

所有 WebRTC 元件都必須加密。透過 RTCDataChannel,所有資料都會受到資料元傳輸層安全標準 (DTLS) 保護。DTLS 是 SSL 的衍生技術,這表示您的資料安全無虞,就像使用任何標準 SSL 連線一樣安全。DTLS 經過標準化,並內建於所有支援 WebRTC 的瀏覽器中。詳情請參閱「Wireshark 維基」。

改變您對資料的看法

處理大量資料可能是 JavaScript 中的困擾。Sharefest 的開發人員指出,他們必須以新的方式思考資料。如果您要傳輸的檔案超過可用的記憶體大小,必須考慮以新方式儲存這些資訊。這時 FileSystem API 等技術就能派上用場。

建構檔案分享應用程式

現在可以使用 RTCDataChannel 建立可在瀏覽器中共用檔案的網頁應用程式。建構在 RTCDataChannel 上表示傳輸的檔案資料會經過加密,而且不會碰觸應用程式供應商的伺服器。這項功能結合了連線至多個用戶端來加快分享速度的可能性,使 WebRTC 檔案成為網路使用者的最佳選擇。

如要成功轉移,您必須完成幾個步驟:

  1. 使用 File API 讀取以 JavaScript 編寫的檔案。
  2. 使用 RTCPeerConnection 在用戶端之間建立對等連線。
  3. 使用 RTCDataChannel 在用戶端之間建立資料管道。

嘗試透過 RTCDataChannel 傳送檔案時,請留意下列要點:

  • 檔案大小:如果檔案大小相當小,而且可以儲存為一個 Blob 載入,您可以使用 File API 載入記憶體,再依照原樣傳送檔案 (但請注意,瀏覽器對傳輸大小上限設有限制)。隨著檔案大小變大,情況也會越來越難。需要使用區塊機制時,檔案區塊會載入並傳送至另一個對等互連人員,同時加上 chunkID 中繼資料,讓對等點可辨識這些區塊。請注意,在這種情況下,您也需要先將區塊儲存到離線儲存空間 (例如,使用 FileSystem API),並且僅在檔案完整的情況下才將區塊儲存到使用者的磁碟。
  • 區塊大小:這是應用程式資料的最小「原子」。由於目前設有傳送大小限制,因此必須進行區塊 (不過我們會在日後的資料管道中修正此問題)。目前建議的區塊大小上限為 64KiB。

檔案完全傳輸到另一端後,即可利用錨定標記下載:

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

這些在 PubShareGitHub 上的檔案分享應用程式使用這項技術。這兩者都是開放原始碼,可以為以 RTCDataChannel 為基礎的檔案分享應用程式奠定良好基礎。

那麼你該怎麼做呢?

RTCDataChannel為檔案分享、多人遊戲和內容傳送等建構應用程式開創全新方式。

  • 如前所述,點對點檔案共用機制
  • 多人遊戲搭配 WebGL 等其他技術,如 Mozilla BananaBread 中所述
  • 內容傳遞服務由 PeerCDN 重新發明,後者是透過點對點資料通訊方式傳遞網路資產。

變更應用程式建構方式

您現在可以透過 RTCDataChannel 使用高效能的低延遲連線,打造更具吸引力的應用程式。PeerJSPubNub WebRTC SDK 等架構可以讓 RTCDataChannel 更容易實作,而且 API 現在廣泛支援各種平台。

RTCDataChannel」的問世可以改變您對瀏覽器資料傳輸的看法。

瞭解詳情