WebRTC データ チャネルを使用してブラウザ間でデータを送信する

通信、ゲーム、ファイル転送のために 2 つのブラウザ間でデータを送信するのは、かなり複雑なプロセスになる可能性があります。データのリレーを行うサーバーを設定して料金を支払う必要があり、場合によっては複数のデータセンターにスケーリングする必要があります。このシナリオでは、レイテンシが高くなる可能性があり、データを非公開に保つのが難しくなります。

これらの問題は、WebRTC の RTCDataChannel API を使用してピア間でデータを直接転送することで軽減できます。この記事では、データ チャネルの設定方法と使用方法の基本と、ウェブでの一般的なユースケースについて説明します。

別のデータ チャネルを使用する理由

WebSocketAJAXサーバー送信イベントがあります。なぜ別のコミュニケーション チャネルが必要なのか?WebSocket は双方向ですが、これらのテクノロジーはすべて、サーバーとの通信用に設計されています。

RTCDataChannel は別のアプローチをとっています。

  • これは、ピアツーピア接続を可能にする RTCPeerConnection API と連携します。これにより、中間サーバーがなく「ホップ」が少ないため、レイテンシを低く抑えることができます。
  • RTCDataChannelストリーム制御伝送プロトコル(SCTP)を使用します。これにより、配信セマンティクスの構成(順序付けされていない配信と再送信の構成)が可能になります。

RTCDataChannel は、パソコンと Android の Google Chrome、Opera、Firefox で SCTP をサポートして利用できるようになりました。

留意点: シグナリング、STUN、TURN

WebRTC ではピアツーピア通信が可能になりますが、ピア接続をブートストラップするためにメディアとネットワークのメタデータを交換するシグナリングを行うサーバーが必要です。

WebRTC は、次の方法で NAT とファイアウォールに対応します。

WebRTC がサーバーとどのように連携してシグナリングとネットワーキングを行うかについて詳しくは、実際の WebRTC: STUN、TURN、シグナリングをご覧ください。

機能

RTCDataChannel API は、柔軟なデータ型のセットをサポートしています。この API は WebSocket を正確に模倣するように設計されており、RTCDataChannel文字列と、JavaScript の一部のバイナリ型(BlobArrayBufferArrayBufferView など)をサポートしています。これらのタイプは、ファイル転送やマルチプレーヤー ゲームで役立ちます。

RTCDataChannel は、信頼性が低く順序付けされていないモード(User Datagram Protocol または UDP に類似)、信頼性が高く順序付けられたモード(Transmission Control Protocol または TCP に類似)、部分的に信頼できるモードで動作できます。

  • 信頼性と順序付けモードでは、メッセージの送信と配信順序が保証されます。これによりオーバーヘッドが増加し、このモードの速度が低下する可能性があります。
  • 信頼できない順序なしモードでは、すべてのメッセージが相手側に届くことや、届く順序が保証されません。これによりオーバーヘッドが解消され、このモードの動作が大幅に高速化されます。
  • 部分信頼モードでは、再送信タイムアウトや再送信の最大回数など、特定の条件下でメッセージの送信が保証されます。メッセージの順序も構成できます。

最初の 2 つのモードのパフォーマンスは、パケットロスがない場合とほぼ同じです。ただし、信頼性と順序付けのモードでは、パケットが失われると、他のパケットがブロックされ、失われたパケットが再送信されて届くまでに古くなる可能性があります。もちろん、信頼性の高いセマンティクスか信頼性の低いセマンティクスをそれぞれ備えた複数のデータ チャネルを、同じアプリ内で使用することも可能です。

Ilya Grigorik 著の High 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 セマンティクスについては、maxRetransmits0 に、orderedfalse に設定します。詳細については、IETF RFC の Stream Control Transmission ProtocolStream Control Transmission Protocol Partial Reliability Extension をご覧ください。

  • ordered: データ チャネルで順序を保証するかどうか
  • maxPacketLifeTime: 失敗したメッセージの再送信を試行する最大時間
  • maxRetransmits: 失敗したメッセージの再送信の最大回数
  • protocol: サブプロトコルを使用できるようにします。これにより、アプリのメタ情報が提供されます。
  • negotiated: true に設定すると、もう一方のピアでのデータチャネルの自動設定が解除され、もう一方のピアで同じ ID のデータチャネルを独自の方法で作成できるようになります。
  • id: negotiatedtrue に設定した場合にのみ使用できる、チャネルの独自の ID を指定できます。

