はじめに
この記事は CyberAgent 19新卒 エンジニア Advent Calendar 2018 23日目の記事です。
自分自身、昔webRTCを使った業務を任されていたのでそこに関してざっくり共有していきたいと思います。
正直レイヤーはちょっと低めですが、個人的にここら辺が自分の中で腑に落ちた頃には普段あまり気にしていなかったドメインにも知見が得られたので知っておいて損はないです。
webRTCとは
webRTCとはビデオチャットなどをサーバを介さずにやり取りできるAPI
ですが実際は裏で色々なサーバが動いていたり、ビデオチャットしかできないわけじゃなかったりします。
ビデオチャットなど
実はwebRTCは大きく分けると二つのチャンネルが存在します。
一つ目がメディアチャネル。いわゆるビデオチャットができるチャンネルです。
もう一つがデータチャネル。これはバイト列を送受信できるチャンネルです。
例えば、ビデオチャットでありがちな「○○さんが入室しました」なんてメッセージを送れます。その気になれば音声データだってフーリエ変換すれば送れるので、データチャネルを使ってメディアチャネルっぽい挙動をさせることもできるはずです。
この二つの大きな違いは通信規格にあります。
メディアチャネルはSRTPという音声や映像情報をパケット化してsecureに送受信できるプロトコルを使っている一方、データチャネルはSCTPという、UDPの小さいオーバーヘッドとTCPの信頼性を融合させたハイブリッドなプロトコルwを使っています。googleが開発したQUICと似てますね。
ちなみにこのSCTP、もっと流行ってもいいと思うんですがこれが流行っていない理由としてはNATにあります。NATは基本的に自分の知らないプロトコル(トランスポート層のTCP/UDP)以外はパケットを破棄してしまう性質があるため、同じトランスポート層のSCTPはNATを超えられず使われていません。
しかしwebRTCは、UDP上にあるDTLS(データグラム指向のTLS)の上にSCTPを実装することで、NATにとってはまるでUDPであるかのように振る舞うことでこの問題を解決しています。
osi参照モデルではSCTPはトランスポート層ですが、webRTCではTLSの上なのでトランスポート層よりも上にいることになります。webRTCは必ずしもosi参照モデルに則って作られているわけではないということです。
こんなように、webRTC = ビデオチャットではなく、ビデオチャット ∈ webRTCだよっていう話です。
ちなみに最近話題のライブ配信サービス系の配信基盤はHLSという、細切れの映像をwebサーバに絶えず投げることで全世界で同じ映像を視聴することができるプロトコルを使っているのでwebRTCとは違います。単純に数万人をP2P通信させるとか鬼畜。
サーバを介さず
webRTCは、ブラウザ同士でデータのやり取りができます。これをP2P通信って言います。
確かに、データのやり取り自体はサーバを介さずにできます。ただしこれは、通信相手のglobalIPや通信経路を事前に取得している状態になって初めて可能になります。逆に言うと、通信相手のglobalIPや通信経路を取得していないとデータのやり取りができません。これらの情報を事前に取得するために裏でサーバが3台動いています。
- STUNサーバ
- TURNサーバ
- シグナリングサーバ
STUNサーバでglobalIPを取得して、TURNサーバでそのIPをもとにグローバルな世界に代理人を立てて代理人同士でやり取りができるようになります。俗に言うNAT超えをこの2つのサーバで実現しています。そうして得た相手のPeer情報(SDP)や通信経路(ICE Candidate)を特定し、取得した通信相手情報をシグナリングサーバでお互いに交換することでP2P通信が成立します。
実はwebRTCにはP2P通信でのやり取りだけではなくビデオ会議とか少し大人数向けのユースケースでは、参加者は映像や音声をサーバとやりとりするSFUや、サーバサイドで音声や映像を合成して参加者全員に配るMCUといったサーバを介したP2P通信っぽいこともできたりします。SFUの方がもちろんサーバ負荷は低いのでこっちの方が使われているのかな。
まとめ
結果、最初の文をこれらを踏まえて書き換えると
webRTCとはビデオチャットやテキストメッセージを、(サーバを介して通信相手の情報を取得した後)サーバを介さずにやり取りできるAPI
になるかと思います。
個人開発としてのミニマムなビデオ通話くらいなら小一時間あればすぐに通話くらいはできちゃうくらい簡単なのでぜひ。
なにか不備な点などありましたらコメントにてお待ちしております。