WebRTC란?
1. P2P 통신을 지원함(Peer-to-Peer)
2. 비디오, 오디오, 각종 데이터를 빠르게 통신가능 (P2P로 오는 장점)
3. 이에따라 낮은 지연시간이 지원됨.
Socket.io같은경우는, 모든 데이터가 소켓서버를 경유하기때문에, 어느정도 지연시간이
필연적이지만,
WebRTC는 P2P시스템을 지원하기에, 연결만 된다면 서버없이 클라이언트끼리
직통으로 데이터교환이가능하다.
특히, 데이터 크기가 큰 비디오, 오디오를 보낸다는것이 특징!
WebRTC는 3가지로 나뉜다.
1. Mesh : 1:1 과같은 화상통화인경우 많이사용한다.
Mesh는 사용자가 늘어날수록, 오고가는 트랙이 점점 많아지므로 가급적 적은 유저의 화상통화일경우만 쓰인다.
P2P의 특징이 가장 잘 살아나는 경우다.
2. MCU: n:m 통신일경우 사용한다.
이런 시스템은 Zoom 과같은 다 대 다 화상통화일경우 많이 사용한다.
각 클라이언트의 요청을받아 받은 데이터를 인코딩,가공하여 다시 다른 클라이언트에 주는 방식이다.
단, webRTC의 P2P특징이 많이 죽는 경우다. (사실 soket.io랑 별차이가 없다)
3. SFU: 1:N일경우 사용한다.
이런 시스템은 주로, 방송 (스트리밍)서비스를 할경우다. 하나의 비디오매체에, 다른 유저들이 참가하는 형태
클라이언트는 1개의 upStream과, 다른유저의 N개의 다운스트림을 받는다.
이번 포스팅은 P2P의 특징이 가장 잘 살아나는 Mesh형식을 사용하여 1:1 화상통화를 만들어보자.
와우.. 우린 이제부터 저 그림에 있는대로 전부 구현해야한다..
우선 WebRTC는 최대 5개의 서버가 필요하다!
1.서비스를 제공하는 서버
2. Socket 서버
3. STUN , TURN 서버
4. Media 서버
여기서 STUN , TURN , Media 서버만 더 자세히 설명을하자면,
STUN 서버는 , Simple Traversal of UDP through NATs
NAT (통칭:네트워크 주소 통신) 상에서 서로 통신할수있게 도와주는 서버다.
기본적으로 모든 컴퓨터엔 Private IP 가 존재하는데, 이 Private IP만으론 통신이 안된다.
통신을 하려면 PublicIP , 공인IP가 무조건 필요로한다.
STUN 서버에 서로의 위치, privateIP를 전달해 서로 어디있는지만 알려주는 정도만 한다.
TURN 서버
STUN 서버의 확장형인데, NAT의 규정이 엄격한곳은 , 저 STUN서버만으로 통신이 안되는 경우가 존재한다.
따라서, 규정이 엄격한곳은 클라이언트와 클라이언트 사이에 TURN서버라는 중개자를 둬서 통신하게한다.
Media 서버
오늘 개발할 Mesh형 WebRTC에겐 무관한 서버이긴 하다.
1:N 또는 , N:M처럼 많은 유저층이 같은곳에서 통신하기위해서 중앙에 Media서버가
중재하여 효율적으로 정보를 가공하는 역할을한다.
예시로 쿠렌토 미디어 서버가있다. (KMS)
즉, 개발할 서버는 총 3개
Express 서버 , socket 서버, STUN 서버이다.
WebRTC 는 다음과같은 순서가 필요하다.
1. STUN 서버 등록
2. Signaling
3. iceCandidate
여기서 중요한 부분만 빨간줄을 치겠다.
getMedia()
주석을 주렁주렁 달아논것뿐이지, 막상 보면 그리 복잡하진않다.,
우선 화상통화를 하기위해선 비디오와 오디오를 가져와야한다.
이 가져오는 메소드가바로, navigator.mediaDevices.getUserMedia() 이다.
여기서 deviceID에 따라, 초기설정과 , deviceId에 따른 설정이 갈린다.
deviceID를 넣고 호출하면 카메라 재설정이 되게끔 구현을 한것이다.
(EX: 휴대폰 셀카모드, 휴대폰 촬영모드 같이 카메라 전환할때)
getCameras()
카메라를 가져오는 메소드다.
우선, navigator.mediaDevices.enumerateDevices()로, 모든 디바이스들을 가져오고,
STUN 서버에 등록한다.
지금 webRTC를 하기위한 첫단계를 거친것이다.
makeConnection()
새로운 new RTCPeerConnection()을 생성한다.
Connection에 2개의 이벤트를 장착한다.
1. "icecandidate" 이벤트를 받으면 handleIce 호출
2. "addstream" 이벤트 받으면 handleAddStream 호출
*addstream 이벤트는 곧 deprecated가 되니 "track" 이벤트를 쓰는걸 권장합니다.*
이후, 아까 전에 getMedia()로 가져온 나의 카메라,비디오 트랙들을 RTC에 등록을한다.
startMedia() 와 handleIndexSubmit()
handleIndexSubmit은 , Room에 입장시 일어나는 이벤트다.
이전 socket.io에서 가져온 코드를 활용했다.
Room에 입장하면, startMedia() 즉, getMedia, getCamera, makeConnection()이 일어나서,
첫번째스텝을 준비하는단계다.
이후, "join_room" 이벤트를 서버측으로 보낸다.
Server.js
소켓 서버 측 코드다.
"join_room" 이벤트를 받으면 새로운 방을 생성한다. (화상채팅방)
그 후 , "welocme" 이벤트를 클라이언트에 보내고
스텝 2 . signaling이 시작된다.
Signalling 순서는 Offer 교환 -> Answer 교환 -> Ice 교환 순서대로 일어난다.
다시 돌아와 ,클라이언트측 (App.js)
설명은 주석에 달아놨다.
서버측 코드와 클라이언트 측을 보면 다음과 같은 교환이일어난다.
1.사용자 A -> offer 생성하여 보낸다.
2.사용자 B가 offer을 받아 등록한뒤, Answer을 생성하여 보낸다.
3.사용자 A가 Answer을 받아 등록한다.
4.Ice가 3번 (setRemoteDescription)을 감지하고 ,사용자 A가 ice를 보낸다
5.사용자 B가 ice를 받아 자신의 RTC에 ice를 등록한다.
=> signalling완료 이제부터 P2P통신이 가능하다.
이와같은 handleChatMessage를 호출하면,
소켓 서버없이 클라이언트끼리 채팅도 가능하다!!
'자바스크립트' 카테고리의 다른 글
Node.js + Socket.io 사용하기 (1) | 2023.03.14 |
---|---|
채팅방을 만들기위한 webSocket 개요! (0) | 2023.03.13 |
React: 영화 웹 서비스 클론 코딩 (0) | 2023.02.12 |
React App으로 간단한 To-Do 리스트 만들기 (0) | 2023.02.01 |
React App을 생성해보자. (0) | 2023.01.28 |