Experts.jp日本に、もっとエキスパートを。(5)こんにちは!がねこまさしです。前回は複数人の同時通話まで実現しました。社内で使うには十分なレベルです。本格的な企業ユースとなると、まだまだ障害があります。会社と家、自社と別の会社さんなど、実際に通信しようとするとNATやFirewallといった壁が立ちはだかります。NATを越えようNATの役割はNAT(+IPマスカレード)は企業だけでなく、一般家庭でも使われています。ブロードバンドルーターやWiFiルーターでは、1つのグローバルIPアドレスを、複数のPCやデバイスで共有することができます。このとき、NATには2つの役割があります。複数のPC/デバイスが同時に通信できるように、ポートマッピングによるポート変換WebRTCでNAT越しに通信すること考えてみましょう。ブラウザが知っている情報ローカルネットワークのIPアドレス:A自分が使う(動的に割り振った)UDPポート:A/UDPブラウザでは分からない情報グローバルIPアドレス:A’NATによってマッピングされた、外部に向けたUDPポート:A’/UDPPeer-to-Peer通信を行うには、シグナリング処理でお互いに(ローカルネットワーク内の情報ではなく)インターネット側から見た情報を通知する必要があります。ブラウザーが、インターネット側から見た情報を知るための仕組みが、STUNになります。STUNの仕組みはSTUNの仕組みは意外とシンプルです。インターネット側にいる誰か(STUNサーバー)に、自分(ブラウザ)がどう見えるか教えてもらうだけです。STUNは元々WebRTCのために作られた仕組みではなく、より汎用的なUDP通信の補助として生まれました。VoIPやネットワークゲームの世界でも使われているようです。自分を外側から見た情報が分かったら、それをシグナリングサーバー経由で通信相手に渡します。お互いの情報が伝わったら、そこを目掛けて通信を行います。間にNATが挟まりますが、ポートを直接マッピングしているのであくまでもPeer-to-Peerです。STUNサーバーを動かそうそれでは実際にSTUNサーバーを動かしてみましょう。Linuxで動作するオープンソースのものがあるので、そちらを使います。rfc5766-turn-serverこのサーバはSTUNだけでなく、後程説明するTURNにも対応しています。DownloadページからOSに合わせたgzファイルをダウンロードし、INSTALL手順に従ってビルド、インストールしてください。参考までに以前私が実施した手順を載せておきます。※ちょっと古いバージョンです。最新のものを取得してインストールしてください。./install.shCentOSの場合、以下の場所に導入されました。ポイントとなるのは次の箇所です。STUN/TURNサーバーの接続待ポート番号。デフォルトは3478です。コメントアウトを外して数値を指定すれば、任意のポートに変更できます。STUN/TURNサーバーの接続待ポート番号。デフォルトは3478です。コメントアウトを外して数値を指定すれば、任意のポートに変更できます。configuration.##listening-port=3478TCPとUDPの両方で待ち受けできますが、STUNはUDPのみが有効なので注意が必要です。※つまりUDPが通らない環境ではSTUNは使えません。このサーバーはデフォルトでSTUN/TURNの両方をサポートしています。コメントアウトを外します。このサーバーはデフォルトでSTUN/TURNの両方をサポートしています。コメントアウトを外します。set.##stun-onlySTUNはPeer-to-Peer通信が始まればサーバーのCPU負荷、ネットワーク負荷はかかりません。それに対して後述するTURNでは特にネットワーク負荷がかかります。サーバーを借りていてネットワーク通信量で課金されるようなケースでは、stun-onlyを設定してTURNは無効にしておいた方が良いかもしれません。設定がすんだらSTUNサーバーを起動してみましょう。画面にエラーが出なければ無事に起動成功です。確認してみてください。/etc/turnserver/turnserver.confクライアントのソースを修正しようここまでで準備したSTUNサーバーを使うように、クライアント側のソースを修正しましょう。前回のソースの一部を変更します。デフォルトのポート3478で動いていると仮定します。その情報をPeerConnectionに教えてあげます。e.message);}//...省略...}さあ、これで接続を試してください。上手く行けば、自宅と友人の家で通信が可能になっているはずです。STUNでNATを越えられないときNATにはグローバルIPアドレスを共有するだけでなく、セキュリティ対策としての役割もあります。内部の端末を隠したり、通信できるポートを制限したり、一種の簡易Firewallとして利用されているケースもあります。その場合はFirewallの場合と同じく、次に説明するTURNを利用する必要があります。この場合もSTUNの仕組みでは通信することができません。TURNの出番ということになります。Firewallを越えよう一般家庭のようにブロードバンドルーターなどでNATがある環境では、STUNを使えば通信が可能になります。次は一般的な企業で使えるようにしましょう。企業ではFirewallが設置されているケースがほとんどです。その場合、外部と通信できるポートも制限されます。STUNではUDPポートは動的に割り振られるままなので、Firewallにとても大きな穴を空けないと通信ができません。セキュリティ管理者に怒られてしまいます。こんなケースに対応するのが、TURNの仕組みです。TURNもWebRTCのために生まれたのではなく、VoIPやネットワークゲームの世界で使われていたものです。TURNの仕組みはTURNを使った通信では、TURNサーバが実際のストリームデータを受け渡す間に入ります。すべてのパケットをTURNサーバーがリレーすることになり、もはやPeer-to-Peer通信ではなくなります。この際TURNサーバーでは動画のエンコーディングは行わないので、CPU負荷よりもネットワーク負荷が高くなりやすいです。Firewallに穴を空けようTURNを使うには、Firewallに1つ穴を空ける必要があります。標準では3478/UDPを使うので、そのポートが通過可能になるように設定して(してもらって)ください。1つ、シグナリングサーバーと通信するための穴も空ける必要があります。9000番を使うのであれば、9000/TCPも同様に通過可能になるように設定して(してもらって)ください。会社間で通信するのは、両方の会社でFirewallに穴を空ける必要があります。Firewallをいじらない方法もあるので、最後までお楽しみに。TURNサーバーを動かそうTURNサーバーは先ほどSTUNサーバーとしてインストールしたrfc5766-turn-serverがそのまま使えます。設定を変更してTURNとして使える様にします。STUN/TURNサーバーの接続待ポート番号。デフォルトは3478です。コメントアウトを外して数値を指定すれば、任意のポートに変更できます。STUN/TURNサーバーの接続待ポート番号。デフォルトは3478です。コメントアウトを外して数値を指定すれば、任意のポートに変更できます。configuration.##listening-port=3478デフォルトのポートは3478ですが、自由に設定できます。started.#no-dtlsTLS/DTLSは今回は使わない設定にしておきます。設定した場合は、再びコメントアウトしてTURNも使える様にして下さい。set.##stun-onlyそして、WebRTCでTURNを使う際のキモはこちらの設定です。認証の方法を選択します。次の3種類があります。lt-cred-mechを使用する必要がありますので、その行のコメントアウトを外します。同時に、realmも設定が必要になります。認証の方法を選択します。次の3種類があります。lt-cred-mechを使用する必要がありますので、その行のコメントアウトを外します。同時に、realmも設定が必要になります。必須だとは分からず、とても長い間悩んでしまいました。Redisなどで管理できますが、今回はシンプルにファイル管理にします。ユーザーアカウントを定義するファイル名を指定します。ユーザーアカウントを定義するファイル名を指定します。使うことにしたので、その内容も変更します。※実際にはもっと強度の高いパスワードにしてくださいね。turnserverを再起動すれば、TURNでの通信が有効になります。turnserverを安全に停止させる手段が分かりません。クライアントのソースを修正しようここまでで準備したTURNサーバーを使うように、クライアント側のソースを修正しましょう。STUNで修正した部分と同じ個所になります。デフォルトのポート3478で動いていると仮定します。その情報をPeerConnectionに教えてあげます。e.message);}//...省略...}さあ、これで接続を試してください。上手く行けば、会社と自宅、あるいは会社と友人の会社で通信が可能になります。Firewallはそのままで実際の企業ではセキュリティ上の制約や手続き上の問題で、Firewallに穴を空けるのが大変なことも多々あります。お客様の会社だったらなおさらですよね。両方ともサポートしてます。これを使えば、Firewallはそのままで、通信が可能になります。一つのポート番号で、UDPとTCPの両方を待ち受けすることができます。HTTPと同じ、80番を設定します。一つのポート番号で、UDPとTCPの両方を待ち受けすることができます。HTTPと同じ、80番を設定します。configuration.#listening-port=80設定が終わったら、turnserverを再起動してください。動かす必要があります。サーバー側のNode.jsのポート番号と、クライアント側のsocket.ioのつなぎ先のポート番号を80番に変更してください。※Webサーバー、シグナリングサーバー、TURNサーバーの3つをすべて80/TCPで動かすので、サーバーを3つ別々に立てる必要があります。さあ、これで最後です。ブラウザをリロードしてください。壁を越えて対話ができることと思います。最後にこれまで全5回、WebRTCの使いかたを説明してきました。開発者向けにコードを一から書いてきましたが、世の中には便利なライブラリやサービスも数多くあります。WebRTC開発者向けライブラリ「PeerJS」はこうして作られたWebRTCで注目された海外企業のサービス19本一挙公開こちらを利用するのもありですね。日本でWebRTCが盛り上がって、企業ユースでも認知されるのを期待しています。おつきあいいただき、どうもありがとうございました。