WebRTC SFU Sora と WebRTC DataChannel

V
shiguredo
Published in
7 min readJun 6, 2021

2021 年 6 月にリリースされる Sora 2021.1 で DataChannel に対応します。これから出発点という感じではありますが、WebRTC SFU Sora の DataChannel 機能の今と今後について雑に書いていきます。

まとめ

  • WebRTC SFU Sora は DataChannel にがっつり取り組んでいきます
  • DataChannel を自由に利用できる仕組みを提供します
  • Sora SDK も DataChannel に対応していきます

WebRTC DataChannel

DataChannel とは DataChannel over SCTP over DTLS over UDP です。UDP 上に DTLS のトンネルを作り、その上でユーザランドの SCTP を動かし、その上に DCEP (Data Channel Establishment Protocol) で SCTP Stream ID と label を紐付け、再送回数や再送時間、順序、終了などを SCTP 拡張を利用して実現しています。

簡単に言えば小さなメッセージを安全に再送を指定して送れる機能です。

WebRTC SFU における DataChannel

MediaChannel もそうですが、基本的に DataChannel は P2P 上の動作を想定しているため、SFU のような PubSub 的な仕組みを利用する場合は、色々注意が必要になります。

このあたりの細かい話は別記事として書いてありますので、興味がある人はどうぞ。

WebRTC SFU Sora における DataChannel

Sora ではもともと DataChannel には否定的でした。ただ、多くの環境で使われるにつれ「WebSocket に依存する限界」がでてきました。簡単にいえばメインである音声や映像を UDP で扱っているのに、シグナリングを TCP で扱っているため、シグナリングが不安定な回線に弱いということです。

これを解決するため SCTP の本来の利用用途である「シグナリング」で DataChannel を使うという方針を決めました。

言うのは簡単ですが、DataChannel を実装するのはそんなに簡単な話ではありません。時雨堂ではプロトコルライブラリは 1 から自分たちで書くという方針をとっています。そのため SCTP を位置から書く必要がありました。もちろん「シグナリング」というコアな部分を任せるため、商用レベル品質は前提です。

Sora の DataChannel 実装の初回リリース

初回リリースでは「WebSocket で行えたことは全て行えるようにする」に絞りました。

そのため DataChannel の特徴である「部分信頼性」と「順不同」については初回リリースでは諦めるという方針をとりました。さらに SCTP 拡張を利用する 1G といった巨大なメッセージを送るための仕組みも見送りました。さらに利用側が好きにメッセージを送れるようになる仕組みも見送りました。

WebSocket から DataChannel に切り替える

初回リリースで重点に置いたのは、WebSocket から DataChannel に置き換えるという機能です。特に「互換性」を重視しました。

大事なのは今まで WebSocket で困っていなかった人たちはそのまま利用できること。DataChannel を使いたい人は気軽に使えるという事です。

そのためシグナリングのメッセージとして type: switched という「シグナリングが DataChannel に切り替わった事をクライアントに伝える」というメッセージを用意しました。

これを受け取ったらそれ以降は全て DataChannel でメッセージのやりとりを行えるようになります。これを受け取るまでは今までと同じです。

WebSocket の重要性

DataChannel への切り替える場合に気になっていたのは「SCTP のユーザランドでの管理」です。簡単に言えば「切断」をユーザランド側で気付く必要があるということです。WebSocket であれば TCP なので、ユーザ側ではなくカーネル側で管理してくれます。

WebRTC SFU にとって「切断」に気付くということはとても重要です。誰かが退室した事をすぐに他の参加者に通知して SDP の再交換が必要になるからです。他にも E2EE であれば切断のタイミングで残っている参加者は鍵交換が必要になります。

そのため WebSocket は「切断検知」という名目で繋ぎっぱなしをデフォルトとすることにしました。

ただ、それだと TCP が切れるような不安定な環境では DataChannel を利用したにもかかわらず今までと変わりません。そのため「WebSocket を切断検知として判断するかどうか」をクライアント側で指定可能にしました。

WebSocket を切断検知として利用しない場合は、SCTP のエンドポイント障害検知のみが切断条件となります。ちなみにこの SCTP の機能はクライアントだとうまく動かないことがわかっており、Sora 側で対応した機能です。

DataChannel に切り替えてどうだったか

検証ではパケロス 40% でも運が悪くなければ接続し続けられるシグナリングを得られました。WebSocket ではどう頑張っても無理な状況でしょう。

最初の目的である「ネットワークが不安定な環境」でもつながり続けるシグナリングは手に入れました。

さらに DataChannel はどうやら、思った以上によく考えられた仕組みだということが実装してわかりました。ただ、SCTP 拡張に依存しているため実装はかなり大変です。

DataChannel におけるメッセージの圧縮の重要性

DataChannel は UDP で動作するため、1200 バイト以上のメッセージを送る場合は 1200 バイト単位で区切って送るように SCTP がうまいことやります。そのため、メッセージの圧縮がかなり聞いてきます。

実際シグナリングで利用する SDP を zlib/deflate で圧縮してみたところ 1/4 まで圧縮されることがわかりました。4000 バイトが 1000 バイトで送る事ができるのは驚異的です。

そのため Sora ではメッセージ圧縮機能を標準で搭載しています。SDP や JSON を圧縮してクライアント側で展開して利用できるようにします。

Sora の DataChannel の今後

まず、年内のリリースで再送時間、再総数、順不同に対応します。また、メッセージング機能を追加し、クライアントから自由にチャネルの他のクライアントにメッセージを送れる仕組みを用意する予定です。

DataChannel のメッセージング機能は MQTT のような仕組みを検討しています。リアルタイムメッセージ over DataChannel を Sora で実現することで、音声や映像だけでない、メッセージの分野にも手を広げて行ければと考えています。

Sora SDK や Momo の DataChannel 対応

Sora 2021.1 リリース時には JavaScript SDK のみが対応となりますが、年内には iOS / Andoird / Unity SDK 、さらに Momo も全て DataChannel へ対応していきます。

--

--