WebRTC DataChannel로 30ms 이내 입력 지연 만들기
PeerJS 기반 WebRTC DataChannel을 사용해 스마트폰 컨트롤러의 입력 지연을 줄이고, 연결 안정성을 높이는 실전 노트입니다.
왜 WebSocket이 아니라 WebRTC인가
스마트폰 컨트롤러처럼 1:1 또는 1:N 실시간 입력을 다룰 때 가장 먼저 떠올리는 선택지는 WebSocket입니다. 구현이 단순하고 호환성이 좋습니다. 하지만 서버를 거치는 구조이기 때문에 지연이 누적되고, 사용자가 늘어날수록 서버 비용도 같이 증가합니다.
Wandcade는 PC와 스마트폰 사이 입력에 PeerJS 기반 WebRTC DataChannel을 사용합니다. 두 기기가 직접 연결되므로 LAN 환경에서는 한 자리수 ms, 일반 가정망에서도 20~30ms 이내로 입력이 전달됩니다. 서버는 시그널링만 담당하기 때문에 동시 접속이 늘어나도 부담이 크지 않습니다.
입력 지연을 줄이는 메시지 설계
센서 입력은 빈도가 높습니다. DeviceOrientation은 보통 초당 60회, DeviceMotion은 그보다 더 자주 발생합니다. 매번 JSON으로 메시지를 보내면 직렬화 비용과 GC 부담이 빠르게 누적됩니다. 그래서 Wandcade의 컨트롤러는 입력 종류별로 짧은 키를 쓰고, 숫자는 소수점 자리를 제한합니다.
메시지 타입을 너무 잘게 쪼개면 송수신 양쪽에서 switch 분기가 늘어나 코드 가독성이 떨어집니다. Wandcade는 state_update, hit_feedback, pitch_start, ready, swing, stance 같은 큰 그룹으로 묶고, 같은 타입 안에서 필드를 확장하는 방식으로 운영하고 있습니다.
- 센서 값은 소수점 2~3자리로 잘라 보냅니다.
- 주기적 상태 업데이트와 일회성 이벤트를 메시지 타입으로 분리합니다.
- 메시지 한 건이 너무 커지지 않도록 필드를 최소화합니다.
- 재전송이 필요 없는 입력은 unreliable 모드(필요 시)를 검토합니다.
NAT, 방화벽, 모바일 네트워크 이슈
WebRTC는 직접 연결을 시도하지만, 실제 환경에서는 NAT와 방화벽 때문에 연결이 안 되는 경우가 있습니다. 가정용 공유기 환경은 대부분 STUN으로 해결되지만, 회사·학교·공용망에서는 외부 포트가 막혀 있어 TURN 서버가 필요한 경우가 있습니다.
비용 측면에서는 TURN 서버를 항상 띄워두기 부담스러울 수 있습니다. Wandcade는 우선 STUN만 사용하는 구조로 운영하고, 연결 실패 시 사용자에게 “현재 네트워크가 P2P 연결을 제한합니다. 모바일 데이터를 사용해보세요”라는 안내를 노출합니다.
모바일 데이터에서 와이파이로 또는 그 반대로 전환되면 ICE 후보가 갱신되어 잠시 연결이 끊깁니다. 이때 무한 재시도를 막기 위해 지수 백오프와 최대 시도 횟수를 같이 두면 사용자 경험이 안정됩니다.
연결 상태 가시화가 신뢰감을 만든다
입력 지연이 짧아도 사용자가 “지금 잘 연결된 건지” 의심하면 게임이 망설여집니다. Wandcade는 PC 화면에 컨트롤러 연결 상태와 핑을 작게 표시하고, 컨트롤러 화면에는 “연결됨/재연결 중/끊김”을 색깔로 보여줍니다.
연결이 끊겼을 때는 단순히 “연결이 끊겼습니다”만 보여주지 않고, 다음 행동(같은 QR로 재접속, 같은 방 코드 입력)을 같이 안내합니다. 사용자가 무엇을 해야 하는지 분명해야 다음 플레이가 이어집니다.