====================================== データチャネルを利用したデータの送受信 ====================================== この章では、データチャネル API (``RTCDataChannel``) を利用したデータの送受信について説明します。 概要 ==== データチャネルは、ピア接続間で任意のデータを送受信するための機能です。 ``RTCPeerConnection`` 自身でやりとりするデータ形式以外(テキスト、バイナリ等)を扱うことができます。 データチャネルは ``RTCPeerConnection`` に紐付ける形で作成・管理を行います。 1つのピア接続に対して複数のデータチャネルを紐付けることが可能です。 データチャネルを作成する ======================== ``RTCPeerConnection`` の以下のメソッドでデータチャネルを新規に生成できます。 - ``createDataChannel(label [,options])`` 第1引数にはデータチャネルの識別子となるラベルを文字列で指定します。 データチャネルが所属するピア接続において、複数の異なるデータチャネルに対して同一のラベルは使えません。 例: データチャネルを生成する .. code-block:: javascript var pc = new RTCPeerConnection(); pc.createDataChannel("spam"); 第2引数ではオプションを指定します。(省略可) 指定できるオプションは以下の通りです。 ``maxPacketLifeTime`` と ``maxRetransmits`` を同時に指定することはできません。 - ``id``: データチャネルの固有 ID を表します。 - ``ordered``: メッセージの送信順序を保証するかどうかのフラグを表します。 - ``maxPacketLifeTime``: メッセージの送信に成功するまで再送を繰り返す時間(ミリ秒)を表します。この時間を過ぎても送信に失敗する場合、再送が止められます。 - ``maxRetransmits``: メッセージの最大再送信回数を示す数値を表します。 - ``protocol``: 利用する sub protocol を表します。 - ``negotiated``: 利用側のアプリケーションがこのデータチャネルをネゴシエーションしたかどうかのフラグを表します。 例: データチャネルをオプションを指定して生成する .. code-block:: javascript var pc = new RTCPeerConnection(); pc.createDataChannel("spam", { ordered: true, maxRetransmits: 10000}); データチャネルが作成された通知を受け取る ======================================== ピアでの接続を行っていて、リモートでデータチャネルが新規に作成された際、 ``RTCPeerConnection`` の ``ondatachannel`` イベントが発火します。 例: リモートでデータチャネルが生成されたときのコールバックを登録する .. code-block:: javascript const pc = new RTCPeerConnection(); pc.ondatachannel = (event) => { console.log("# ondatachannel, label=>", event.channel.label); }; データチャネルの接続状態 ======================== ``RTCDataChannel`` の接続状態は、 ``readyState`` プロパティに格納されています。 ``readyState`` の値は以下のいずれかとなります。初期状態は ``opening`` です。 - ``opening`` - ``open`` - ``closing`` - ``closed`` 接続状態(``readyState``)が変更された際は以下のイベントが発火します。 各イベントの詳細については `API リファレンス `_ を参照してください。 - ``onopen``: ``readyState`` が ``open`` になったときに発火します。 - ``onclosing``: ``readyState`` が ``closing`` になったときに発火します。 - ``onclose`` : ``readyState`` が ``closed`` になったときに発火します。 例: データチャネルの接続状態が変更されたときのコールバックを登録する .. code-block:: javascript const pc = new RTCPeerConnection(); const dataChannel = await pc.createDataChannel("spam", {ordered: true}); dataChannel.onopen = (event) => { console.log("# datachannel onopen"); }; dataChannel.onclosing = (event) => { console.log("# datachannel onclosing"); }; dataChannel.onclose = (event) => { console.log("# datachannel onclose"); }; データを送信する ================ ``RTCDataChannel`` の以下のメソッドでデータを送信できます。 - ``send(data)`` 送信できる ``data`` の型は ``string``, ``ArrayBuffer``, ``ArrayBufferView`` のいずれかです。 例: データチャネルで文字列データを送信する .. code-block:: javascript const pc = new RTCPeerConnection(); const dataChannel = await pc.createDataChannel("myLabel", {ordered: true}); dataChannel.onopen = (event) => { await dataChannel.send("egg"); }; データを受信する ================ リモートからデータを受信した際、 ``RTCDataChannel`` の ``onmessage`` イベントが発火します。 ``onmessage`` イベントの詳細については `API リファレンス `_ を参照してください。 例: データチャネルでメッセージを受け取ったときのコールバックを登録する .. code-block:: javascript const pc = new RTCPeerConnection(); ... const dataChannel = await pc.createDataChannel("myLabel", {ordered: true}); dataChannel.onmessage = (event) => { console.log("# datachannel onmessage, is binary data=>", event.binary); console.log("# datachannel onmessage, data =>", event.data); } データチャネルを閉じる ====================== データチャネルの接続を閉じるには、 ``RTCDataChannel`` の以下のメソッドを呼び出します。 - ``close()`` 複数のデータチャネルを管理する ============================== ``RTCDataChannel`` の ``label`` プロパティの値を識別子として用いることで、 一つのピア接続に対して複数のデータチャネルを発行・管理することができます。 例: 複数のデータチャネルを発行する .. code-block:: javascript const pc = new RTCPeerConnection(); const labelChannel1 = "spam"; const labelChannel2 = "egg"; (async function() { // 1 本目の dataChannel と event handler を登録 const channel1 = await pc.createDataChannel(labelChannel1, {ordered: true}); channel1.onopen = (event) => { console.log("channel1 onopen"); } channel1.onclose = (event) => { console.log("channel1 onclose"); } channel1.onmessage = (event) => { console.log("channel1 onmessage =>", event.data); } // 2 本目の dataChannel と event handler を登録 const channel2 = await pc.createDataChannel(labelChannel2, {ordered: false}); channel2.onopen = (event) => { console.log("channel2 onopen"); } channel2.onclose = (event) => { console.log("channel2 onclose"); } channel2.onmessage = (event) => { console.log("channel2 onmessage =>", event.data); } })(); 例: リモートで発行された複数のデータチャネルを管理する .. code-block:: javascript const pc = new RTCPeerConnection(); const labelChannel1 = "spam"; const labelChannel2 = "egg"; pc.ondatachannel = (event) => { console.log("ondatachannel label=>", event.channel.label); if (event.channel.label === labelChannel1) { // 1 本目 // event handler を登録 event.channel.onopen = (event) => { console.log("channel1 onopen"); } event.channel.onclose = (event) => { console.log("channel1 onclose"); } event.channel.onmessage = (messageEvent) => { console.log("channel1 onmessage =>", messageEvent.data); } return; } if (event.channel.label === labelChannel2) { // 2 本目 // event handler を登録 event.channel.onopen = (event) => { console.log("channel2 onopen"); } event.channel.onclose = (event) => { console.log("channel2 onclose"); } event.channel.onmessage = (messageEvent) => { console.log("channel2 onmessage =>", messageEvent.data); } return; } console.log("unknown datachannel"); } ``onbufferedamountlow`` イベントと ``bufferedAmountLowThreshold`` プロパティについて ==================================================================================== ``RTCDataChannel`` オブジェクトの未送信データのバイトサイズは ``bufferedAmount`` プロパティに格納されています。 この未送信データのバイトサイズのしきい値として ``bufferedAmountLowThreshold`` プロパティを利用します。 ``bufferedAmount`` が ``bufferedAmountLowThreshold`` の値以下になったとき、 ``onbufferedamountlow`` イベントが発火します。 ``bufferedAmountLowThreshold`` プロパティの初期値は ``0`` です。 ``onbufferedamountlow`` イベントの詳細については `API リファレンス `_ を参照してください。 例: 未送信データのバイトサイズが ``2048`` 以下になったときのコールバックを登録する .. code-block:: javascript const pc = new RTCPeerConnection(); const dataChannel = await pc.createDataChannel("spam", {ordered: true}); dataChannel.bufferedAmountLowThreshold = 2048; dataChannel.onbufferedamountlow = (event) => { console.log("# datachannel onbufferedamountlow, bufferedAmount=>", dataChannel.bufferedAmount); }; データ形式(``binaryType``)について ================================== Web API では ``RTCDataChannel`` オブジェクトの ``binaryType`` プロパティに ``blob`` または ``arraybuffer`` を指定することで 送受信するデータの形式を指定できますが、本ライブラリでは ``arraybuffer`` のみサポートしています。 ``blob`` を指定することは出来ないので、注意してください。 Android で利用する際の注意点 ============================ Android の場合、 ``RTCDataChannel`` オブジェクトから以下のプロパティの取得を行えないので、注意してください。 - ``ordered`` - ``maxPacketLifeTime`` - ``maxRetransmits`` - ``protocol`` - ``negotiated``