導入:WebRTCで実現するリアルタイム通信の世界
「ブラウザだけでビデオ通話や画面共有ができる」――
そんなリアルタイム通信を支えているのがWebRTC(Web Real-Time Communication) です。
Google MeetやSlackのhuddleなど、多くのサービスでこの技術が使われており、SKYMENU Cloud Devicecontrol Editionでも利用しております。
基本的なところから開発中に苦労した点までを計3回に分けてわかりやすく紹介いたします。
- WebRTCの基礎を理解する(本記事)
- WebRTCの帯域制御とQuality設定 — サンプルコードを用いて紹介
- WebRTCのパフォーマンス品質の測定と監視について
WebRTCとは何か? — ブラウザでリアルタイム通信を可能にする技術
WebRTCは、ブラウザ間で 低遅延・安全・双方向 の通信を行うためのWeb標準技術です。
一般的なHTTP通信では、ブラウザは必ず中継サーバーを介してデータをやり取りしますが、 WebRTCでは中継サーバーを介さず、可能な限りブラウザ同士で直接通信します。
WebRTCには主に次の3つのAPIが関わります。
-
RTCPeerConnection:
P2P接続を確立と接続状態の管理、MediaStreamやDataChannelのデータをやり取りするための基盤を提供する -
MediaStream:
カメラやマイク、画面共有の映像・音声データを扱う -
RTCDataChannel:
ファイルやテキストなど任意のデータをやり取りする
つまり、"WebRTC = これらのAPIを使ってP2P接続を確立し、映像・音声や任意のデータをやり取りする技術 "と言えます。
リアルタイム通信の基本構成 — PeerConnectionとMediaStreamの関係
WebRTCの通信の核は RTCPeerConnectionです。これは「ブラウザ同士を直接つなぐオブジェクト」で、内部では映像や音声の圧縮・転送・再送制御などを行っています。そして、実際の映像や音声の“中身”を持つのがMediaStreamです。
例えば以下のようなコードで、ブラウザのカメラ映像を取得できます。
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
このstreamをpeerConnection.addTrack()して接続相手に送ると、相手側のブラウザでその映像が再生されます。
※端末Aから端末Bへメッセージ送信/画面共有を行うイメージ図
ポイント
- MediaStreamは データの中身
- RTCPeerConnection は通信のパイプライン
WebRTCの通信を支えるSignalingサーバーの役割
WebRTCでブラウザ同士が直接通信を始めるには、事前に“お互いの情報”を知っておく必要があります。 このお互いの情報を交換する仕組みを Signaling と言います。
WebRTCでは、適切なネットワーク経路の確保と接続後にスムーズなメディアストリーミングを実現するためにP2P接続を行うにあたり、 お互いの情報を事前に交換しておきます。
また、WebRTCそのものにはSignalingをどのようにやり取りするかまでは規定されていませんが、 接続を行うタイミングで相手にプッシュで情報を通知するためWebSocketが一般的に使用されます。このときSignalingの情報を仲介しプッシュ通知を行うサーバーを「Signalingサーバー 」と呼びます。
Signalingでは、以下の情報をブラウザ間でやり取りします。
- SDP(Session Description Protocol):
通信方式・映像コーデック・ポート情報など - ICE Candidate(Interactive Connectivity Establishment):
自分が通信できる可能性のあるネットワーク経路(IPとポート、通信プロトコルなど)の候補
このように、Signalingサーバーが「ブラウザがP2P接続を始めるための仲介人」として役割を果たします。
接続確立までの流れを理解する — SDPとICEの裏側
WebRTCで接続が確立するまでの流れを、下記図を元に追って見てみましょう。
SDPの交換
送信側はSignalingサーバー経由でSDPを受信側へoffer(提案)として送信します。受信側はSDPを受け取った後、自分側の設定情報をanswer(応答)として返します。

ICE Candidateの交換~接続確立
後述するSTUNサーバーを使って「自分が通信できるネットワーク経路」を探し出し、相手に送ります。

- onicecandidate:
ICE Candidatesが生成された時発火するイベントハンドラ ローカルSDPの設定がなされるとICE Candidatesの生成が裏で行われて発火する
- addIceCandidate:
相手から送られてきた接続情報を接続候補として追加する 最適な経路が見つかりP2P接続が確立すると、 映像や音声のデータが直接ブラウザ間で流れ始めます。
この一連の流れは、ブラウザ内部では非同期で進行しており、 どのタイミングでCandidateが届くかなどはネットワーク状況によって変わります。
STUN/TURNサーバーの役割 — NAT越えの壁を乗り越える
家庭や企業のネットワークでは、多くの場合ルーター(NAT)配下にいます。 そのままでは外部から通信が届かないため (例:NATのセキュリティレベルが高い、FirewallやプロキシサーバーがWebRTC通信をブロックし直接通信できない)、STUN/TURNサーバーが助けてくれます。
- STUNサーバー:
自分のグローバルIPとポート番号を調べ、NAT越えのための候補の生成 - TURNサーバー:
P2Pが無理なときに中継役をする(リレー)
個人で試したい程度であれば、以下のようにGoogleが提供している無料STUNサーバーを使うこともできます。
const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
TURNサーバーはトラフィックを中継するため、単純にP2P方式で通信する場合よりも負荷やコストが高くなります。また、大規模配信を想定する場合は、より効率的な配信を行うためにSFU導入を検討します。
※ SFU(Selective Forwarding Unit) は、複数のクライアント間でのメディアデータをサーバーを中継して配信する通信技術の事です
まとめ:WebRTCの通信フロー
ここまで紹介した要素をつなげて簡単にまとめると、以下のようなフローになります。

このように、Signalingサーバーは「最初の仲介」をおこない、以降はブラウザ同士が直接データをやり取りする事が可能になります。この仕組みにより、WebRTCの最大の特徴である「低遅延・高効率なリアルタイム通信」を実現しています。
次記事・・・
使用帯域を指定して画面共有する方法をサンプルコードを用いて解説していきます

