Developer · Hosting · WebRTC

WebRTC 사용법

교육생 사이트는 HTTPS + 카메라/마이크 권한 + 시그널링 웹소켓이 준비되어 있습니다. 영상·음성·데이터채널은 브라우저끼리 P2P로 주고받고, 연결을 맺는 신호만 서버 웹소켓으로 전달합니다.

준비된 것

  • HTTPS (https://{아이디}.zyo.kr) — getUserMedia 필수 조건
  • 카메라·마이크·화면공유: 같은 출처(self)에서 허용
  • 시그널링: wss://{아이디}.zyo.kr/ws (계정·방 단위 중계)
  • STUN 목록: GET /ws JSON의 iceServers
curl -sS https://아이디.zyo.kr/ws

카메라 시험

이 페이지(포털)와 교육생 사이트에서 카메라가 켜지는지 확인합니다. 브라우저가 권한을 물으면 허용하세요.

대기

시그널링

WebRTC 미디어는 서버를 거치지 않습니다. offer / answer / ICE candidate 만 웹소켓으로 교환합니다.

  1. 같은 방 wss://아이디.zyo.kr/ws/call 에 두 탭(또는 두 PC)이 접속
  2. 한쪽이 createOffer → JSON으로 send
  3. 상대가 setRemoteDescriptioncreateAnswer
  4. icecandidate 도 같은 방으로 전달

예제

const info = await fetch('/ws').then((r) => r.json());
const pc = new RTCPeerConnection({ iceServers: info.iceServers });
const ws = new WebSocket(`wss://${location.host}/ws/call`);

const local = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
local.getTracks().forEach((t) => pc.addTrack(t, local));

pc.onicecandidate = (ev) => {
  if (ev.candidate) ws.send(JSON.stringify({ type: 'ice', candidate: ev.candidate }));
};
pc.ontrack = (ev) => {
  remoteVideo.srcObject = ev.streams[0];
};

ws.onmessage = async (ev) => {
  const msg = JSON.parse(ev.data);
  if (msg.type === 'offer') {
    await pc.setRemoteDescription(msg.offer);
    const answer = await pc.createAnswer();
    await pc.setLocalDescription(answer);
    ws.send(JSON.stringify({ type: 'answer', answer }));
  } else if (msg.type === 'answer') {
    await pc.setRemoteDescription(msg.answer);
  } else if (msg.type === 'ice' && msg.candidate) {
    await pc.addIceCandidate(msg.candidate);
  }
};

async function call() {
  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);
  ws.send(JSON.stringify({ type: 'offer', offer }));
}

웹소켓은 보낸 사람도 메시지를 받습니다. 자기 offer를 다시 처리하지 않도록 호출자 구분 필드를 넣으세요.

한도 · 주의

  • 영상·음성은 P2P입니다. 서버 CPU/대역에 미디어가 실리지 않습니다.
  • NAT 통과용 STUN은 공개 서버를 씁니다. 일부 대칭 NAT 환경은 TURN 중계가 필요할 수 있습니다. (이 호스팅은 공인 UDP 포트가 없어 TURN을 두지 않습니다.)
  • 같은 Wi-Fi·같은 수업장에서는 대부분 STUN만으로 연결됩니다.
  • iframe 으로 넣을 때는 allow="camera; microphone; display-capture" 가 필요합니다.
  • 비밀번호·개인 영상을 불특정 방에 브로드캐스트하지 마세요.

WebSocket 사용법 호스팅