# [知識篇]WebRTC APIs - RTCDataChannel

# 學習目標

  • 了解 RTCDataChannel 中的 methods及作用

透過前一章節的實作,本章藉由分解過程來了解RTCDataChannel中的功能

# RTCDataChannel 介紹

The RTCDataChannel interface represents a network channel which can be used for bidirectional peer-to-peer transfers of arbitrary data. 擷取自MDN

主要就是扮演P2P中雙向資料傳輸的通道。

要創建 data channel 必須藉由 RTCPeerConnection的createDataChannel() method, 呼叫createDataChannel() 時,除了創建 data channel外,也會呼叫目前已連線的remote peers的 datachannel event。

localPeer = buildPeerConnection(configuration);

datachannel = localPeer.createDataChannel("my local channel"); // 在RTCPeerConnection中建立 data channel

因此當 remote peer 有綁定datachannel event時,就會收到 channel 的邀請通知,通知該p2p 連線中有加入新的 data channel!

remotePeer = buildPeerConnection(configuration);
remotePeer.ondatachannel = (event) => {
  const channel = event.channel
}; // 收到新的data channel 創建的通知

# Properties

console看看 datachannel 裡有哪些屬性。

datachannel

  • binaryType: 數據型別(可以自定義),但只接受 BlobArrayBuffer 兩種型別,預設是Blob。

    注意: 雖然文件上預設是Blob但目前範例上實測出來得結果在chrome是arrayBuffer 但firefox是 blob (因此使用上指定一下自己想使用的型別比較妥當)

    firefox-datachannel

  • bufferAmount: 以bytes為單位,表示目前尚未傳輸完畢的數據大小。

  • bufferedAmountLowThreshold: 作為傳送的緩衝區,在傳送指定大小的數據後,會觸發 bufferedamountlow 事件,可以在此繼續讀取尚未傳輸的數據並使用 send() method 將數據丟到傳輸隊列中。

    let source = /* source data object */
    // 指定大小
    datachannel.bufferedAmountLowThreshold = 65536;
    
    pc.addEventListener("bufferedamountlow", ev => {
      if (source.position <= source.length) {
        // 當發現檔案還未傳完,繼續讀取並交由send()丟到隊列中傳送
        datachannel.send(source.readFile(65536));
      }
    }, false);
    
  • readyState: channel連線狀態。

以下為初始化 createDataChannel() 階段才能設定的參數:

  • id: 代表目前創建的data channel unique ID (數值介於 0 到 65,534 間),換句話說,建立 data channel的數量是有上限的!

  • label: 顯示該channel的指定名稱/描述,非唯一值。

  • maxPacketLifeTime: 類似在axios中設定的timeout時間,規定瀏覽器在放棄傳送前能夠重新或是等待傳送的時間限制。

  • maxRetransmits: 規定瀏覽器在放棄傳送前能夠重新傳送的次數。

  • negotiated: true/false,是否透過Web app,default: false 是透過 WebRTC peer connection ,或是設為true 則由 Web App (中介層) 將id傳送到remote peer ,讓遠端自行建立相同id的channel。

  • ordered:是否依照順序傳送,default: true

  • protocol: 能夠定義子協議,如json,raw...等,讓接下來接收端能夠依此判斷數據格式,default: "" (empty string)。

localPeer.createDataChannel("my local channel", {
  id: 1,
  negotiated: false,
  ordered: true,
  protocol: "json",
  maxPacketLifeTime: 2000,
  maxRetransmits: 5
});

延伸思考:

  • 試著想想 Blob 與 ArrayBuffer 是什麼?其差異在哪?

# Event handler

  • onbufferedamountlow : 有設定bufferedAmountLowThreshold且到達上限時。
  • onclose : 呼叫close() method時。
  • onclosing : 呼叫close() method後,且傳輸處理皆已結束時。
  • onerror : 發生錯誤時。
  • onmessage : 呼叫send() method傳輸數據時。
  • onopen : data channel 雙邊(local & remote)都連接上時。
localChannel.send('hello')

receiveChannel.onmessage = event => console.log(event.data) // 'hello'

# 總結

本章節了解到:

  • RTCDataChannel的屬性及事件。

# 參考