WebRTC-RTCPeerConnection API

RTCPeerConnection APIは、各ブラウザー間のピアツーピア接続の中核です。RTCPeerConnectionオブジェクトを作成するには、次のように記述します。

var pc = RTCPeerConnection(config);

ここで、config引数には、少なくともキーであるiceServersが含まれています。これは、ICE候補の検索中に使用されるSTUNおよびTURNサーバーに関する情報を含むURLオブジェクトの配列です。code.google.comで利用可能なパブリックSTUNサーバーのリストを見つけることができます

発信者であるか着信者であるかに応じて、RTCPeerConnectionオブジェクトは、接続の両側でわずかに異なる方法で使用されます。

これがユーザーのフローの例です-

  • onicecandidateハンドラーを登録します。ICE候補は、受信されると、他のピアに送信されます。

  • onaddstreamハンドラーを登録します。リモートピアから受信したビデオストリームの表示を処理します。

  • メッセージハンドラを登録します。シグナリングサーバーには、他のピアから受信したメッセージのハンドラーも必要です。メッセージにRTCSessionDescriptionオブジェクトが含まれている場合は、setRemoteDescription()メソッドを使用してRTCPeerConnectionオブジェクトに追加する必要があります。メッセージにRTCIceCandidateオブジェクトが含まれている場合は、addIceCandidate()メソッドを使用してRTCPeerConnectionオブジェクトに追加する必要があります。

  • getUserMedia()を利用してローカルメディアストリームを設定し、addStream()メソッドを使用してRTCPeerConnectionオブジェクトに追加します。

  • オファー/アンサー交渉プロセスを開始します。これは、呼び出し元のフローが呼び出し先のフローと異なる唯一のステップです。呼び出し元は、createOffer()メソッドを使用してネゴシエーションを開始し、RTCSessionDescriptionオブジェクトを受信するコールバックを登録します。そして、このコールバックは、この追加する必要がありRTCSessionDescriptionのあなたにオブジェクトをRTCPeerConnectionの使用してオブジェクトsetLocalDescriptionを() 。そして最後に、呼び出し元は、シグナリングサーバーを使用してこのRTCSessionDescriptionをリモートピアに送信する必要があります。一方、呼び出し先は同じコールバックを登録しますが、createAnswer()メソッドに登録します。呼び出し先フローは、呼び出し元からオファーを受け取った後にのみ開始されることに注意してください。

RTCPeerConnection API

プロパティ

  • RTCPeerConnection.iceConnectionState (read only)−接続の状態を説明するRTCIceConnectionState列挙型を返します。この値が変更されると、iceconnectionstatechangeイベントが発生します。可能な値-

    • new −ICEエージェントはリモート候補者を待っているかアドレスを収集しています

    • checking − ICEエージェントにはリモート候補がありますが、まだ接続が見つかりません

    • connected − ICEエージェントは使用可能な接続を検出しましたが、より良い接続のためにより多くのリモート候補をチェックしています。

    • completed − ICEエージェントは使用可能な接続を検出し、リモート候補のテストを停止しました。

    • failed − ICEエージェントはすべてのリモート候補をチェックしましたが、少なくとも1つのコンポーネントに一致するものが見つかりませんでした。

    • disconnected −少なくとも1つのコンポーネントが生きていません。

    • closed −ICEエージェントは閉じられています。

  • RTCPeerConnection.iceGatheringState (read only) −接続のICE収集状態を説明するRTCIceGatheringState列挙型を返します−

    • new −オブジェクトが作成されたばかりです。

    • gathering −ICEエージェントは候補者を集める過程にあります

    • complete ICEエージェントは収集を完了しました。

  • RTCPeerConnection.localDescription (read only)−ローカルセッションを説明するRTCSessionDescriptionを返します。まだ設定されていない場合はnullになる可能性があります。

  • RTCPeerConnection.peerIdentity (read only)−RTCIdentityAssertionを返します。これは、idp(ドメイン名)とリモートピアのIDを表す名前で構成されます。

  • RTCPeerConnection.remoteDescription (read only)−リモートセッションを説明するRTCSessionDescriptionを返します。まだ設定されていない場合はnullになる可能性があります。

  • RTCPeerConnection.signalingState (read only)−ローカル接続のシグナリング状態を説明するRTCSignalingState列挙型を返します。この状態は、SDPオファーを表します。この値が変更されると、signalingstatechangeイベントが発生します。可能な値-

    • stable−初期状態。進行中のSDPオファー/アンサー交換はありません。

    • have-local-offer −接続のローカル側がSDPオファーをローカルに適用しました。

    • have-remote-offer −接続のリモート側がローカルでSDPオファーを適用しました。

    • have-local-pranswer −リモートSDPオファーが適用され、SDPpranswerがローカルに適用されました。

    • have-remote-pranswer −ローカルSDPが適用され、SDPpranswerがリモートで適用されました。

    • closed −接続が閉じられます。

