跳至主要內容
Skip to content

WebRTC 實戰 (5) —— Data Channel:不只是傳影音

很多人誤以為 WebRTC 只能用來視訊或通話。其實,它還提供了 RTCDataChannel,允許你在兩台電腦之間建立一個 低延遲、高吞吐量 的資料通道。


一、 核心概念:SCTP 傳輸

Data Channel 建立在 SCTP (Stream Control Transmission Protocol) 之上:

  • 可靠且有序:預設模式,資料會重傳並保持順序,適合聊天與檔案控制訊息。
  • 部分可靠或無序:可設定 maxRetransmitsmaxPacketLifeTimeordered: false,適合允許丟失的即時狀態。

二、 實作:建立數據通道

Data Channel 的建立必須依附於 RTCPeerConnection,且通常是在 Offer 發起端建立。

1. 發起端 (Offerer)

javascript
const pc = new RTCPeerConnection();
const dc = pc.createDataChannel("chat-room", {
  ordered: true,
});

dc.onopen = () => {
  console.log("通道已開啟!");
  dc.send("Hello WebRTC!");
};
dc.onmessage = (event) => console.log("收到訊息:", event.data);

send() 只能在 readyState === "open" 時呼叫。若要使用部分可靠傳輸,可另外建立通道:

javascript
const positionChannel = pc.createDataChannel("position", {
  ordered: false,
  maxRetransmits: 0,
});

2. 接收端 (Answerer)

接收端監聽 ondatachannel 事件:

javascript
pc.ondatachannel = (event) => {
  const receiveChannel = event.channel;
  receiveChannel.onopen = () => console.log("接收通道已開啟");
  receiveChannel.onmessage = (e) => console.log("接收端收到:", e.data);
};

3. 大檔案需要背壓控制

檔案不能一次塞進 DataChannel。應切成較小區塊,並監控 bufferedAmount,避免瀏覽器持續累積待送資料:

javascript
dc.bufferedAmountLowThreshold = 256 * 1024;

async function waitForBuffer() {
  if (dc.bufferedAmount <= dc.bufferedAmountLowThreshold) return;

  await new Promise((resolve) => {
    dc.addEventListener("bufferedamountlow", resolve, { once: true });
  });
}

三、 應用場景

  1. 即時通訊:在已建立 PeerConnection 的使用者之間傳送聊天資料,減少應用伺服器的資料轉送量。
  2. 多人遊戲:利用「非可靠傳輸」同步玩家座標,獲得極低延遲。
  3. P2P 檔案共享:直接路徑成功時不需應用伺服器中轉;若 ICE 選到 Relay Candidate,資料仍會經過 TURN。

總結

今天我們解鎖了 WebRTC 的半壁江山:RTCDataChannel。它可以平衡可靠性與速度,是開發高性能 P2P 應用的關鍵。

下一篇,我們將進入第二階段:討論如何利用成熟的框架 PeerJS 來優化這一切。


進階挑戰

試著實作一個「P2P 檔案傳輸進度條」。你需要發送方定期發送「目前已發送 Chunk 數量」的資訊,而接收方則根據總檔案大小更新 UI。別忘了在傳送完畢後,正確合併所有的 ArrayBuffer 並觸發下載!


延伸閱讀與資源

← 上一章:ICE 候補者與 NAT 穿越 | 返回專題首頁 | 下一章:PeerJS 實戰