WebRTC技術検証メモ
ビデオチャット機能を実装する必要が生じてWebRTCについて色々と調べているのでその記録
そもそもWebRTCとは?
ブラウザやモバイルアプリ同士でP2P通信を行うための規格。
モダンブラウザなら標準で搭載されており、javascriptでAPIを叩くことで利用できる。
(かつてはFlashやSilverLightなどのサードパーティ製ライブラリが必要だったのと対照的)
ビデオチャットに利用されることが多いが、厳密にはWebRTCはP2P通信の規格のため単なるデータ通信にも利用できる。(ビデオチャットはメディア系のAPIで取得した映像や音声をWebRTCで流している)
P2P通信であるため、原則的に通信されるデータを捌くサーバーは必要ない。(例外に関しては後述)
少し古い資料だとiOSが未対応という記述もあるようだが、現在は問題ない模様。
WebRTCに必要なもの
シグナリング
P2P通信のため、通信に関わるクライアント同士がお互いの情報を交換しなければならない。
この処理がシグナリング。
通常はシグナリングサーバーを用意してWebSocket接続を通して行うが、特にシグナリングの方法は決まっていないので方法は何でもいい。
実際サンプルでは最低限やり取りしなければいけない情報(SDP)を手動でコピペして動かしているものも結構ある。
一度つないでしまえば特に必要はない上、重いデータのやり取りもないので、
シグナリングサーバーにはそれほどのサーバーパワーは必要ない。
NAT問題への対応
P2P通信を行うためにはお互いに疎通するIPアドレスとポート番号が必要である。
お互いが同じネットワーク上にいたり、グローバルIPアドレスを単独で保持していれば問題ないものの、
実際にはお互いに別ネットワーク上におり、ブラウザやクライアントプログラムが認識しているプライベートIPアドレスと(ipconfigで見えるやつ)、外から見えるIPアドレス(こういう類のサービスで確認できる奴)が異なっていることは多い。
(ネットワークアドレス変換(NAT)が行われている)
ブラウザは自分から見えるIPアドレスしかわからないので何とかこの部分を解決して通信経路を確保しなければならない。
STUNを使う
外から自分がどのようなグローバルIPとポートで見えているのかを確認するプロトコル。
STUNサーバーに問合せを行うことで確認ができる。
処理自体は非常に軽いので、STUNサーバーもほとんど負担はなく、
googleなどが一般に公開しているものも利用できる。
TURNを使う
しかし、STUNではNATで割り振られたポートを利用するため、
Firewallで利用可能なポートをしっかりと制御している場合弾かれてしまうことがある。
このような場合には外部に中継用のサーバーを建てて、そこにアクセスするという形をとるしなかなくなる。これがTURNサーバーである。
TURNを利用するとP2P通信ではなくなり、すべてのデータがTURNサーバーを通過することになる。
つまり、TURNサーバーには強力な通信能力が要求される。
IaaSにcoturnなどを自分で建てるにせよ、SaaSを利用するにせよ通信量に応じた従量課金になる場合が多いのでコストについては注意が必要。
なるべく他の通信手段を使い、どうしようもない場合のみTURNを使うべきである。(あるいはSTUNで済まない場合は諦める)
ただし、幸いにして、ここの制御は開発者が行わなくても後述のICEという仕組みでSTUN側を優先的に選んでくれるようになっている。
なお、TURNが必要になるのはサービスの形態と利用するネットワーク(BかCか?Cでもモバイルか家庭内ネットワーク向けか?)によって異なるが、概ね1~20%の範囲の模様。
参考
ICE
Interactive Connectivity Establishmentの略。
P2P間での直接通信やSTUN、TURNなど複数の通信方法の中から最適なものを選ぶ仕組み。
基本的にはブラウザが勝手にやってくれるので、利用したいSTUNサーバーやTURNサーバーの情報を設定値として渡してやればよい。
API等
以前は必要なAPIにベンダープレフィクスがついていたものが多く、peerjsなどが求められていたようだが、
最近は標準の新APIに置き換わっているので不要。WebRTCが盛り上がっていた2015~2016年前後の資料は旧APIで書かれているものが多いので適宜読みかえる必要アリ。
サービス等
前述のシグナリングサーバーやSTUN,TURNサーバーなどとsdk一式を提供してくれるサービスもある。
国内だとSkyWay世界的にはtokboxなど。
高い接続成功率を維持したいものの、TURNサーバーなどのインフラ管理に割く労力に不安がある場合はこれらの有償サービスに頼るのが無難か。
まとめ
- APIはかなり整備されているので、コーディングは楽
- NAT越え問題だけは考えておく必要アリ。(TURNはどれだけ必要か、どう用意するのか)