WebRTC における QUIC がもともとは DataChannel を置き換える予定だったが、どうやら完全に別物で進みそうということがわかったので、DataChannel を取りあえず WebRTC SFU Sora で使えるようにするというのを進めている。
WebRTC DataChannel について
WebRTC の DataChannel というのは、音声や映像以外のデータを送る仕組み。文字列だったりバイナリだったり。
利用されているプロトコルは SCTP という UDP と TCP のいいところをかけ合わせた歴史の古いプロトコル。それを DTLS というデータグラム向け TLS で暗号化して、さらに UDP 上でやりとりをするというのが基本戦略。
SCTP 上に DataChannel 拡張を用意しているので、厳密に書くのであれば DataChannel over SCTP over DTLS over UDP という事になる。
カーネルランドではなくユーザランドで SCTP を利用するので思っている以上に複雑というのが現状。
DataChannel の使い所は P2P
何でも載せられるので、汎用性は高いがそれこそサーバ経由であれば SFU ではなく WebSocket でいいのではとなりがちなのが現実。
とはいえ、 1:N に対してデータを流し込む、それも安定的に低遅延で配信可能というのは魅力的である。
DataChannel は順番通りかどうかを選べたり、リトライ回数を指定できたり、リトライ時間を指定できたりとかなり融通が聞く仕組みになっている。それもチャネル単位でできるので優秀だ。
つまり 1 RTCPeerConnection で複数のチャネルが保持でき、さらにはそのチャネルごとに再送時間や順番通りかどうかが指定可能になる。とはいえ、WebSocket で事足りることが 99% になる。
DataChannel は SFU ではなく P2P で生きる技術だと思っている。実際 Peer5 などのような P2P CDN は DataChannel を利用して大規模配信に P2P を持ち込んで負荷を削減したりしている。
DataChannel をなぜ SFU に持ち込むのか
ではなぜ DataChannel を SFU に持ち込もうとしているのか。方針としては2つある。
一つは WebSocket シグナリングの代わりに DataChannel シグナリングを利用したい。WebSocket は TCP ということありどうしても切断に弱い。DataChannel で TURN-TCP/TLS が使われてさえ居なければ切断には強い。
もう一つが組み込み向けの Native Client との連携だ。Native Client から映像や音声を受け取り、DataChannel 経由で Native Client にデータを送るというのは別に変な話ではない。
むしろ HoL Blocking が起きないデータ送信技術は色々な場面で有効になる可能性は一応ある。
主にロボットや自動運転、監視カメラなどで利用してほしいという思いがあったりもする。無理に使って貰う必要はないが。
SFU 経由での DataChannel の課題
DataChannel の何がいけてないかというと、パーミッションという概念が一切ない。P2P ということもあり、双方向でデータを送り放題モデルになっている。
P2P なら被害は 1 名だけだからいいかもしれないが、さすがに SFU 経由だとそうは行かない。そもそも WebSocket だって SFU で利用する場合はクライアントから自由に送れるようになんてしないだろう。というかしたら危ない。
WebRTC SFU Sora は WebSocket 経由のメッセージは決められたデータしか送れない。ただし Sora の HTTP API を利用することで WebSocket 経由でメッセージは送れる。あくまで HTTP API 経由だけだ。
そのため DataChannel を SFU で有効にするにはパーミッションを宣言して認証してする仕組みを用意する必要がある。DataChannel は前述したとおり複数のチャネルを利用できるので 1 チャネルにつき 1 つ配信、視聴、配信と視聴の 3 タイプから選んでもらうことになる。
配信を選んだ場合は視聴はできない。視聴を選んだ場合は配信はできない、といった感じになる。
コレを実装しないと DataChannel は好き勝手にデータが送れてしまうので SFU が大変なことになる。
SFU 経由での DataChannel パーミッション
完全に MQTT を思い出しているが、そっと忘れることにする。複数チャネルを実装して片方向だけに絞るというのがまず最初。
チャネルの指定は {“label”: “spam”, “role”: “pub”} や {“label”: “egg”, “role”: “sub”} という感じ。その後、双方向を可能にする。
{“label”: “ham”, “role”: “pubsub”} という指定をするとそのチャネルは双方向にデータが送れるようになる。
これらを全て認証で判断できるようにし、想定外のパケットが送られてきたタイミングでその接続を切断してしまうとうい仕組みにする。
WebRTC SFU と DataChannel の今後
QUIC や WebTransport に置き換わるのは 1 年とかのスパンではないだろう。数年という時間をかけてゆっくり置き換わっていくことを考えると DataChannel が必要とされることはあるかもしれない。
実際 SFU に DataChannel を乗せれば、それを QUIC にするのは QUIC スタックさえあれば、それほど大変ではないだろう。SDP を使わなくなるのは面倒事が増えるというのが正直なところだが。
WebRTC SFU Sora の DataChannel の実装現状
片方向限定だが実装はできている。とはいえ SDK は一切対応していないので、要注意。
今後は次のリリースで、最低限動く 1:N で利用できるようにと考えてはいるがどうなるかはわからない。まずは安定して使えるものを用意できるように、開発を進めていく。