この記事はOIC ITCreate Club Advent Calendar 2018 19日目です
昨日はhirokiさんでした
トラコン1次予選にWebRTCの問題があったのですけど、解説を今読んでみたら余りにクソチョロ過ぎて泣いてました。その当時は名前しか存じ上げなかったのでしょうがないね。
http://icttoracon.net/tech-blog/2018/08/27/ictsc2018-prep01-webrtc-p/
2問目がDataChannelに関するものでした、これはDataChannelを扱う時に陥りがちな罠ではないかと個人的に感じたので、今日はその話を含めてWebRTCのDataChannelの話をします。
あとトラコン2次予選は土曜日にやりましたけど12位でした 激!激!激!激クソ
49チーム中12位だったので我々は良い結果を残したと思い込んでおきます。
対象者
これを3周くらい読んでいる人
最高の本なので買ってください。
DataChannel
WebRTCには映像/音声を送受信するMediaChannelと、それ以外のデータも送受信できるDataChannelがあります。
JavaScriptにおいて、DataChannelで扱えるデータ型は次の4つです。
- String
- Binary Large Object (Blob)
- ArrayBuffer
- ArrayBufferView
ちなみにChromeでBlobをDataChannelで投げようとしたら「実装してない」って怒られました。泣いてます。
他のブラウザでは試していませんが、少なくともChrome70ではBlobをArrayBufferに変換して送信する必要があります。
使い方
Offer視点
WebRTCのコネクションを確立
SDPを投げ合ってP2Pコネクションを確立するところまでは省略します。
ただ、注意点が一つだけあって、必ずPeerに対するDataChannelを作成してからOfferSDPを生成する必要があります。これがトラコン1次予選で出題された罠です。
1 | const dataChannel = peer.createDataChannel("hoge"); |
DataChannelを作っておかないとスッカラカンのSDPが生成されるため、対向Peerと正常にネゴシエーションが出来ません。
MediaChannelの場合も同様に、Offer生成前にPeerに対してTrackを投入しておく必要があります。
1 | localStream.getTracks().forEach(track => { |
イベントハンドラ
dataChannelが作成された後は、次のようなイベントハンドラで処理できます。
1 | dataChannel.onopen = (ev) => { |
Answer視点
peer.ondatachannelの発火を待つ
Offer側でDataChannelが作成されると、Answer側ではondatachannel
が発火します。
OfferSDPを貰ったタイミングでAnswer側でもDataChannelを作ることはできますが、DataChannelを双方で2本張る必要があるかと言うと怪しいところです。
1 | peer.ondatachannel = (ev) => { |
イベントハンドラはOfferで扱うものと同じです。
Answer側は少し特殊で、ondatachannelの引数(ev: Event)からdataChannelを取り出すという手間があります。それだけです。
チラ裏
DataChannelに関する資料はMediaChannelと比べると少ないですが、例えばWebTorrentではWebRTCのDataChannelが使われていますし、P2P CDNのPeer5でもDataChannelが使われています。
WebRTCでは映像/音声に限らず、あらゆるデータをサーバレスで送る事が出来るので、他にも色々な用途で使えそうです。
あと最近初めて参加させてもらった学生LTでも少しだけWebRTCの話をしたのですが、割とウケたので助かりました。
P2Pは夢があっていいですね。
夢はありますが大抵よからぬことに使われるの本当に泣く。
明日はelipmocです。C++からRustの紹介記事になっていました。やっぱりわからん(わかりたい)