ステートレスなWebRTCシグナリングサーバーは存在できるのか問題
基本的にWebRTCの用途はかなり限定的というかDTLS APIとしてしか使っていない。なのでWebTransport ...はあんまり実現が近そうな気がしないけど、とにかくブラウザ間のP2P手段が揃ってくるまでの繋ぎでしか無いんだし適当でも良いんではないか。
前提
P2Pである 。使うものはDatachannelのみ、かつ、マルチキャストが無いのでP2Pのみの実装で良い。
TURNしない -- 基本的にLAN内接続でしか使用しないし、TURNが必要なケースでは自前のforwarderにフォールバックする方が簡単。
〜 500ユーザ程度にスケールすれば良い 。Twitterのフォロワー全員集合くらいの規模で十分でしょ多分。SkyWayとかTwilioのようなマネージドサービスでもTURNやSFUしないならば事実上タダに近いので、ある程度以上ユーザが集りそうならそれらを採用すれば良い。
このため iceServers
はSTUNだけで良い。stun.stunprotocol.org
や Google( stun.l.google.com:19302
)やTwilio https://www.twilio.com/docs/stun-turn が無料のSTUNサーバを提供しているので、STUNサーバについては自前で用意する必要がない(のでグローバルIPv4アドレスを用意する必要もない)。
そもそもシグナリングに何が必要なのか?
P2PケースでのWebRTCのシグナリングは特に特殊なプロトコルは要求しておらず、単に未加工のメッセージを2台の間で交換できれば十分と言える。
Piping-server で十分か?
原理的には、POSTされたメッセージをGETしてきたクライアントに横流しするだけのPiping-server https://github.com/nwtgck/piping-server で求めていることが実現できるように思える。
が、メッセージの横取りを防ぐためには認証が必要になり、そのために一時的なステートが必要になる。
WebSocketのパイプ
今のところ、 fetch
で WritableStream を扱うのはChromeの特権になっている。Firefoxは興味有というところだが現状は実装されていない。
まぁ今回の場合は通常のHTTPとの互換性は全く必要ないので、Web Socketのpipeが実現されていると考える。
サーバー ws-pipe
のWebSocket wss://ws-pipe/<エンドポイント名>
に2つのホスト A
B
が接続すると、 ws-pipe
はそれぞれの通信内容をリレーするものとする。
ws-pipe
サーバーは2つのTLS接続ぶんのステートさえ保持すれば十分ということになる。
WebRTCのシグナリングを成立するためには、ここで通信する内容をJSONの連続と約束し、そこにICEメッセージを載せて適宜交換してやる必要がある。 ws-pipe
サーバ自体にはメッセージの知識は必要ない。
エンドポイント名とその使用権の配付
エンドポイント名はランダム文字列でも良いが、ws-pipeサーバー自体をabuseされると困った事になるので:
- 接続のUUID (本来の意味でのエンドポイント名)
- 転送量上限 (256KiBくらいか -- 超過したらws-pipeサーバー側から両者を切断する)
をJWTにエンコードし、管理サーバーの秘密鍵で署名して A
や B
に配付することにする。 ws-pipeサーバーはJWTを管理サーバーの公開鍵で検証して、正当であれば接続を受け入れる。
A
や B
に配付されたJWTを横取りされたらゲームオーバーになるが、TLS経由かつ相手が正当な証明書を持っていればMITMされることは無いので大きな問題ではない。