WebRTC data channels

高パフォーマンスなデータ交換のためのWebRTC data channels

HTML5 Rocks

コミュニケーション、ゲーム、ファイル転送のために、2つのブラウザ間でデータを送信するのは、やや難解なプロセスです。データを中継するためには、お金を払ってサーバを建てたり、サーバを複数のデータセンタへ拡大する必要があります。このようなシナリオでは、レイテンシが高くなる可能性がありますし、データを秘匿するのも困難です。

これらの問題は、WebRTCのRTCDataChannel APIを活用して、一方のピアからもう一方のピアへデータを直接送れば、軽減できます。本記事では、data channelとその一般的なユースケースについて取り扱います。

本記事を最大限に活かすためには、RTCPeerConnection API、STUN、TURN、シグナリングについて、ある程度の知識が必要です。Getting Started With WebRTCを参照ください。

なぜ、もうひとつdata channelが必要?

すでにWebSocketAJAXServer Sent Eventsがあります。なぜ、もう一つのコミュニケーションchannelが必要なのでしょうか? WebSocketは双方向ですが、これら全ての技術はサーバとの送受信を目的として設計されています。

RTCDataChannelの異なるアプローチ:

  • ピアツーピア間の接続を可能にするRTCPeerConnection APIと連携して動きます。これにより、レイテンシを低くすることができます。なぜならば、中継サーバが無く、中継するホップも少ないためです。
  • RTCDataChannelはStream Control Transmission Protocol (SCTP)を利用しており、転送方式を変更可能です:つまり、順序を考慮しない方式、順序を考慮して再送制御する方式を設定可能となります。

SCTPのサポートを含むRTCDataChannelは、Chrome、Opera、Firefox(デスクトップ版、Android版)で現在利用可能です。

注意:シグナリング、STUN、TURNについて

WebRTCはピアツーピア間のコミュニケーションを可能にしますが、サーバは依然として必要です:

  • シグナリング:ピア接続を確立するために、メディアやネットワークのメタ情報の交換が必要です。
  • NATとファイアウォールの対処:ICEフレームワークの活用によりピア間の最適な経路を確立できます。ICEフレームワークは、STUNサーバ(ピア間で接続可能な外部に公開されているIPとポートの確認)とTURN(ピア間の直接の接続が失敗した場合には、データの中継が必要)と連動して動作します。

HTML5 Rocksの記事であるWebRTC in the real world: STUN, TURN, and signalingは、シグナリングとネットワーク、とWebRTCがどのように関連しているか、詳細に説明しています。

能力

RTCDataChannel APIは、柔軟なデータ形式をサポートしています。APIはWebSocketをそっくり真似るように設計されています。また、JavaScriptにおけるBlob, ArrayBufferArrayBufferViewのようなデータ形式をサポートしています。これらの形式は、ファイル転送や多人数ゲームを実現する際に、有用です。

TCPUDPSCTP
信頼性到達保証有り到達保証無し変更可能
配送順序順序付け有り順序付け無し変更可能
転送方式バイト指向メッセージ指向メッセージ指向
流量制御有り無し有り
輻輳制御有り無し有り

(Ilya Grigorik氏のHigh Performance Browser Networkingの記事より)

RTCDataChannelはUDP同様に信頼性の無いモードでも動作しますし、TCP同様に信頼性のあるモードでも動作します。これら2つのモードは、シンプルな違いがあります:

  • 信頼性の有るモードでは、メッセージの到達を保証しており、また到達される順序も保証しています。これらの処理はオーバヘッドがあるため、潜在的に動作が遅くなります。
  • 信頼性の無いモードでは、全てのメッセージがもう一方に到達されることを保証しておらず、また順序も保証しません。これによりオーバヘッドが生じないため、より早く動作します。

もしパケットロスがなければ、これらの両方のモードの性能はおおよそ同じです。しかし、信頼性のあるモードにおいて、パケットロスが発生すると、他の後続パケットがブロックされます。また、ロスしたパケットは再送により到達するのを待つ必要があります。

以下では、信頼性の有るモードおよび無いモードについて、どのようにRTCDataChannelで変更するかを示します。

Data Channelの変更

RTCDataChannelのシンプルなオンラインデモがあります:

これらのケースでは、ブラウザが自身にピア接続を作ります。その後、Data Channelを作成し、ピア接続に応じてメッセージを送信します。そして、最後にはもう一方の欄にメッセージが表示されます!

この動作をはじめるコードは短いです:

var peerConnection = new RTCPeerConnection();

var dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

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

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

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

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

dataChannelオブジェクトは、既に確立しているピア接続から作られます。このオブジェクトは、シグナリングが起こる前後に作られます。ラベルを用いて、他のチャネル間と識別して、設定(省略可能)を行います。

var dataChannelOptions = {
  ordered: false, // 順序を保証しない
  maxRetransmitTime: 3000, // ミリ秒
};

maxRetransmits(再送が失敗するまでの試行回数)をオプションとして加えることも可能ですが、maxRetransmitsかmaxRetransmitsTimeのどちらかしか指定できません。例えばUDPのようにするためには、maxRetransmitsを0にして、orderedをfalseに設定してください。さらなる詳細は、RFC 4960 (SCTP) と RFC 3758 (SCTP partial reliability)を確認してください。

  • ordered: 順序を保証するか、しないか
  • maxRetransmitTime: 送信に失敗したメッセージの最大再送時間(信頼性の無いモード)
  • maxRetransmits: 送信に失敗したメッセージの最大再送回数(信頼性の無いモード)
  • protocol: 下位のプロトコル利用が可能になる、指定したプロトコルがサポートされていない場合は失敗する
  • negotiated: trueに設定されている場合は、他方のピアとのdata channelの自動設定しない。つまり、同じidを活用して、他方のピアと、あなた自身がdata channelを作成する
  • id: チャネル向けに独自のIDを指定

