Webrtc-rtcpeerconnection-apis
WebRTC-RTCPeerConnection API
RTCPeerConnection APIは、各ブラウザー間のピアツーピア接続の中核です。 RTCPeerConnectionオブジェクトを作成するには、単に書く
var pc = RTCPeerConnection(config);
ここで、_config_引数には少なくとも1つのキーiceServersが含まれます。 これは、ICE候補の検索中に使用される、STUNおよびTURNサーバーに関する情報を含むURLオブジェクトの配列です。 利用可能な公開STUNサーバーのリストは、https://code.google.com/p/natvpn/source/browse/trunk/stun_server_list [code.google.com]で見つけることができます。
呼び出し元であるか呼び出し先であるかに応じて、RTCPeerConnectionオブジェクトは、接続の両側でわずかに異なる方法で使用されます。
これは、ユーザーのフローの例です-
- _onicecandidate_ハンドラーを登録します。 受信したICE候補は、他のピアに送信されます。
- _onaddstream_ハンドラーを登録します。 リモートピアから受信したビデオストリームの表示を処理します。
- _message_ハンドラーを登録します。 シグナリングサーバーには、他のピアから受信したメッセージのハンドラーも必要です。 メッセージに_RTCSessionDescription_オブジェクトが含まれる場合、_setRemoteDescription()_メソッドを使用して_RTCPeerConnection_オブジェクトに追加する必要があります。 メッセージに_RTCIceCandidate_オブジェクトが含まれる場合、_addIceCandidate()_メソッドを使用して_RTCPeerConnection_オブジェクトに追加する必要があります。
- _getUserMedia()_を使用してローカルメディアストリームを設定し、_addStream()_メソッドを使用して_RTCPeerConnection_オブジェクトに追加します。
- オファー/アンサーネゴシエーションプロセスを開始します。 これは、呼び出し元のフローが呼び出し先のフローと異なる唯一のステップです。 呼び出し元は、_createOffer()_メソッドを使用してネゴシエーションを開始し、_RTCSessionDescription_オブジェクトを受け取るコールバックを登録します。 次に、このコールバックは、_setLocalDescription()_を使用して、この_RTCSessionDescription_オブジェクトを_RTCPeerConnection_オブジェクトに追加する必要があります。 最後に、呼び出し元は、シグナリングサーバーを使用して、この_RTCSessionDescription_をリモートピアに送信する必要があります。 一方、呼び出し先は同じコールバックを登録しますが、_createAnswer()_メソッドに登録します。 呼び出し先からのオファーが受信された後にのみ、呼び出し先フローが開始されることに注意してください。
RTCPeerConnection API
プロパティ
- * RTCPeerConnection.iceConnectionState(読み取り専用)*-接続の状態を説明するRTCIceConnectionState列挙を返します。 この値が変更されると、iceconnectionstatechangeイベントが発生します。 可能な値-
- 新規-ICEエージェントはリモート候補者を待っているか、アドレスを収集しています
- checking -ICEエージェントにはリモート候補がありますが、まだ接続が見つかりません
- connected -ICEエージェントは使用可能な接続を検出しましたが、接続を改善するためにさらに多くのリモート候補をチェックしています。
- 完了-ICEエージェントは使用可能な接続を検出し、リモート候補のテストを停止しました。
- 失敗-ICEエージェントはすべてのリモート候補をチェックしましたが、少なくとも1つのコンポーネントに一致するものが見つかりませんでした。
- 切断-少なくとも1つのコンポーネントが動作していません。
- closed -ICEエージェントは閉じられています。
- * RTCPeerConnection.iceGatheringState(読み取り専用)*-接続のICE収集状態を記述するRTCIceGatheringState列挙を返します-
- new -オブジェクトは作成されたばかりです。
- gathering -ICEエージェントは候補者を収集中です
- 完了 ICEエージェントは収集を完了しました。
- * RTCPeerConnection.localDescription(読み取り専用)*-ローカルセッションを説明するRTCSessionDescriptionを返します。 まだ設定されていない場合、nullになる可能性があります。
- * RTCPeerConnection.peerIdentity(読み取り専用)*-RTCIdentityAssertionを返します。 idp(ドメイン名)とリモートピアのIDを表す名前で構成されます。
- * RTCPeerConnection.remoteDescription(読み取り専用)*-リモートセッションを説明するRTCSessionDescriptionを返します。 まだ設定されていない場合、nullになる可能性があります。
- * RTCPeerConnection.signalingState(読み取り専用)*-ローカル接続のシグナリング状態を記述するRTCSignalingState列挙を返します。 この状態は、SDPオファーを説明しています。 この値が変更されると、signalingstatechangeイベントが発生します。 可能な値-
- 安定-初期状態。 進行中のSDPオファー/アンサー交換はありません。
- have-local-offer -接続のローカル側がSDPオファーをローカルに適用しました。
- have-remote-offer -接続のリモート側がローカルでSDPオファーを適用しました。
- have-local-pranswer -リモートSDPオファーが適用され、SDP pranswerがローカルに適用されました。
- have-remote-pranswer -ローカルSDPが適用され、SDP pranswerがリモートで適用されました。
- closed -接続は閉じられています。
イベントハンドラ
以下は、RTCPeerConnectionの一般的に使用されるイベントハンドラーです。
S.No. | Event Handlers & Description |
---|---|
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(IDプロバイダー)がエラーを検出したときに送信されます。 |
7 |
RTCPeerConnection.onidpvalidation このハンドラは、idpvalidationerrorイベントが発生したときに呼び出されます。 このイベントは、IDアサーションの検証中にIdP(IDプロバイダー)がエラーを検出したときに送信されます。 |
8 |
RTCPeerConnection.onnegotiationneeded このハンドラは、negotiationneededイベントが発生したときに呼び出されます。 このイベントは、将来のある時点でネゴシエーションが必要になることを知らせるために、ブラウザーによって送信されます。 |
9 |
RTCPeerConnection.onpeeridentity このハンドラは、peeridentityイベントが発生したときに呼び出されます。 このイベントは、この接続でピアIDが設定および検証されたときに送信されます。 |
10 |
RTCPeerConnection.onremovestream このハンドラーは、signalingstatechangeイベントが発生したときに呼び出されます。 このイベントは、signalingStateの値が変更されたときに送信されます。 |
11 |
RTCPeerConnection.onsignalingstatechange このハンドラーは、removestreamイベントが発生したときに呼び出されます。 このイベントは、この接続からMediaStreamが削除されると送信されます。 |
方法
以下に、RTCPeerConnectionの一般的に使用されるメソッドを示します。
S.No. | Methods & Description |
---|---|
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つは接続するユーザー名用です。 _indexl_ファイルを作成し、次のコードを追加します-
<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オファーを行うことがわかります。 _onAnswer_および_onCandidate_ハンドラーも設定します。 ページをリロードし、2つのタブで開いて、2人のユーザーでログインし、それらの間に接続を確立しようとします。 次のコンソール出力が表示されるはずです-
これで、ピアツーピア接続が確立されました。 次のチュートリアルでは、ビデオストリームとオーディオストリーム、およびテキストチャットのサポートを追加します。