에듀테크 프로젝트 대시보드
WebRTC & NAT 트래버설
영상통화·화면공유·게임 P2P는 브라우저끼리 직접 데이터를 주고받는다. 그런데 우리 컴퓨터는 대부분 공유기(NAT) 뒤에 숨어 있어서 서로의 진짜 주소를 모른다. WebRTC는 STUN·TURN·ICE라는 3가지 도구로 이 "서로 못 찾는 문제"를 푼다.
| 구분 | STUN | TURN |
|---|---|---|
| 역할 | "내 공인 주소가 뭐야?"를 알려주는 거울 | 두 피어 사이 트래픽을 대신 중계하는 우체국 |
| 데이터 경로 | 연결만 도와주고 빠짐 → 이후 완전 P2P | 모든 패킷이 TURN 서버를 경유 (P2P 아님) |
| 비용/지연 | 거의 공짜, 지연 최소 | 서버 대역폭 많이 씀, 지연·비용 증가 |
| 언제 | 대부분의 가정용 NAT (원뿔형) | 대칭형 NAT·엄격한 회사 방화벽 등 최후의 수단 |
ICE는 host → srflx → relay 순으로 더 싼 경로부터 시도한다. 그래서 통계상 약 8~15%의 연결만 TURN까지 내려간다. 서비스 입장에선 이 소수를 위해 TURN 서버를 꼭 준비해야 통화가 "가끔 안 되는" 일이 없다.
const pc = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.l.google.com:19302" }, // 공인 주소 거울 { urls: "turn:turn.example.com", username: "u", credential: "p" } // 중계 (fallback) ] }); // ICE 후보가 하나씩 발견될 때마다 상대에게 전달 (Trickle ICE) pc.onicecandidate = (e) => { if (e.candidate) signaling.send({ ice: e.candidate }); }; // 데이터 채널 = 브라우저끼리 직접 연결된 파이프 const chan = pc.createDataChannel("chat"); chan.onmessage = (e) => render(e.data); const offer = await pc.createOffer(); await pc.setLocalDescription(offer); signaling.send({ sdp: offer }); // 시그널링 서버는 "소개"만, 데이터는 안 봄
시그널링 서버는 WebRTC 표준에 없다 — WebSocket이든 뭐든 자유. 두 피어가 SDP·ICE 후보를 "주고받게만" 해주면 되고, 연결이 뚫린 뒤엔 미디어/데이터가 서버를 거치지 않는다.