ほとんどのユーザーが使用する必要があるのは、最初の 3 つのオプション(orderedmaxPacketLifeTimemaxRetransmits)のみです。SCTP(現在、WebRTC をサポートするすべてのブラウザで使用)では、信頼性と順序付けはデフォルトで true です。アプリレイヤから完全に制御したい場合は、信頼性が低く順序付けされていないものを使用するのが合理的ですが、ほとんどの場合、部分的な信頼性が有用です。

WebSocket と同様に、RTCDataChannel は接続が確立されたとき、閉じられたとき、またはエラーが発生したときと、他のピアからメッセージを受信したときにイベントを起動します。

それは安全?

暗号化は、すべての WebRTC コンポーネントに必須です。RTCDataChannel では、すべてのデータが Datagram Transport Layer Security(DTLS)で保護されます。DTLS は SSL の派生物です。つまり、標準的な SSL ベースの接続を使用する場合と同様に、データの安全性が確保されます。DTLS は標準化されており、WebRTC をサポートするすべてのブラウザに組み込まれています。詳細については、Wireshark のウィキをご覧ください。

データに対する考え方を変える

JavaScript では、大量のデータの処理が問題になることがあります。Sharefest のデベロッパーが指摘したように、そのためにはデータについて新しい考え方をする必要がありました。使用可能なメモリ量よりも大きいファイルを転送する場合は、この情報を保存するための新しい方法を検討する必要があります。ここで役立つのが FileSystem API などのテクノロジーです。

ファイル共有アプリを作成する

RTCDataChannel を使用すると、ブラウザでファイルを共有できるウェブアプリを作成できるようになりました。RTCDataChannel 上に構築すると、転送されたファイルデータが暗号化され、アプリ プロバイダのサーバーには影響を与えません。この機能と、複数のクライアントに接続してより迅速に共有できる可能性を組み合わせることで、WebRTC ファイル共有はウェブでの使用に適した候補となります。

送金が正常に行われるようにするには、いくつかの手順が必要です。

  1. File API を使用して JavaScript でファイルを読み取る
  2. RTCPeerConnection を使用してクライアント間でピア接続を作成します。
  3. RTCDataChannel を使用して、クライアント間のデータチャネルを作成します。

RTCDataChannel 経由でファイルを送信する場合は、次の点に注意してください。

  • ファイルサイズ: ファイルサイズが比較的小さい場合、1 つの Blob として保存して読み込むことができる場合は、File API を使用してメモリに読み込み、そのまま信頼性の高いチャネル経由でファイルを送信できます(ただし、ブラウザには転送サイズの上限が設定されていることに注意してください)。ファイルサイズが大きくなると、状況は複雑になります。チャンク処理メカニズムが必要な場合、ファイル チャンクは読み込まれ、chunkID メタデータとともに別のピアに送信されます。これにより、ピアはチャンクを認識できます。この場合、最初にオフライン ストレージにチャンクを保存し(FileSystem API などを使用して)、ファイル全体を取得したときにのみユーザーのディスクに保存する必要があります。
  • チャンクサイズ: アプリのデータの最小「アトム」です。現在、送信サイズの上限があるため、チャンク化が必要です(ただし、これは今後のバージョンのデータ チャネルで修正される予定です)。現在の推奨される最大チャンクサイズは 64 KiB です。

ファイルが反対側に完全に転送されたら、アンカータグを使用してダウンロードできるようになります。

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

PubShareGitHub のファイル共有アプリでは、この手法が使用されています。どちらもオープンソースであり、RTCDataChannel ベースのファイル共有アプリの優れた基盤となります。

ではどうすればよいでしょうか。

RTCDataChannel により、ファイル共有、マルチプレイヤー ゲーム、コンテンツ配信用のアプリを新しい方法で構築できるようになります。

  • 前述のピアツーピア ファイル共有
  • Mozilla の BananaBread で見つかるような、WebGL などの他のテクノロジーと組み合わせたマルチプレーヤー型ゲーム
  • コンテンツ配信の再発明: ピアツーピアのデータ通信を通じてウェブアセットを配信するフレームワークである PeerCDN

アプリの作成方法を変更する

RTCDataChannel を介した高パフォーマンスで低レイテンシの接続を使用することで、より魅力的なアプリを提供できるようになりました。PeerJSPubNub WebRTC SDK などのフレームワークを使用すると、RTCDataChannel を簡単に実装できます。また、この API はプラットフォーム間で幅広くサポートされています。

RTCDataChannel の登場により、ブラウザでのデータ転送に対する考え方が変わる可能性があります。

補足説明