ほとんどの人が使う唯一のオプションは、最初の3つです:つまり、orderedmaxRetransmitTimesmaxRetransmitsです。SCTP(全てのブラウザせ現在サポートされています)を使えば、reliableとorderedはデフォルトでtrueとなります。もし、アプリケーションレイヤを完全にコントロールしたければ、信頼性の無いモードを活用するのは理にかなっていますが、ほとんどのケースでは信頼性の有るモードが有効です。

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

安全?

暗号化はWebRTCの全ての構成要素で必須です。WebRTCDataChannelの全てのデータは、Datagram Transport Layer Security (DTLS)により、保証されます。DTLSはSSLの派生で、データは標準的なSSLベースの接続と同様の安全さになります。DTLSは標準化されており、WebRTCをサポートする全てのブラウザに搭載されています。さらなるDTLSの情報は、Wireshark wikiを確認してください。

データの考え方を変える

大量のデータをJavaScriptで扱うのは苦痛となります。Sharefestの開発者が指摘するように、データについて新しい考え方が必要となります。もし、利用可能なメモリ上限を超えてデータを転送したい場合は、データを保存するのに新しい方法を考えなければなりません。以下で示しますが、FileSystem APIのような技術になります。

ファイル共有アプリケーションの開発

RTCDataChannelを使えば、ファイルをブラウザ間で共有するWebアプリケーションが作れます。RTCDataChannel上に作るということは、転送されるデータは暗号化され、アプリケーション提供者のサーバでは、手が加えられないことを意味します。この機能性は、複数のクライアントと迅速なファイル共有の可能性を含んでおり、WebRTCによるファイル共有を有力な候補としています。

ファイル共有を成功させるために必要ないくつかのステップ

  1. File APIを活用した、JavaScriptでのファイルの読み込み
  2. RTCPeerConnectionを使ったクライアント間でのピア接続の確立
  3. RTCPeerConnectionを使ったクライアント間でのdata channelの作成

RTCDataChannelでファイルを送る際に気をつけるいくつかのポイント:

  • ファイルサイズ: ファイルサイズが小さくて、1つのBlobに保存できるのであれば、FileAPIを用いてメモリ上に読み込み、信頼性のあるchannelを用いてファイルを送ってください(ブラウザが最大送信サイズを制限していることも忘れずに)。ファイルサイズが大きくなるにつれて、やや面倒になります。チャンキング(分割)の仕組みが必要になります:ファイルチャンク(ファイルのかたまり)を読み込み、もう一方のピアへ送ります。また、受信側でどのチャンクかを認識するために、メタ情報であるチャンクIDも必要です。また、この例やファイルをユーザのディスクに保存する場合は、チャンクをオフラインストレージ(例えば、FileAPIを活用して)に、最初に保存する必要があるでしょう。
  • 速度: ファイル転送に、信頼性の無いモード(UDP同様)と信頼性の有るモード(TCP同様)のどちらを使うかは議論があるところです。もしアプリケーションが1対1の簡単なデータ転送で、信頼性の無いdata channelを使う場合は、ACK/再送プロトコルを設計する必要があります。これは自身で実装する必要があり、たとえあなたが上手くできても、信頼性のある転送よりも大して早くならないかもしれません。信頼性があり、順序を気にしない方式であれば最適でしょうが、マルチメッシュでのファイル転送においては、結果は変わるでしょう。
  • チャンクサイズ: チャンクは、あなたのアプリケーションの最小単位です。送信サイズに制限があるので(将来のdata channelでは改修される予定ですが)、チャンキングは必要です。現在の最大チャンクサイズの推奨値は、16KBです。

ひとたびデータが他方に完全に転送されてしまえば、アンカータグを用いてダウンロードできます:

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

ファイル共有アプリのpubnub.github.io/rtc-pubnub-fileshareや、github.com/Peer5/ShareFestは、このテクニックを使っています。これらはどちらもオープンソースであり、RTCDataChannelベースのファイル共有アプリの良い出発点になります。

で、何が出来るのでしょうか?

RTCDataChannelは、ファイル共有・マルチプレイヤゲーム・コンテンツデリバリのアプリケーションの新しい作成方法への扉を開いてくれます。

  • ピアツーピアのファイル共有(上述したように)
  • マルチプレイヤーゲーム:MozillaのBanana Breadのような、WebGLのような他の技術と併せて作られる
  • コンテンツデリバリ:PeerCDNピアツーピアのデータ転送を通じて、Webの要素を転送するフレームワーク)で再発明されているように

アプリケーションの構築方法を変える

今なら、高いパフォーマンスで低レイテンシのRTCDataChannelを使うことにより、より魅力的なアプリケーションを提供できます。PeerJSPubNub WebRTC SDKは、RTCDataChannelの利用を簡単にしており、多数のプラットフォームをサポートしています。

RTCDataChannelの出現は、ブラウザでのデータ転送の考え方を変えうるのです。

さらなる情報

この記事の準備にあたり、Hadar WeissとShachar Zoharの助力に感謝します。

Comments

0