イベントハンドラー

S.No. イベントハンドラーと説明
1

RTCPeerConnection.onaddstream

このハンドラーは、addstreamイベントが発生したときに呼び出されます。このイベントは、MediaStreamがリモートピアによってこの接続に追加されたときに送信されます。

2

RTCPeerConnection.ondatachannel

このハンドラーは、データチャネルイベントが発生したときに呼び出されます。このイベントは、RTCDataChannelがこの接続に追加されたときに送信されます。

3

RTCPeerConnection.onicecandidate

このハンドラーは、icecandidateイベントが発生したときに呼び出されます。このイベントは、RTCIceCandidateオブジェクトがスクリプトに追加されたときに送信されます。

4

RTCPeerConnection.oniceconnectionstatechange

このハンドラーは、iceconnectionstatechangeイベントが発生したときに呼び出されます。このイベントは、iceConnectionStateの値が変更されたときに送信されます。

5

RTCPeerConnection.onidentityresult

このハンドラーは、identityresultイベントが発生したときに呼び出されます。このイベントは、getIdentityAssertion()を介したオファーまたはアンサーの作成中にIDアサーションが生成されたときに送信されます。

6

RTCPeerConnection.onidpassertionerror

このハンドラーは、idpassertionerrorイベントが発生したときに呼び出されます。このイベントは、IDアサーションの生成中にIdP(Identitry Provider)がエラーを検出したときに送信されます。

7

RTCPeerConnection.onidpvalidation

このハンドラーは、idpvalidationerrorイベントが発生したときに呼び出されます。このイベントは、IDアサーションの検証中にIdP(Identitry Provider)がエラーを検出したときに送信されます。

8

RTCPeerConnection.onnegotiationneeded

このハンドラーは、交渉が必要なイベントが発生したときに呼び出されます。このイベントはブラウザによって送信され、将来のある時点でネゴシエーションが必要になることを通知します。

9

RTCPeerConnection.onpeeridentity

このハンドラーは、peeridentityイベントが発生したときに呼び出されます。このイベントは、この接続でピアIDが設定および検証されたときに送信されます。

10

RTCPeerConnection.onremovestream

このハンドラーは、signalingstatechangeイベントが発生したときに呼び出されます。このイベントは、signallingStateの値が変更されたときに送信されます。

11

RTCPeerConnection.onsignalingstatechange

このハンドラーは、removestreamイベントが発生したときに呼び出されます。このイベントは、MediaStreamがこの接続から削除されたときに送信されます。

メソッド

S.No. 方法と説明
1

RTCPeerConnection()

新しいRTCPeerConnectionオブジェクトを返します。

2

RTCPeerConnection.createOffer()

リモートピアを見つけるためのオファー(リクエスト)を作成します。このメソッドの最初の2つのパラメーターは、成功とエラーのコールバックです。オプションの3番目のパラメーターは、オーディオまたはビデオストリームの有効化などのオプションです。

3

RTCPeerConnection.createAnswer()

オファー/アンサーネゴシエーションプロセス中にリモートピアが受信したオファーに対するアンサーを作成します。このメソッドの最初の2つのパラメーターは、成功とエラーのコールバックです。オプションの3番目のパラメーターは、作成する回答のオプションです。

4

