3. p2p 연결 생성하기
3-1) icecandidate 이해하기
offer 와 answer이 끝날 때, p2p연결의 양쪽에서는 icecandidate 이벤트를 실행할 것임.
여기서ice는 internet connectivity establishment를 의미하며 '인터넷 연결 생성'을 의미한다.
icecandidate는 통신할 때 필요한 프로토콜과 라우팅 정보인데, 연결이 이루어지고 나면 이를 이용해 서로 데이터 교환을 시도할 수 있다. WebRTC연결이 처음 시작되면 일반적으로 icecandidate가 각 peer에서 여러개 만들어진다.
우리는 그중 하나를 연결에 이용하면 됨.
3-2) 이벤트 핸들러 함수 정의하기
//offer 받는 쪽.
socket.on("offer", async(offer) => {
console.log("received the offer");
myPeerConnection.setRemoteDescription(offer);
const answer = await myPeerConnection.createAnswer();
myPeerConnection.setLocalDescription(answer);
socket.emit("answer", answer, roomName)
console.log("sent the offer");
})
//answer 받는 쪽.
socket.on("answer", answer => {
console.log("received the offer");
myPeerConnection.setRemoteDescription(answer);
})
function makeConnection() {
myPeerConnection = new RTCPeerConnection();
myPeerConnection.addEventListener("icecandidate", handleIce);
myStream.getTracks()
.forEach(track => myPeerConnection.addTrack(track, myStream));
}
function handleIce(data) {
console.log("got ice candidate");
console.log(data);
}
handleIce 함수가 이벤트 핸들러 역할을 담당할 것이고 icecandidate이벤트로부터 객체가 전달될 것임.
<결과확인>
여러개의 icecandidate 타입 확인가능
앞서말했듯이 딱 한개만 존재하는 데이터가 아니라서 콘솔창에 여러개가 출력됨을 이해해야한다.
3-3) candidate 교환하기
candidate는 브라우저가 우리에게 '이게 바로 브라우저간의 소통 방법이다' 라고 알려주는 일종의 정보다.
브라우저 1의 candidate는 브라우저2로
브라우저 2의 candidate는 브라우저 1로 교환되어야 한다.
app.js
socket.on("ice", ice => {
console.log("received candidate");
myPeerConnection.addIceCandidate(ice);
})
function handleIce(data) {
console.log("sent cadidate");
socket.emit("ice", data.candidate, roomName);
}
server.js
socket.on("ice", (ice, roomName) => {
socket.to(roomName).emit("ice", ice);
});
설명 : candidate 속성을 서버에 보내고 서버에서 받은 candidate를 같은 채팅룸에 있는 다른 탭에게 전달해줌. 다시 app.js에서 addIceCandidate메서드를 통해 전달받은 candidate를 내 peer에 추가하는 역할을 함.
<결과 확인>
서로서로 candidate까지 잘 주고받는것 확인가능하다.
2. 미디어 교환하기
2-1) addstream 이벤트 추가하기
화면도 공유해야함.
addstream을 사용하고 makeConnection 함수에 이벤트함수를 추가로 등록할 것임.
//RTC Code
function makeConnection() {
myPeerConnection = new RTCPeerConnection();
myPeerConnection.addEventListener("icecandidate", handleIce);
myPeerConnection.addEventListener("addstream", handleAddStream);
myStream.getTracks()
.forEach(track => myPeerConnection.addTrack(track, myStream));
}
function handleAddStream(data) {
}
addstream 이벤트는 peer 간의 연결에 스트림을 추가하면 발생하는 이벤트.
우리는 영상과 소리를 위해 스트림을 사용하고 있으니 이 이벤트에 코드를 추가하는것이 맞음.
2-1) 대화 상대의 미디어 출력하기
home.pug를 다음과 같이 수정
div#myStream
video#myFace(autoplay, playsinline, width="400", height="400")
button#mute Mute
button#camera Turn Camera Off
select#cameras
video#peerFace(autoplay, playsinline, width="400", height="400")
video 요소를 추가하외 id가 peerFace이다.
추가로 app.js 수정을 다음과 같이 하자.
function handleAddStream(data) {
const peerFace = document.getElementById("peerFace");
peerFace.srcObject = data.stream;
}
이제 상대방의 stream이 화면에 출력될 것임.
<결과화면>
성공 ! 브라우저 1 과 2의 화면이 잘 동시에 출력된다.
카메라 1은 브라우저1의 카메라고 / 카메라2는 브라우저 2의 카메라이다.
따라서 브라우저 1의 카메라를 끄면
브라우저 1화면
브라우저 2 화면
p2p가 잘 이뤄지는 것을 확인할 수 있다.