4.3 NAT を越えてゆけ 内の端末の IP アドレスが隠蔽されるためです * 1 。本来、インターネットにアクセスする 端末はそれぞれがグローバル IP アドレスを持っている必要があり、プライベート IP ア ドレスしか持っていない端末はインターネットに接続できません。しかし、 NAT 機能を 利用している LAN 内の各端末はグローバル IP アドレスを持たず、プライベート IP アド レスのみが割り当てられています。ではなぜ LAN 内の各端末がインターネットに接続で きるかというと、ルーターが持っているグローバル IP アドレスを皆で共有して利用する からです。そのため、 LAN 内の複数の端末が別々にアクセスしていても、 LAN 外から見 ればすべて同一 IP アドレスからのアクセスとなり、各端末の IP アドレスを知ることは できません。また、それを知ったとしても、 LAN 内のみで有効なプライベート IP アドレ スなので、それだけでは外部から接続することはできないのです。 そこで、 LAN の外部から自分の端末への接続を受け付けるため、一部のネットワーク 対戦ゲームや、一昔前の P2P ファイル共有ソフトなどでは、ポート開放という作業を必 要としていました。これはつまり、①ファイアウォールで特定のポートへの接続を許可 し、②さらに特定のポートへの接続はすべて特定の端末へと転送するように設定すること で、 LAN 内部の特定の端末へ外部から接続できるようにするものです。しかしこの作業 はルーターなどの設定が必要で、また下手に設定するとセキュリティレベルが低下してし まうなど、初心者が気軽に行えるものではありませんでした。 WebRTC でもファイアウォールと NAT という 2 つの間題を解決しなければならない ことに変わりはありません。しかし WebRTC ではファイアウォールやルーターの設定を 変えるのではなく、 NAT の特性をうまく利用して巧妙に穴を開けているのです。このよ しかし考えてみると不思議です。 LAN 内の複数の端末からほぼ同時に同じサーバ は先ほど説明したとおりです。 NAT は複数の端末で 1 つのグローバル IP アドレスを共有する技術であるということ そのからくりを理解するため、まずは NAT の働きについて確認しましよう。 NAT のおしごと うな技術を一般に NAT 越え (NAT traversal) と呼びます。 49 本書では「 NAT 」という表現で統一します。 スカレードと呼ばれる技術なのですが、 NAPT は NAT の一種であることや、他の用語との統一のため、 * 1 ここで説明している内容は、厳密には NAPT (Network Address port Translation) あるいは IP マ ません。ルーターはどのようにしてレスポンスの宛先を判断しているのでしようか。 たリクエストに対するレスポンスを間違えて別の端末に返してしまう、なんてことはあり てくれます。どのリクエストも送信元 IP アドレスは同じなのに、ある端末から送信され アクセスしても、ルーターはちゃんと各リクエストに対するレスポンスを間違いなく返し
4.3 NAT を越えてゆけ の宛先ポート番号は 5001 のようなので、 192.168.0.20 : 4000 にレスポンスを送信すればよ いことがわかります ( 図 4.3 ) 。 ロロ 192.168.0.10 : 408 192.168.0.20 変換前・ポート書号変換後ポート番号 LAN 側 192.168.0.1 192.1 .0.10 : 2000 192.168.0.20 : 4000 WAN 側 198.51.100.65 : 5001 インターネット 5000 5001 203.0.113.206 △図 4.3 198.51.100.65 : 5001 へのレスポンスを 192.168.0.20 : 4000 に返す この例では、後から送信したリクエストに対するレスポンスのほうが先に返ってきまし たが、ポート番号を利用することで間違いなく元々のリクエストを送信した端末にレスポ ンスを返せるのです。 NAT を騙して穴を開ける このしくみを上手く利用すれば、外部から LAN 内の端末への接続が可能になります。 ポート開放で行っていた作業のひとつに、 " 特定のポートへの接続はすべて特定の端末 へと転送する " というものがありました。 NAT の働きをよく見ると、これと同じような 状態が発生していることにお気付きでしようか。 つまり、ルーターが記憶している割当表に載っているポート番号宛にリクエストを投げ れば、ルーターはそれをレスポンスと勘違いして端末に接続させてくれるのでは・・・ ? 嘘のような話ですが、本当にこれで接続できてしまう ( ことがある ) のだから驚きです。 STUN サーバーがグローバル IP アドレスだけでなく送信元ポート番号も教えてくれる のは、端末を特定するために必要だったからなのです。 これはあくまでもわかりやすいように単純化した話で、実際にはこれよりも複雑な手 順を踏んでようやく接続できるようになります。しかし基本的な考え方はこのとおりで、 いったん外に出て穴を作れば同じ穴から中に人れるというわけです。このような NAT 越 えの手法を、 UDP ホールバンチングと呼びます * 2 。 * 2 名前のとおり、 るのですが、 この手法は UDP 専用です。 TCP の場合は TCP ホールバンチングという別の方法があ 51 こでは説明しません。
第 1 章 WebRTC に関する基本的知識 Android はほぼ OK ・・・のはずだけど・・・ です。 モバイル環境 モバイル環境でも、主要な OS である Android と iOS 両方の主要プラウザーで対応済 にしなくてもよいのかもしれません。 し、 iOS では大半のユーザーが積極的に OS のアップデートを行っているので、あまり気 iOS 11 未満については残念ながらネイテイプアプリで対応するしかありません。ただ 製プラウザーは非対応です。 く Mobile Safari で利用できるようになりました。 Mobile Safari 以外のサードバーティ で WebRTC を利用できなかったのですが、 2017 年 9 月リリースの iOS 11 からようや いる WebView を使用する必要があります。そのため、これまで iOS ではプラウザー上 レンダリング・ JavaScript 工ンジンを積むことはできず、すべて OS が SDK で用意して 一方、 iOS では Android と異なり、 AppStore で公開するプラウザーアプリは独自の iOS は 1 1 から もいいのに いくら「みんなちがうから、世界はたのしい」 * 14 からって、そこまで違いを出さなくて いということになります。 H. 264 にする必要があるので、この不具合のある端末では Safari とビデオ通話ができな いえません。 iOS を含む Safari との間でビデオ通話をする場合は映像フォーマットを たりといった不具合を持っている端末が割とあるようで、結局は「端末による」としか 実際には、カメラの映像を取得できなかったり、 H. 264 で映像をエンコードできなかっ Android 4 以前の古い端末を除けば、ほぼ利用可能なはずなのです・・・仕様上は。 ているサードバーティー製プラウザーでも同様に利用できます。 うになった "Android システムの WebView" が対応しているため、 WebView を利用し 対応しています。さらには、 Android 5 以降システムと切り離されて単独で更新できるよ Android でもデスクトップ環境同様に Firefox と、デフォルトプラウザーの Chrome が 14 * 14 2014 年ごろにやってた Android の広告キャンペーン。
第 2 章メディアストリームを取得する・・・ Media Capture API ▽リスト 27 フレームレートの指定 environment facingMode : ' video: { 1et mediaStream = await navigator. mediaDevices . getUserMedia( リスト 2.8 インカメラ・アウトカメラの指定 らで撮影するかを指定する場合に使います。 モバイル端末にはたいていイン・アウト 2 つのカメラが搭載されていますが、そのどち facingMode frameRate : {max: 10 . 0 } , video: { Iet mediaStream = await navigator. mediaDevices . getUserMedia( つで、 left と right は対応している端末が少ないので気にしなくも大丈夫です。 指定できる値は表 2.4 のとおりです。このうちよく使うのは user と environment の 2 値 environment left r i ght マ表 2.4 facingM0de に指定できる値 意味 インカメラ ( フロントカメラ、画面側 ) アウトカメラ ( バックカメラ、背面側 ) 左側カメラ 右側カメラ デフォルト 〇 デフォルト値は user 、つまりインカメラとなりますが、 environment を指定すればア ウトカメラで撮影できます。このとき、 exact で指定すると、アウトカメラが存在しない 端末では取得に失敗します。 また、デスクトップ環境ではプラウザーと OS 、 Web カメラの内蔵・外付けの組み合わ せにより挙動が異なります。筆者の環境では、 user 指定で内蔵インカメラの映像が取得 され、その他の値を指定すると取得できないという想定どおりの挙動をしたのは Edge と Mac 版 Firefox だけです。 Chrome や Mac 以外の Firefox では何を指定しても取得に失 28
3.3 シグナリングのシーケンス 45 ました。 プジェクトを利用し、コーデックやビットレートなどパラメーターの変更を簡単に行えるようになってい まさに SDP のことです。 ORTC では SDP の代わりに、 SDP に含まれる各情報をプロバティとするオ * 6 第 1 章末尾のコラムで述べた、 ORTC 誕生のきっかけとなった WebRTC の「イケてない」仕様とは、 なお、通信経路候補をすべて見つけ終えたときも onicecandidate イベントは発火し 出して登録します。 ターで RTCIceCandidate オプジェクトに戻してから addlcecandidate メソッドを呼び トに登録する必要があります。データは送信時に文字列化されているので、コンストラク 相手から通信経路候補が送られてきたら、その情報を RTCPeerConnection オプジェク date プロバティに格納されているので、これを相手に送信して通信経路候補を教えます。 ます。通信経路候補を表すオプジェクト RTCIceCandidate が引数オプジェクトの candi プラウザーが通信経路候補を発見すると、その都度 onicecandidate イベントが発火し けられていれば、両方の IP アドレスが候補となります。 てられていれば、それもやはり候補です。端末に複数のネットワークアダブターが取り付 ので、これも候補となります。端末に IPv4 アドレスだけでなく IPv6 アドレスも割り当 です。 LAN 外の端末とならグローバル IP アドレスを使えば通信できるかもしれません ドレスでも、同じ LAN 内にいる端末同士なら通信できる可能性があるので候補のひとっ 通信経路候補はたいてい 1 つだけでなく、複数発見されます。たとえばローカル IP ア 相手に送信する部分と、相手から送られてきたそれを保存する部分です。 必要はありません。実装しなければならないのは、プラウザーが見つけた通信経路候補を 通信経路候補を見つける処理はプラウザーが自動的に行ってくれるため、特に実装する セッション情報の交換が終わったら、こんどは通信経路候補の交換を行います。 通信経路候補の交換 はありませんが、ただ単に使うだけであればその必要はないので安心してください。 現在のところはコーデックやビットレートを変更するには SDP を書き換えるしか方法 はまだありません。 おり、 Firefox や Safari では一部機能が実装済みですが、完全に対応しているプラウザー れに伴い、 SDP の書き換えはできなくする方針のようです。仕様書にはすでに存在して パラメーターの設定はそれらのオプジェクトのメソッドで行えるようになる予定です。そ 将来的には、メディアストリームの送信・受信を管理するオプジェクト群が実装されて 列を置換しなければいけません。ビットレートを変更するだけでも大仕事です * 6 。 しかし、 SDP はデータとしては単なる文字列なので、内容を書き換えるためには文字 てから LocaIDescription に設定できるようにするためだったのです。 SDP の生成と LocalDescription の設定が分かれていたのは、 SDP の内容を書き換え
はじめに るのではないか。そう思った私は早速 WebRTC の使い方を勉強しはじめ、数日でプロト タイプを組み上げました。試しにフレンド同士で実際に使いながら遊んでみると、これが 思った以上に楽しい。さらに改良を加え、「イカデンワ」という名前で公開、 3 したところ、 予想を超える大きな反響を呼び、大変多くの方にご利用いただけるサービスとなったので す。それ以来、私は WebRTC の魅力に取りつかれました。 私は 2015 年末に TechBooster 、 4 の同人誌「 JavaScriptoon2*5 」で WebRTC の紹介記 事を執筆しました。この記事はありがたいことに各所から大変ご好評をいただきました が、執筆から時が経ち、今となっては時代遅れな記述が目立ちます。そこでこの記事をも とに、現在の仕様に沿うように大幅に加筆・修正し、一冊の本として再構成することにし ました。そうしてできたのが本書です。 本書はあくまでもタイトルどおり「わか ( った気がす ) る」ことを目標としており、わ かりやすさを優先するために必要以上の説明を避けている場合もあることをお断りしてお きます。 WebRTC の世界は広すぎる。 本書の対象範囲 本書で扱う内容は次のとおりです。 「 WebRTC とは何か」「何ができるか」という基本的な知識 ・ WebRTC が動作するしくみ ・ WebRTC を利用した Web アプリケーションの実装方法 WebRTC の動作に必要なサーバーの構築方法 ・ WebRTC に関連する Web プラウザーの挙動 次の内容については、本書では扱いません。 WebRTC の各機能についての少し掘り下げた知識 WebRTC で採用されている各プロトコルの詳細な仕様 Web プラウザーやサーバーの内部実装 ・ WebRTC を利用したネイテイプアプリケーションの実装方法 * 3 ちなみにこの名前は、 をモジッたものです。 * 4 技術系同人サークル。 * 5 2015 年 12 月 31 日、 ケータイ (PHS) なのに固定電話の形をしているという伝説の端末「イエデンワ」 https : //ikadenwa. ink/ http://techbooster.org/ C89 にて頒布。 https : //booth. pm/ja/items/178227 3
第 4 章相手とつながるために・・・ ICE/STUN/TURN されており、端末自体には付与されていません。そのため、何らかの方法で調べる必要が アドレスになります。しかし、グローバル IP アドレスは一般にモデムやルーターに付与 外にいる相手から自分に接続できる可能性がある IP アドレスというと、グローバル IP 一方、相手が LAN 外にいる場合は、ローカル IP アドレスでは接続できません。 LAN べることができます。 ローカル IP アドレスは端末自体に付与されているので、サーバーの助けを借りずとも調 ている場合もありますが、一般的な家庭内・企業内 LAN であればまず大丈夫でしよう。 セキュリティ上の理由で、同じ LAN 内のユーザー同士で接続できないように設定され 相手が同じ LAN 内にいれば、ローカル IP アドレスで接続できる可能性があります。 信経路候補として見つけ出します。 そのため、プラウザーは自分と接続できる可能性があるありとあらゆる IP アドレスを通 WebRTC の通信相手はネットワーク上のありとあらゆる場所にいる可能性があります。 4.2 STUN サーバー そのように呼んでいます。 TURN (TraversaI Using Relay around NAT) という 2 種類のサーバーの総称として 類のサーバーを指す言葉ではなく、 STUN (Session TraversaI UtiIities for NATs) と あるのですが、 こで活躍するのが STUN サーバーです。 STUN サーバーに対してリ クエストを投げると、サーバーから見える送信元のグローバル IP アドレスとポート番号 を教えてもらえます。 STUN サーバーとは、ものすごく乱暴にいえば、 API 化された " 確 認くん " のようなものと思って間違いではありません。プラウザーは STUN から教えて もらったグローバル IP アドレスとポート番号を通信経路候補として採用します。 4.3 NAT を越えてゆけ こまでの説明を聞いて疑間に思われたかもしれません。「グローバル IP アドレスが わかったとしても、 LAN 内にいる端末には接続できないのではないか」と。 たしかにそのとおりです。一般的に、 LAN の中から外に向かってアクセスすることは 簡単でも、 LAN の外から中に向かってアクセスすることは難しいのです。 その理由は大きく 2 つあります。 ひとつは、ルーターなどに実装されているファイアウォール機能により、外部からの接 続のほとんどが拒否される設定になっているためです。これはもちろんセキュリティ上の 理由によるもので、必要があれば個別に許可することになります。 もうひとつは、ルーターの NAT (Network Address TransIation) 機能により、 LAN 48
第 3 章 通信相手を見つけて、つなげる・・ シグナリング 人力デバイスからメディアストリームを取得できたところで、いよいよ WebRTC によ る P2P 接続・通信のはじめかたを見ていきます。 3.1 はじめましてのシグナリング 36 す。 * 1 、、候補 " となっているのは、実際にその経路で通信が可能かどうかは試してみないとわからないためで 呼びます。 接続を行おうとするピア同士でこれらの情報を交換しあう一連の作業をシグナリングと 合意する必要があります。 コーデックや帯域幅といった情報を共有し、間題なく通話できるデータを送信するように がなく、通話は成り立ちません。確実に通話をするためには、お互いの使用する ( できる ) 質な音声を送信したとしても、相手がそのデータをちゃんと受信・再生できなければ意味 は正常に通話を成立させるために必要なものです。こちらがどれだけ高画質な映像・高音 もう 1 つはセッション情報、今回の通信をどのような形式で行うかという情報で、これ ります。 なポート番号を教えあい、お互いに相手の端末にリクエストを送れるようにする必要があ WebRTC での接続先は ( 基本的に ) 相手の端末ですから、自分の IP アドレスと接続可能 かに接続するためには、接続先の IP アドレスとポート番号を知らなければなりません。 接続を確立するために必要な情報です。当然のことですが、インターネットを通じてどこ 1 つ目は通信経路候補 * 1 、平たくいえば IP アドレスとポート番号で、これは相手との WebRTC で通信をはじめるためには、 2 種類の情報が必要になります。
4.5 Microsoft は TURN サーバーがお好き ? TURN サーバーの必要性 53 、 5 Edge のユーザーエージェントのバージョン番号は、 EdgeHTML のバージョンで表記されます。 画質、 500kbps) で約 1 , 111 時間 ( 約 46.3 日 ) 相当とかなり余裕のある設定になっています。 TURN サーバーを提供しています。通信量 500GB / 月という制限はあるものの、 1 : 1 のビデオ通話 (SD * 4 たとえば NTT コミュニケーションズの SkyWay (https://webrtc.ecl.ntt.com/) では無料で 字列をチェックし、 Edge / 1 [ 3 ー 5 ] \. にマッチすれば、 5TURN サーバーのみ、マッチしな 外とで ICE サーバーのリストを差し替えるのがよいでしよう。ユーザーエージェント文 うバグとしか思えない挙動があります。この問題を回避するには、 Edge40 以下とそれ以 には i ceservers に STUN サーバーが指定されているだけでエラーになってしまうとい さらに厄介なことに、 Windows 10 バージョン 1703 (Creators Update) の Edge 40 おける WebRTC の利用には、 TURN サーバーが事実上必須ということになります。 が、 LAN 外の端末との間では ICE を利用した P2P 通信ができません。つまり、 Edge に Microsoft Edge は同一の LAN 内に存在する端末同士では P2P 通信ができるのです さて、本章の最後にけっこう面倒くさい間題を紹介します。 4.5 Microsoft は TURN サーバーがお好き ? のデータを右から左へただ流しているだけなのです。 鍵を持っておらず、当然中身を知ることもできません。 TURN サーバーは、暗号化済み アに行われています。つまり、 TURN サーバーは暗号化されたデータを解読するための WebRTC の暗号化の鍵は通信を行う両ピアが生成しており、その鍵交換自体もセキュ うになっています。それは TURN サーバーも例外ではありません。 WebRTC の通信内容は暗号化されており、第三者が中身を覗き見ることができないよ TURN サーバーはただのトンネルである ているものもありますので、これを利用するのがお手軽で便利です * 4 。 するのもひとつの手ですが、 WebRTC プラットフォームサービスが利用者向けに提供し 継するもので、大量の帯域が必要となるため、これはしようがないことです。自前で用意 については自由に使える公開サーバーはまず存在しません。 TURN サーバーは通信を中 STUN サーバーは Google などが公開サーバーを提供していますが、 TURN サーバー サーバーはなるべく用意するようにしましよう。 り、決して無視できる範囲ではありません。ユーザーの利便線を損なわないよう、 TURN NAT を越えられず TURN サーバーが必要になる環境は 1 割 ~ 2 割程度といわれてお
8.1 プラウザーの挙動を変える 0 : 00 : 40 : 500 810 図 8.2 Ch 「 ome のテストバターン映像 Edge の場合 Edge では about:flags で挙動を変更できます。現在は、 WebRTC 関連で指定できる 項目はほとんどありません。 WebRTC 接続でローカル旧アドレスを隠す ローカル IP アドレスが通信経路候補として発見されなくなります。同一 LAN 内 の端末同士でも、 ICE を使って外部と通信できるかを確認するために使えます。 Safari の場合 Safari の場合は開発メニューから挙動を変更できます。開発メニューが表示されていな い場合は、「 Safari 」→「環境設定・・・」と進み、「詳細」タブの下にある「メニューバ " 開発 " メニューを表示」にチェックを人れてください。 . 、、 -- ロウインドウヘルプ ページをこのアプリケーションで開く ユーザ工ージェント セキュリティ保護されていないサイトでのメディアキャプチャを許可 ℃ E 候補の制限を無効にする ノレガシ—WebRTC A 円を有効にする 擬キャプチャデバイスを使用 WebRTC スマート検索フィールドからの J aSc 「 i 可を許可 AppIeEvent からの JavaScript を許可 リモートオートメーションを許可 未署名の機能拡張を許可 Safari TechnoIogy Preview を入手 △図 8.3 Safari の開発メニューで設定できる WebRTC 関連の項目 85