更新: | 2017-09-26 |
---|---|
作者: | @voluntas |
作者サイト: | http://voluntas.github.io/ |
バージョン: | 1.2.1 |
セッション日時: | 2017-09-24 14:20 - 15:00 |
セッション場所: | 5号館3F |
発表時間: | 40 分 |
公式セッション情報: | http://events.html5j.org/conference/2017/9/session/#e3 |
公式スピーカー紹介: | http://events.html5j.org/conference/2017/9/speaker/index.html#voluntas |
この資料は 2017-09-24 に行われた HTML5 Conference 2017 の 発表者メモ です。
ショートURL は http://bit.ly/u-w-i です。understanding-webrtc-internals です。
この資料の間違いについては Twitter で @voluntas までリプライをお願いします。
この資料では WebRTC API については説明していません。一通りの知識を得たい場合の本をオススメしておきます。
わか(った気にな)るWebRTC 電子版のみ - Route 312 - BOOTH(同人誌通販・ダウンロード)
個人が書かれている本ですが、とてもキレイにまとまっておりますのでオススメです。アップデート版も今後でるそうなので期待しておきましょう。
これらの WebRTC の章を呼んでから、この話を聞きに来るとより、楽しいかもしれません。
時雨堂の方から来ました。Erlang/OTP でミドルウェアを書いて 10 年くらいご飯を食べています。 専門は認証、課金、暗号(使う方)、そしてリアルタイム配信です。興味があるのは継続的負荷試験です。 最近は WebRTC 用の負荷試験ツールをちまちま作ったりしています、そのうち売り出す予定です。
今回は WebRTC API の話は一切しません。ブラウザが 通信している部分の仕組み を中心に話をします。
今回持って帰っていただきたいのは「 WebRTC はこんな複雑なんだな」ということです。
この資料自体は公開されますので、写真とかは取らなくて大丈夫です。
- WebRTC のデータチャネルについては解説しません
- 単に自分が詳しくないのと DTLS-SCTP を解説してると時間が足りないから
- WebRTC API については解説しません
- 知りたい人は沢山資料があるのでぐぐってください
このイベントに来ていて WebRTC を知らない人はいないと思うので解説しません。
- TLS の基本的な知識
- WebRTC は P2P という技術を利用している
- WebRTC は暗号化されている
- WebRTC はリアルタイムに音声や映像を相互に送りあえる
これは知っている前提で話をします。
実は WebRTC というのは沢山のプロトコルが絡み合ってできています。
- UDP
- DTLS
- RTP / RTCP
- SRTP / SRTCP
- STUN / TURN / ICE
- SDP
まずは簡単に利用している主なプロトコルの説明をしていきます。
HTTP は TCP です。 WebRTC は UDP を利用します。
- RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2
- RFC 6347 - Datagram Transport Layer Security Version 1.2
- RFC 4492 - Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)
- RFC 5288 - AES-GCM Cipher Suites for TLS
WebRTC で利用されている主なプロトコルは暗号を書けるための MasterSecret を得るために利用するデータグラム向けの TLS です。 基本的には ECDHE-ECDSA で AES-GCM-128 が利用されます。
- RFC 3550 - RTP: A Transport Protocol for Real-Time Applications
- RFC 5761 - Multiplexing RTP Data and Control Packets on a Single Port
WebRTC の音声や映像をこの RTP というプロトコルに詰め込んで送ります。リアルタイムアプリケーション用のプロトコルです。 UDP 上のプロトコルです。
RTP と対になるプロトコルです。ただこちらは RTP をコントロールするプロトコルです。RTP は UDP ベースのためパケロス、遅延など色々な問題が起きたことに気付くのがわかりません。それを気づかせるためのプロトコルです。
RFC 3711 - The Secure Real-time Transport Protocol (SRTP) RFC 7714 - AES-GCM Authenticated Encryption in the Secure Real-time Transport Protocol (SRTP)
SRTP は RTP を暗号化するプロトコルです。 DTLS で交換した MasterSecret を利用します。 RTP のヘッダー自体は暗号化しません。さらに HMAC によるハッシュチェックも追加されます。これにより改ざんを防ぐことができます。
暗号には AES-CTR が利用されます。最近では AES-GCM も実装されました。
AES-GCM は Chrome では chrome://flags で有効にすることで実現できます。そのうち AES-GCM が標準になるかもしれません。
SRTCP は RTCP を暗号化するプロトコルです。少し SRTP と違うのは RTP にはあったシーケンス番号が RTCP にはないため、SRTCP ように SRTCPIndex というのが用意されています。さらに 32 ビットではなく 31 ビットで、1 ビットだけ E フラグという暗号化しているのかされているのかという判断用のフラグが用意されています。
こちらにもハッシュチェックは存在しています。
- RFC 5764 - Datagram Transport Layer Security (DTLS) Extension to Establish Keys for the Secure Real-time Transport Protocol (SRTP)
- RFC 7983 - Multiplexing Scheme Updates for Secure Real-time Transport Protocol (SRTP) Extension for Datagram Transport Layer Security (DTLS)
WebRTC では DTLS を普通の使い方せず Applicaiton Data は利用しません。あくまでマスターシークレットだけを活用します。
マスターシークレットからクライアントとサーバの AES-CTR 用の鍵、ハッシュ関数用のシークレットを生成します。これが AES-GCM n場合は AES-GCM 用の鍵を生成するだけです。
RFC 5389 - Session Traversal Utilities for NAT (STUN)
相手から見た、自分の IP を知るためのプロトコルです。そんなの自分で知ってるのでは?と思われがちですがそんなことはないです。インターネッツはそんな単純ではありません。
これは STUN サーバというのをグローバルに置くことで、そこに自分 STUN パケットを送り、相手が受け取ったときの自分の IP アドレスとポート番号を繰り返してもらいます。これを利用して自分が今どんなネットワーク状況にいるのかを知ります。
TURN は STUN のお仲間ですが、役割が違います。STUN で確認した自分の状況で「あきらかにこれは相手と直接やり取りするのは難しそう ... 」と判断した際に利用します。
直接やり取りをせず、通信をやり取りするためのプロトコルです。
これは UDP と TCP 、そして TLS over TCP が WebRTC では採用されています。
ICE は STUN と TURN を組み合わせたプロトコルで、どうにかして相手とやり取りをするためにいろいろな策を打つためのプロトコルです。
この話をするだけで 1 日使える位な世界なので、今回は詳しくは話しません。
RFC 4566 - SDP: Session Description Protocol
これはお互いにやり取りをする時の条件を決めるためのプロトコルです。 SDP は WebRTC の通信上でやり取りはしません。
WebRTC の仕様で決められていない、第三者を経由して相手と SDP を交換します。この第三者のことをシグナリングサーバと呼びます。
先程のプロトコルの紹介のときに、全てに RFC が割り当てられているのにお気づきかと思います。先ほど紹介したのは基本の RFC だけです。応用となると大変な数があります。
その大変な量の RFC またはドラフトと呼ばれるまだ確定していない仕様をそれぞれのブラウザが独自で実装しています。
大変な量 ... というのがどのくらいかは全てではありませんが一部をまとめてあります。
WebRTC スタックを一から実装する場合読んでおくべき資料まとめ
実は WebRTC の具体的な仕様は決められていません。仕様があるのは WebRTC API の方です。
WebRTC 1.0: Real-time Communication Between Browsers
WebRTC はネットワークの問題で繫がらない事があります。ブラウザから見たら「ちょっとしたエラーメッセージがでているだけ」ですが、実際はおもったより深刻なネットワーク問題だったりもします。
うまくいかない時、 WebRTC はブラウザから突然別世界へ連れて行かれます。
全てのブラウザで WebRTC API の対応が違う以前に、内部実装も異なります。 内部実装は全て違います。重要な事なので二回言いました。
現時点で WebRTC に対応している主要なブラウザは 4 つです。これ以上は増えないと考えて良いでしょう。
- Chrome
- Firefox
- Edge
- Safari
やっと 2017 年で出揃いました。
RFC 7742 - WebRTC Video Processing and Codec Requirements
WebRTC API やプロトコル以外に、 WebRTC では コーデック という概念があります。音声や映像を圧縮する仕組みです。
コーデックが問題になるのは、大きく2つの点です。 一つはライセンスです。そしてもう一つはハードウェアアクセラレータの必要性です。
ライセンス問題は色々めんどくさいのですが、 Safari を例に取ると大変良くわかります。
- Safari 11 では H.264 というコーデックしか対応しない
- Safari が使える端末には H.264 のハードウェアアクセラレータが必ず載っている
- H.264 を使うにはライセンス費用がかかる
- OpenH264 というライブラリをシスコが出しており、シスコがライセンス費用の全額を負担している
- WebRTC では VP8 と H.264 両方に対応するべきという方針になった
- VP8 上位版である VP9 は VP8 のビットレートを半分にして、同等の画質が得られる
- ただし CPU 使用率は 30% アップ
- VP8 と VP9 は Google がオープンに開発しているコーデック
もうめんどくさそうなのわかりますか? RFC は強制ではありません。
8265 - Add H.265 support for iOS - webrtc - Monorail
iOS が H.265 に対応したことにより、WebRTC で H.265 を採用する可能性が出てきました。 H.265 は VP9 と同じ立ち位置に有り、 H.264 の半分のビットレートで同じ画質を実現可能になります。
ただ、闇は多く特許がとても複雑です。詳細は H.265/HEVC特許暗黒時代 - Qiita を御覧ください。
アップルは特許ホルダー側なのでいいですが、ブラウザ側は色々手の出しようがありません。さてさて。
これまためんどくさい世界で、それぞれで仕組みが違います。
- RFC 6184 - RTP Payload Format for H.264 Video
- RFC 7741 - RTP Payload Format for VP8 Video
- RFC 7798 - RTP Payload Format for High Efficiency Video Coding (HEVC)
- RTP Payload Format for VP9 Video
AV1 というコーデックがあります。これは AOM (Alliance for Open Media) という団体で開発されているコーデックです。これは H.265 とは違いパテントフリーです。いろいろな企業がパテントに疲れたのでしょう ... 。
VP9 に比べて 50% 効率が良いらしいですが、実際使ったこと無いのでよくわかりませんが、かなり気合い入れて開発はしているようです。
これは何かというと、Chrome で利用されている WebRTC 実装です。 Firefox と Safari はこのライブラリを利用しています。ただし、Chrome のように常に最新版のタグを使っているわけではなく、少し遅れている感じです。 Edge は独自です、間違いなく。
さてここで Edge の WebRTC について、一言言わせてください。仕様がクローズドな上にソースもクローズドです。そして WebRTC の仕様は明確にされていない。現時点での Edge の WebRTC 実装は使い物にならないというのが現状です。
いままで説明してきたプロトコルの話を 知らなくても利用できる というのが WebRTC の凄いところです。
JavaScript API だけで利用が可能になりました、特に WebRTC がブラウザに搭載されるまでは音声や映像でリアルタイムにやり取りをする場合は専用アプリを作る必要がありました。これらがブラウザで完結できるようになりました。
また WebRTC はブラウザに搭載されているという技術でしかないため、 iOS/Android 、さらにはラズパイなどでブラウザ無しでの WebRTC を動かすことも可能です。
WebRTC は 双方向で音声や映像をやりとりするなんでも入りのライブラリ です。いままでこのレベルでまとまっているものはありませんでした。これが全てオープンソース公開されているのはとても凄いことです。
ブラウザごとの WebRTC API の仕様は統一されていくそうです。だからといって、プロトコルレイヤーは統一されていくことは無いでしょう。
ただ、正直全てのブラウザが同一の仕様になる日は来ないと考えています。開発ペース、動作するハード、条件が色々違いすぎます。このあたりを吸収するのは難しいと考えています。
例えば Edge はソースコードがクローズだったり、そもそも Skype をブラウザで動かすことが目的だったりと WebRTC を他のブラウザとやりとりすることはあまり考えられていない印象があります。
また Safari は動作する環境が Apple 側で決められるため、それに最適化した仕様になってしまいます。Chrome/Firefox は中立といえば中立でしょうか。
正直どうなるかは読めません。
Flash が 2020 年に終わるということで、今まで Flash で利用してきた音声や映像を配信する技術は今後は WebRTC または HLS/MPEG-DASH に切り替わっていくでしょう。
とはいえ、 WebRTC はあくまで P2P の技術であり、 RTMP のように多くのユーザに配信する技術ではありません。そもそも RTMP は CDN が使えます。
つまり、そう簡単に RTMP から WebRTC への置き換えはできない、というのが現状です。
Safari 11 で WebRTC に対応しました。今まで iOS のモバイル Safari では WebRTC が動かないため、iOS の場合は専用アプリを作る必要がありました。
ただ、これが必要なくなるため、ブラウザベースで十分という人が増えることで気軽に利用可能です。この流れは大きく、スマホアプリを作らなくても iOS に対応可能というのは、 WebRTC の利用範囲を押し上げると思います。
ざっと WebRTC で利用されているプロトコルから、 WebRTC の仕組み。さらにはなぜ WebRTC が難しいのか、なぜ凄いのか。そして今後を見てきました。
実際に WebRTC を利用したアプリケーションを使う場合はこれらを意識する必要は一切ありません。ユーザ側はとても便利です。ただアプリケーションを開発したり、運用シていく場合はこのあたりの知識を持っていたほうが良い場合は多いです。
WebRTC のようなリアルタイムな双方向通信は Skype や Facetime 、さらには LINE のようなメッセンジャーツールが実現している事もあり、簡単な技術と取られることが多いです。ただ実際は複雑な仕組みになっています。この複雑な仕組みは好きで複雑になっているわけではありません。
ネットワーク環境、マシン環境、ブラウザバージョンなど様々な条件は使う人全てが同じわけではありません。そんな中で遅延が 1 秒を切る世界を実現するには、かなり幅広いところまで考えておく必要があるのです。
今後もし WebRTC の話題が出た時に「あ、これ実は凄い複雑で難しい技術だよね」なんて話をしてもらえれば今回の発表の目的は達成できたと思います。
以上で発表を終わります。
商用の WebRTC SFU です。価格は同時 100 接続で年間利用料ライセンス 60 万円です。毎年かかります。製品のサポート料金込みです。200 接続だと年間 120 万円です。
複数人数での会議や、 数百人への配信、一対一の面談など様々な用途に利用可能です。
パッケージで提供しますので、自社で運用が可能です。 AWS だろうが GCP だろうが、オンプレだろうがなんでも好きな環境で動かすことができます。
サーバさえあれば起動までは 10 分です。デモ機能が内蔵しているので動かすまで 15 分です。
- 大変多くのお客様に採用いただいております
- とにかく 落ちないこと を目的に作っています
- とにかく 繋がること を目的に作っています
- とにかく 手間がかからないこと を目的に作っています
- 最新ブラウザのアップデートに追従しています
- シグナリングサーバ内蔵ですので別途立てる必要はありません
- TURN サーバ内蔵ですので別途立てる必要ありません
- 日本語によるサポート対応しています
- フルスクラッチ自前実装なのですべて把握しています
- 1:1 の双方向に対応しています
- 1:300 の片方向に対応しています
- 3:300 といった配信者が複数の片方向にも対応しています
- スポットライトという機能を利用することで 50 人以上の会議に対応しています
- 録画機能があります
- Chrome / Firefox / Edge / Safari といった主要ブラウザ全てに対応しています
- Apache 2.0 ライセンスで JavaScript と iOS と Android のクライアント SDK を公開しています
- Apache 2.0 ライセンスで React Native 向け WebRTC ライブラリを公開しています
- https://github.com/shiguredo/react-native-webrtc-kit
- Sora と簡単に利用可能なサンプルも公開しています
- 既存システムとの連携を重視しており、Web フック機能を利用して簡単に連携が可能です
- 認証や、クライアントの接続切断などもすべて HTTP での通知を既存のシステムに送ることができます
興味のある方はお気軽に sora at shiguredo.jp までお問い合わせください。
紹介や検討資料も公開しております。