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 ()를 해당 지역의 미디어 스트림을 설정하고에 추가 RTCPeerConnection의 사용하여 객체 addStream () 메소드를.
제안 / 응답 협상 프로세스를 시작합니다. 이것은 호출자의 흐름이 수신자의 흐름과 다른 유일한 단계입니다. 호출자는 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 에이전트가 모든 원격 후보를 확인했지만 적어도 하나의 구성 요소와 일치하는 항목을 찾지 못했습니다.
disconnected − 적어도 하나의 구성 요소가 더 이상 살아 있지 않습니다.
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 제안을 설명합니다. 이 값이 변경되면 signallingstatechange 이벤트가 발생합니다. 가능한 값-
stable− 초기 상태. 진행중인 SDP 제안 / 답변 교환이 없습니다.
have-local-offer − 연결의 로컬 측이 SDP 제안을 로컬로 적용했습니다.
have-remote-offer − 연결의 원격 측이 SDP 제안을 로컬로 적용했습니다.
have-local-pranswer − 원격 SDP 제안이 적용되었고 SDP pranswer가 로컬에 적용되었습니다.
have-remote-pranswer − 로컬 SDP가 적용되었고 SDP pranswer가 원격으로 적용되었습니다.
closed − 연결이 닫혔습니다.
이벤트 핸들러
S. 아니. | 이벤트 처리기 및 설명 |
---|---|
1 | RTCPeerConnection.onaddstream 이 핸들러는 addstream 이벤트가 시작될 때 호출됩니다. 이 이벤트는 원격 피어가이 연결에 MediaStream을 추가 할 때 전송됩니다. |
2 | RTCPeerConnection.ondatachannel 이 핸들러는 데이터 채널 이벤트가 시작될 때 호출됩니다. 이 이벤트는 RTCDataChannel이이 연결에 추가 될 때 전송됩니다. |
삼 | RTCPeerConnection.onicecandidate 이 핸들러는 icecandidate 이벤트가 시작될 때 호출됩니다. 이 이벤트는 RTCIceCandidate 개체가 스크립트에 추가 될 때 전송됩니다. |
4 | RTCPeerConnection.oniceconnectionstatechange 이 핸들러는 iceconnectionstatechange 이벤트가 시작될 때 호출됩니다. 이 이벤트는 iceConnectionState 값이 변경 될 때 전송됩니다. |
5 | RTCPeerConnection.onidentityresult 이 핸들러는 identityresult 이벤트가 시작될 때 호출됩니다. 이 이벤트는 getIdentityAssertion ()을 통해 오퍼 또는 응답을 작성하는 동안 ID 어설 션이 생성 될 때 전송됩니다. |
6 | RTCPeerConnection.onidpassertionerror 이 핸들러는 idpassertionerror 이벤트가 시작될 때 호출됩니다. 이 이벤트는 IdP (Identitry Provider)가 ID 어설 션을 생성하는 동안 오류를 발견 할 때 전송됩니다. |
7 | RTCPeerConnection.onidpvalidation 이 핸들러는 idpvalidationerror 이벤트가 시작될 때 호출됩니다. 이 이벤트는 IdP (Identitry Provider)가 ID 어설 션의 유효성을 검사하는 동안 오류를 발견하면 전송됩니다. |
8 | RTCPeerConnection.onnegotiationneeded 이 핸들러는 협상 필요 이벤트가 시작될 때 호출됩니다. 이 이벤트는 브라우저에서 전송되어 향후 언젠가 협상이 필요함을 알립니다. |
9 | RTCPeerConnection.onpeeridentity 이 핸들러는 peeridentity 이벤트가 시작될 때 호출됩니다. 이 이벤트는이 연결에서 피어 ID가 설정되고 확인되었을 때 전송됩니다. |
10 | RTCPeerConnection.onremovestream 이 핸들러는 signallingstatechange 이벤트가 시작될 때 호출됩니다. 이 이벤트는 signallingState 값이 변경 될 때 전송됩니다. |
11 | RTCPeerConnection.onsignalingstatechange 이 핸들러는 removestream 이벤트가 시작될 때 호출됩니다. 이 이벤트는 MediaStream이이 연결에서 제거 될 때 전송됩니다. |
행동 양식
S. 아니. | 방법 및 설명 |
---|---|
1 | RTCPeerConnection() 새로운 RTCPeerConnection 객체를 반환합니다. |
2 | RTCPeerConnection.createOffer() 원격 피어를 찾기위한 오퍼 (요청)를 작성합니다. 이 메서드의 첫 번째 매개 변수 두 가지는 성공 및 오류 콜백입니다. 선택적 세 번째 매개 변수는 오디오 또는 비디오 스트림 활성화와 같은 옵션입니다. |
삼 | RTCPeerConnection.createAnswer() 오퍼 / 응답 협상 프로세스 중에 원격 피어가받은 오퍼에 대한 응답을 작성합니다. 이 메서드의 첫 번째 매개 변수 두 가지는 성공 및 오류 콜백입니다. 선택적인 세 번째 매개 변수는 생성되는 답변에 대한 옵션입니다. |
4 | RTCPeerConnection.setLocalDescription() 로컬 연결 설명을 변경합니다. 설명은 연결 속성을 정의합니다. 연결은 이전 설명과 새 설명을 모두 지원할 수 있어야합니다. 이 메서드는 RTCSessionDescription 객체, 설명 변경 성공시 콜백, 설명 변경 실패시 콜백의 세 가지 매개 변수를 사용합니다. |
5 | RTCPeerConnection.setRemoteDescription() 원격 연결 설명을 변경합니다. 설명은 연결 속성을 정의합니다. 연결은 이전 설명과 새 설명을 모두 지원할 수 있어야합니다. 이 메서드는 RTCSessionDescription 객체, 설명 변경 성공시 콜백, 설명 변경 실패시 콜백의 세 가지 매개 변수를 사용합니다. |
6 | RTCPeerConnection.updateIce() 원격 후보를 핑하고 로컬 후보를 수집하는 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를 설정합니다. 이름, 통신에 사용되는 프로토콜 및 선택적 사용자 이름의 세 가지 매개 변수를 사용합니다. |
19 | RTCPeerConnection.getIdentityAssertion() 신원 주장을 수집합니다. 응용 프로그램에서이 방법을 다룰 것으로 예상되지 않습니다. 따라서 필요를 예상하기 위해서만 명시 적으로 호출 할 수 있습니다. |
연결 설정
이제 예제 애플리케이션을 만들어 보겠습니다. 먼저“노드 서버”를 통해“시그널링 서버”튜토리얼에서 생성 한 시그널링 서버를 실행합니다.
페이지에는 두 개의 텍스트 입력이 있는데, 하나는 로그인 용이고 다른 하나는 연결하려는 사용자 이름입니다. 생성 된 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>
로그인을위한 텍스트 입력, 로그인 버튼, 다른 피어 사용자 이름에 대한 텍스트 입력, 그리고 connect-to-him 버튼이 추가되었음을 알 수 있습니다. 이제 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 핸들러 도 설정 합니다. 페이지를 새로 고침하고 두 개의 탭에서 열고 두 명의 사용자로 로그인 한 다음 두 사용자 사이에 연결을 설정하십시오. 다음 콘솔 출력이 표시되어야합니다.
이제 피어 투 피어 연결이 설정되었습니다. 다음 자습서에서는 비디오 및 오디오 스트림과 텍스트 채팅 지원을 추가합니다.