ここでは、XMPPを利用して、どのようにボイスチャットやビデオチャットを実現するのかを解説していきます。
XMPPにはJingleという拡張があり、これがボイスチャットやビデオチャットを実現するためのものになります。
関連する拡張と、その参照先をまとめて挙げておきます。
ボイスチャットやビデオチャットでは、音声や映像などのメディアデータを通信相手とやりとりすることになります。このようなデータをXMPPサーバーを介してやり取りするとサーバーに大きな負荷がかかるので、クライアントは、こういったデータを、通信相手とP2Pで直接やりとりするのが基本です。
ただし、P2Pでのメディアデータのやりとりを行うセッションの管理は、XMPPサーバーとの接続を利用します。XMPPサーバーを仲介するかたちで、ボイスチャットの開始リクエストや、終了リクエスト、そこで利用されるコーデックの候補など、セッションに関連する情報を通信相手とやりとりします。
[図が入る]
VoIPのコンテキストにおいて、上のXMPPとクライアントとの接続のように、セッションに関する情報をやり取りするチャンネルのことをシグナリングチャンネル、メディアのデータをやりとりするクライアント同士のP2Pの接続のチャンネルをデータチャンネルと呼びます。
このように、二つのチャンネルを利用するということをまずは理解して下さい。
Jingleでは、シグナリングチャンネルを利用した、クライアント同士のセッション確立のためにはICEという仕様を利用します。データチャンネルでのデータ転送にはRTP/RTCPを利用します。これらについては後で解説します。
ICEやRTP/RTCP以外を使うことも出来ないわけではないですが、Jingleにおいては、これらがデファクトスタンダードになっています。
さて、データチャンネルのP2Pコネクションが簡単に確立できればよいのですが、大抵の場合は簡単にはいきません。NATによるfirewallやIPマスカレード(NAPT)などの問題があるからです。
[図が入る]
NATを越えてP2P通信を実現するための議論というのが、昔から継続されていて、様々な方法が公安、実践されています。
そのNAT越え(NAT Traversal)の手段の中で、現在よく使われているものがICEです。他にもUPnPとか、Simultaneous TCP Openだとか、色々な方法があるのですが、ここでは省略します。
ICEでは、基本的には、NAT越えにおいてもっともベーシックなUDP Hole Punchingを行い、そのためにSTUNというプロトコルを利用します。
ここで、NATの種類とUDP Hole Punchingについて少し言及しておきます。以前は、NATは大きくわけて4種類になると考えられていました。なので、まずクライアントに対応するNATが4種類のうちのどれに該当するのかをチェックし、それぞれの攻略法に従って穴を空けようという戦略です。ところが、現在では様々なNATが存在し、このような固定された分類はあまりあてにならないとされるようになりました。しかし、それぞれの性質自体は一度見ておくとよいと思います。
NATの種類は次に挙げられるものになります。
詳しくはこちらを参照するとよいでしょう。Wikipedia - ネットワークアドレス変換
現在では、NATのそれぞれの振舞いについてRFC4787で、別々に分類がなされています。
振舞いの種類は次に挙げられるものになります。
ここで用いられるSTUNサーバーの役割は非常に単純で、グローバルネットワークにおいて、そのクライアントのIPアドレスとポートがどのように見えるかを教えてくれるだけです。このようなIPアドレスとポートの組み合わせをトランスポートアドレスと呼びます。
トランスポートアドレスには色々種類があり、STUNで取得するアドレスは、サーバーリフレクシヴトランスポートアドレス ( Server Reflexive Transport Address )と呼ばれます。
クライアントは、OSのAPIを通じてNICから取得したトランスポートアドレスや、STUNを利用して取得したトランスポートアドレスをリストアップし、シグナリングチャンネルを通して通信したい相手に渡します。それぞれのトランスポートアドレスでP2P通信が可能かどうかを順番にチェックしていくわけです。
このように、なんとかトランスポートアドレスを確保してP2P通信を行おうとしますが、NATによってはSTUNを利用したとしてもそれが出来ない場合があります。そういった場合のためにTURNという仕様がRFC5786で定義されていて、ICEでも、STUNと組み合わせてTURNが利用されるようになっています。
簡単に言えば、P2Pで通信する代わりにTURNサーバーがクライアントから受け取ったデータを中継して、通信相手に届けます。ですのでTURNサーバーのことをリレーサーバーと呼びます。もちろんこれはサーバー側からしたら大きな負荷のかかるサービスであり、可能な限りSTUNなどで対応し、TURNを利用するのは最後の手段であるべき、とされています。
ここでSIPというプロトコルについて少し紹介しておきます。
RFC3261: Session Initiation Protocol (SIP)
いわゆるIP電話に利用されているプロトコルで、上で説明したシグナリングチャンネルとして利用されています。
[図が入る]
SIPにおいても、当然データチャンネルでNAT越えが必要になる場合があります。XMPP上のJingleで利用されるNAT越えのための各種プロトコルは、もともとSIPのコンテキストで議論されていたものがほとんどです。関連のドキュメントもSIPと組み合わせて解説されているものも多いです。
例: RFC6314: Practices for Client-Server SIP
なので、これらの関連プロトコルで頻出する用語も、もともとSIP絡みのVoIPで利用されていたものが多くなります。Jingleを学習しだすと、これまでのXMPPの用語ではなく、SIP/VoIPの用語が頻出するので戸惑うことになるかもしれません。そういうわけで、直接SIPを利用しなかったとしても、この分野(jingle)を学習する場合は、事前にSIP関連の文献に一度目を通しておくことを奨めます。
余談ですが、SIPにもSIMPLE(SIP for Instance Messaging and Presence Leveraging Extensions)という、メッセージングとプレゼンスを扱うための拡張があります。 SIPは電話から始まって、テキストベースのメッセージとプレゼンスのサポートを後から拡張し、XMPPは逆にテキストベースのメッセージとプレゼンスから始まり、jingle拡張によってAudio/Videoチャットをサポートしたわけです。
http://www.ietf.org/rfc/rfc3264.txt