RTCPeerConnection.setLocalDescription()

ローカル接続の説明を変更します。説明は、接続のプロパティを定義します。接続は、古い説明と新しい説明の両方をサポートできる必要があります。このメソッドは、RTCSessionDescriptionオブジェクト、説明の変更が成功した場合のコールバック、説明の変更が失敗した場合のコールバックの3つのパラメーターを取ります。

5

RTCPeerConnection.setRemoteDescription()

リモート接続の説明を変更します。説明は、接続のプロパティを定義します。接続は、古い説明と新しい説明の両方をサポートできる必要があります。このメソッドは、RTCSessionDescriptionオブジェクト、説明の変更が成功した場合のコールバック、説明の変更が失敗した場合のコールバックの3つのパラメーターを取ります。

6

RTCPeerConnection.updateIce()

リモート候補にpingを実行し、ローカル候補を収集するICEエージェントプロセスを更新します。

7

RTCPeerConnection.addIceCandidate()

リモート候補をICEエージェントに提供します。

8

RTCPeerConnection.getConfiguration()

RTCConfigurationオブジェクトを返します。これは、RTCPeerConnectionオブジェクトの構成を表します。

9

RTCPeerConnection.getLocalStreams()

ローカルMediaStream接続の配列を返します。

10

RTCPeerConnection.getRemoteStreams()

リモートMediaStream接続の配列を返します。

11

RTCPeerConnection.getStreamById()

指定されたIDでローカルまたはリモートのMediaStreamを返します。

12

RTCPeerConnection.addStream()

ビデオまたはオーディオのローカルソースとしてMediaStreamを追加します。

13

RTCPeerConnection.removeStream()

ビデオまたはオーディオのローカルソースとしてMediaStreamを削除します。

14

RTCPeerConnection.close()

接続を閉じます。

15

RTCPeerConnection.createDataChannel()

新しいRTCDataChannelを作成します。

16

RTCPeerConnection.createDTMFSender()

特定のMediaStreamTrackに関連付けられた新しいRTCDTMFSenderを作成します。接続を介してDTMF(デュアルトーン多重周波数)電話信号を送信できます。

17

RTCPeerConnection.getStats()

接続に関する統計を含む新しいRTCStatsReportを作成します。

18

RTCPeerConnection.setIdentityProvider()

IdPを設定します。名前、通信に使用されるプロトコル、およびオプションのユーザー名の3つのパラメーターを取ります。

19

RTCPeerConnection.getIdentityAssertion()

IDアサーションを収集します。アプリケーションでこのメソッドを処理することは期待されていません。したがって、必要性を予測するためにのみ明示的に呼び出すことができます。

接続の確立

それでは、サンプルアプリケーションを作成しましょう。まず、「シグナリングサーバー」チュートリアルで作成したシグナリングサーバーを「ノードサーバー」経由で実行します。

ページには2つのテキスト入力があります。1つはログイン用で、もう1つは接続するユーザー名用です。index.htmlファイルを作成し、次のコードを追加します-

<html lang = "en"> 
   <head> 
      <meta charset = "utf-8" /> 
   </head>
	
   <body> 
	
      <div> 
         <input type = "text" id = "loginInput" /> 
         <button id = "loginBtn">Login</button> 
      </div> 
	
      <div> 
         <input type = "text" id = "otherUsernameInput" />
         <button id = "connectToOtherUsernameBtn">Establish connection</button> 
      </div> 
		
      <script src = "client2.js"></script>
		
   </body>
	
</html>

ログイン用のテキスト入力、ログインボタン、他のピアユーザー名用のテキスト入力、および彼に接続するボタンが追加されたことがわかります。次に、client.jsファイルを作成し、次のコードを追加します-

var connection = new WebSocket('ws://localhost:9090'); 
var name = ""; 
 
var loginInput = document.querySelector('#loginInput'); 
var loginBtn = document.querySelector('#loginBtn'); 
var otherUsernameInput = document.querySelector('#otherUsernameInput'); 
var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); 
var connectedUser, myConnection;
  
