WebSocket から WebRTC DataChannel へのマイグレーション (2) 完結

DataChannel 活用の道

V
6 min readApr 2, 2021

前回から少し間が開いてしまったが、続きを書いていく。

前回の振り返り

WebRTC SFU のシグナリングは WebSocket をつかっているが HoL Blocking が起きたり、切断しやすいため、DataChannel をシグナリングに利用したい。

最初の接続だけ WebSocket を利用し、その後は DataChannel を利用する仕組みを実現したい。

WebRTC SFU をメディアだけでなくデータのルーター、つまりメッセージルータとしても使えるようにしていきたい。

SCTP 自前実装

SCTP の機能は一通り実装して、さらに SCTP 拡張である Reconfig にも対応した。Reconfig は DataChannel のストリーム毎の close に対応するために必要。

ShutdownChunk や AbortChunk だと SCTP 自体がすべて閉じてしまうので、使えない。

DataChannel 実装現状

  • SCTP で順番保証 (再送含む) は実装済み
  • 細かいエラーハンドリングやタイマー処理がまだ終わっていない
  • 悪意あるパケットへの対策がまだ終わっていない
  • DataChannel で複数チャネルを開く仕組みは実装済み
  • DataChannel で複数チャネルを閉じる仕組みは実装済み
  • DataChannel 経由でのグレイスフルシャットダウンは実装済み

意図的な制限

クライアント側から createDataChannel を行え仕組みを入れる予定で、これは WebRTC 的には仕様から外れる。ただ勝手に DataChannel を作られると WebRTC SFU 側で処理に困るというのがある。本来は DataCHannel をクライアントが作ったら、接続しているクライアント全員に ondatachannel が上がるという仕組みがよいのだろうが、悪意ある攻撃がし放題になってしまうので、デフェンシブに実装することにした。

WebSocket から DataChannel の切り替え

切り替えの仕組みは前もっていろいろ準備しておいたので簡単に切り替えられた。

WebSocket の onclose が上がった後に通知を DataChannel 経由でプッシュで受け取っている

シグナリングに利用する DataChannel が確立したタイミングで WebSocket を「DataChannelへの切り替え」とい切断理由(とコード)で切断し、クライアント側で WebSocket の終了処理だけして、PeerConnection に関しては処理しない。

DataChannel であれば HoL Blocking におびえる必要がないのは本当に大きい。

DataChannel のグレイスフルシャットダウン

DataChannel を扱っている場合にグレイスフルシャットダウンを行うためにはまずここのデータチャネルをすべて close する必要がある。このためには前述した Reconfig を投げる必要がある。すべてのデータチャネルを終了させ、その後 SCTP を Shutdown / ShutdownAck / ShutdownComplete でシャットダウンし、最後に DTLS を alert Close Notify で終了する事で綺麗に終了することができる。

もちろんクライアント側がブラウザやアプリを落としたときは DTLS Close Notify が飛んでくればいいがそれに気付けない場合は SCTP の Heartbeat で気付くか、 DataChannel 上の Ping/Pong を利用して終了するか、ICE の STUN Binding Request の応答をみるなど、いろいろな方法があるのでそこは「なんとかして綺麗に終了させる」が大事になる。

DataChannel を利用したグレイスフルシャットダウン

これはクライアントから type: disconnect メッセージを WebRTC SFU に送ってサーバ側からシャットダウン処理を走らせているログだ。綺麗に終了できていることがわかる。DataChannel の onerror も上がっていない。

今後

今後はまず WebSocket から DataChannel への切り替えを商用で利用可能なレベルまで持って行く。その後は DataChannel を利用したメッセージングをクライアントが利用できるようにしたいと考えている。リアルタイムメッセージング機能を Sora に積んでいきたい。

実は E2EE で WebSocket でメッセージング機能を積んである。ただこれはかなり限定的な実装になっている。それを MQTT の DataChannel 版のような仕組みを用意できればと考えている。まさか MQTT Broker を開発した経験がここで生きることになるとは … 。

WebSocket から WebRTC DataChannel へのマイグレーションは無事成功したので、この連載はこれで終了になる。

今後は “WebRTC SFU DataChannel 対応” が (2) までしか書けていないのでそちらの続きを書いていきたいと思う。

WebTransport 対応

WebTransport などが今後出てくるが、残念ながらこれらはまだフォールバックが明確ではない。DataChannel の強みは TURN を利用したフォールバック機能にある。またもう 10 年以上使われており枯れているというのもあるだろう。

WebTransport にも対応はしていくが、DataChannel と併用できるようにしていくつもりだ。

--

--

V
V

No responses yet