【初心者向け】P2Pを知らない１ヶ月前の自分にWebRTCを説明してみる

## この記事の内容
Webアプリ開発の基礎を学んだばかりの初心者エンジニアです。
最近、WebRTCについて調査する機会があったので、整理を兼ねてWebRTCの仕組みをまとめてみました。
自分と同じような初心者エンジニアの方のお役に立てれば幸いです。

## WebRTCって何？
WebRTC（Web Real-Time Communication）とは、ブラウザ間でリアルタイムにデータをやり取りする仕組みのこと。web会議アプリなどに利用されている仕組みです。
![RTC図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/2544a286-dc98-d533-0952-96560bcc7bc3.png)

## WebRTCの特徴
Webアプリというと、クライアントとサーバー間のリクエスト・レスポンス型の通信を思い浮かべます。しかし、WebRTCの場合は、サーバーを介さず、ブラウザ同士が直接データを送受信するP2P<sup>※1</sup>で通信しています。これがWebRTCの最大の特徴です。
※１．P2P（Peer to Peer）とは、複数の端末同士がサーバーを介さずに直接通信する技術。

## WebRTCの基本的な仕組み
WebRTCでのデータ通信は、以下のステップで成立します。
![RTC図2-F.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/b606c556-7609-02cc-95fc-b20139029e47.png)



#### ステップ１．P2P通信の準備
ブラウザ間でP2P通信するには、あらかじめ、通信相手のIPアドレス等を知る必要があります。そのために、まずシグナリングサーバー<sup>※２</sup>を経由して、SDP<sup>※３</sup>を相手のブラウザと交換します。

※２．シグナリングサーバーとは、P2P通信を開始する前に、必要な情報を相手のブラウザと交換するための仲介役のサーバー。

※３．SDP（Session Description Protocol）は、通信に必要な情報(IPアドレス、ポート番号、暗号化通信のめの公開鍵情報、メディアの形式、通信帯域など)のプロトコル。

![PTC図1－１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/724a7d33-4fe8-65d9-1ca0-021c084089e4.png)

#### ステップ２．P2P通信開始
SDPを共有すると、候補の通信経路を試行して、P2P通信を確立します。この通信には、リアルタイム性を求める通信に適したUDP<sup>※４</sup>を利用します。
これで、ブラウザ同士がオーディオ/ビデオなどのデータを送受信するWeb会議が成立します。送信するデータは、ビデオ/オーディオを送信するのに適したSRTP、または様々なデータ形式に対応したSCTPで暗号化されています。

※４．UDPとは、トランスポート層のプロトコル。データの誤りや順序の違いなどを検出する機能がないので、TCPと比べて遅延が発生しにくい。

![RTC図1－２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/29c39239-1734-18b3-5998-c8be58f9edff.png)


## NAT越えの課題
WebRTCの基本的な仕組みは上記です。しかし、実際にはNAT<sup>※５</sup>が存在するため、簡単にP2P通信は成立しません。NAT配下のPCに、NATの外側から直接データを送信することはできないからです。WebRTCでは、STUNサーバー、TURNサーバーを利用して課題を解決しています。
※５．NAT（Network Address Translation）とは、プライベートIPアドレスをグローバルIPアドレスに変換、またその逆の変換を行う仕組みのこと。
![NAT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/d1f49910-77d3-171e-e938-a063c29d0987.png)



#### STUNサーバーの役割
前述の通り、P2P通信の準備として、ブラウザはSDPを送信して自身のグローバルIPアドレスを相手に伝えなくてはなりません。しかし、NAT配下のブラウザは自分のグローバルIPアドレスを知りません。そこで、STUNサーバー<sup>※６</sup>にアクセスして自分のグローバルIPアドレスを取得し、相手にSDPを送信します。
※６．STUNサーバーとは、NAT配下にあるPCがNATの外側から見たグローバルIPアドレスを知るためのもの。この、NAT配下のPCと通信できるようにする仕組みのことをNAT越えと言います。
![STUN図1.png２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/312bc7af-bc16-cc9e-9211-9e57448e485a.png)






#### TURNサーバーの役割
STUNサーバーでIPアドレスを確認出来ても、セキュリティ性の高いNATの場合はP2P通信を確立できないことがあります。そんな場合に利用するのがTURNサーバー<sup>※７</sup>です。P2P通信時に、TURNサーバーが仲介することでNATを超えたデータの送受信を可能にします。
※７．TURNサーバーとは、PC同士の間に立って、データの中継をしてくれるサーバー。このサーバーでデータの変形は行われません。
![TURN2図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/c052f055-00ff-f17b-d165-92094446bb36.png)


以上のように、P2P通信を確立させる際には、ブラウザ間の直接通信を試し、必要に応じてSTUNサーバーへアクセスし、それでも通信が確立しない場合はTURNサーバーを利用します。このような通信経路を見つけ出す仕組みを、ICE(Interactive Connectivity Establishment)と言います。WebRTCでは、SDPにICE Candidateという通信経路候補を含めて、相手に経路情報を伝えています。


## まとめ
* WebRTCとは、ブラウザ間のP2P通信でデータをやり取りする仕組みのこと。
* P2P通信を成立するにはシグナリングサーバーが必要。
* 必要に応じて、STUNサーバー、TURNサーバーを利用して通信する。

以上、初心者エンジニアがWebRTCの仕組みをまとめてみました。
不適切な表現がございましたら、ご指摘頂けますと幸いです。
[次回は](https://qiita.com/rie_uchida500/items/32cbe3793c995b5a7537)ハンズオンとして、Amazon Kinesis Video Streams WebRTCを使ってWebチャットアプリの実装をします。

## 参考サイト
以下のサイトを参考にさせて頂きました。
- [WebRTC入門2016]
(https://html5experts.jp/series/webrtc2016/)
- [WebRTCの基本とP2P通信が成立するまでを学ぶ]
(https://qiita.com/daitasu/items/ae21b16361eb9f65ed43)
- [【初心者向け】STUN/TURNサーバをざっくり解説してみた](https://qiita.com/okyk/items/a405f827e23cb9ef3bde)
- [WebRTCにおけるNAT越えの課題へのアプローチ](https://qiita.com/udonchan/items/693e43b13269207f904a)