//when a user clicks the login button 
loginBtn.addEventListener("click", function(event){ 
   name = loginInput.value; 
	
   if(name.length > 0){ 
      send({ 
         type: "login", 
         name: name 
      }); 
   } 
	
});
  
//handle messages from the server 
connection.onmessage = function (message) { 
   console.log("Got message", message.data);
   var data = JSON.parse(message.data); 
	
   switch(data.type) { 
      case "login": 
         onLogin(data.success); 
         break; 
      case "offer": 
         onOffer(data.offer, data.name); 
         break; 
      case "answer": 
         onAnswer(data.answer); 
         break; 
      case "candidate": 
         onCandidate(data.candidate); 
         break; 
      default: 
         break; 
   } 
};
  
//when a user logs in 
function onLogin(success) { 

   if (success === false) { 
      alert("oops...try a different username"); 
   } else { 
      //creating our RTCPeerConnection object 
		
      var configuration = { 
         "iceServers": [{ "url": "stun:stun.1.google.com:19302" }] 
      }; 
		
      myConnection = new webkitRTCPeerConnection(configuration); 
      console.log("RTCPeerConnection object was created"); 
      console.log(myConnection); 
  
      //setup ice handling
      //when the browser finds an ice candidate we send it to another peer 
      myConnection.onicecandidate = function (event) { 
		
         if (event.candidate) { 
            send({ 
               type: "candidate", 
               candidate: event.candidate 
            }); 
         } 
      }; 
   } 
};
  
connection.onopen = function () { 
   console.log("Connected"); 
};
  
connection.onerror = function (err) { 
   console.log("Got error", err); 
};
  
// Alias for sending messages in JSON format 
function send(message) { 

   if (connectedUser) { 
      message.name = connectedUser; 
   } 
	
   connection.send(JSON.stringify(message)); 
};

シグナリングサーバーへのソケット接続を確立していることがわかります。ユーザーがログインボタンをクリックすると、アプリケーションはユーザー名をサーバーに送信します。ログインが成功すると、アプリケーションはRTCPeerConnectionオブジェクトを作成し、見つかったすべてのicecandidateを他のピアに送信するonicecandidateハンドラーをセットアップします。次に、ページを開いてログインしてみます。次のコンソール出力が表示されます-

次のステップは、他のピアへのオファーを作成することです。次のコードをclient.jsファイルに追加します-

//setup a peer connection with another user 
connectToOtherUsernameBtn.addEventListener("click", function () { 
 
   var otherUsername = otherUsernameInput.value; 
   connectedUser = otherUsername;
	
   if (otherUsername.length > 0) { 
      //make an offer 
      myConnection.createOffer(function (offer) { 
         console.log(); 
         send({ 
            type: "offer", 
            offer: offer 
         });
			
         myConnection.setLocalDescription(offer); 
      }, function (error) { 
         alert("An error has occurred."); 
      }); 
   } 
}); 
 
//when somebody wants to call us 
function onOffer(offer, name) { 
   connectedUser = name; 
   myConnection.setRemoteDescription(new RTCSessionDescription(offer)); 
	
   myConnection.createAnswer(function (answer) { 
      myConnection.setLocalDescription(answer); 
		
      send({ 
         type: "answer", 
         answer: answer 
      }); 
		
   }, function (error) { 
      alert("oops...error"); 
   }); 
}
  
//when another user answers to our offer 
function onAnswer(answer) { 
   myConnection.setRemoteDescription(new RTCSessionDescription(answer)); 
} 
 
//when we got ice candidate from another user 
function onCandidate(candidate) { 
   myConnection.addIceCandidate(new RTCIceCandidate(candidate)); 
}

ユーザーが「接続の確立」ボタンをクリックすると、アプリケーションが他のピアにSDPオファーを提供することがわかります。また、設定onAnsweronCandidateハンドラを。ページをリロードし、2つのタブで開き、2人のユーザーでログインして、それらの間の接続を確立してみます。次のコンソール出力が表示されます-

これで、ピアツーピア接続が確立されました。次のチュートリアルでは、ビデオとオーディオのストリーム、およびテキストチャットのサポートを追加します。