기술 블로그

WEB REMOTE를 구성하는 핵심 기술과 아키텍처를 깊이 있게 탐구합니다.

WebRTC: 브라우저 간 실시간 통신의 핵심

WebRTC (Web Real-Time Communication)는 웹 브라우저와 모바일 애플리케이션에서 별도의 플러그인 없이 실시간 음성, 영상, 데이터 통신을 가능하게 하는 오픈소스 프로젝트입니다.

WebRTC의 3가지 핵심 API

  1. getUserMedia: 카메라와 마이크에 접근하여 미디어 스트림을 가져옵니다.
  2. RTCPeerConnection: 피어 간 오디오/비디오 통신을 설정합니다.
  3. RTCDataChannel: 피어 간 임의의 데이터를 전송합니다.

WEB REMOTE에서의 WebRTC 활용

WEB REMOTE는 Electron 환경에서 getUserMedia API와 chromeMediaSource: "desktop" 옵션을 사용하여 호스트의 화면을 캡처하고, 이를 WebRTC를 통해 게스트에게 전송합니다. 이 과정에서 서버는 단순히 시그널링(Signaling) 역할만 수행하며, 실제 미디어 스트림은 P2P (Peer-to-Peer) 방식으로 직접 전송됩니다.

💡 참고: 웹 브라우저에서는 getDisplayMedia를 사용하지만, Electron 앱에서는 getUserMedia + chromeMediaSource 방식이 표준입니다.

// 호스트: 화면 캡처 및 스트림 생성 (Electron)
const stream = await navigator.mediaDevices.getUserMedia({
  audio: false,
  video: {
    mandatory: {
      chromeMediaSource: "desktop",
      chromeMediaSourceId: selectedSourceId
    }
  }
});

// RTCPeerConnection에 스트림 추가
stream.getTracks().forEach(track => {
  peerConnection.addTrack(track, stream);
});

P2P 연결의 장점

💡 알아두면 좋은 점

WebRTC는 기본적으로 DTLS (Datagram Transport Layer Security)를 사용하여 모든 미디어 스트림을 암호화합니다. 따라서 중간자 공격(Man-in-the-Middle Attack)으로부터 안전합니다.

시그널링 서버: WebRTC 연결의 중개자

WebRTC는 P2P 연결을 지원하지만, 초기 연결을 설정하기 위해서는 시그널링 서버가 필요합니다. 시그널링 서버는 두 피어가 서로를 찾고, 연결 정보를 교환할 수 있도록 돕습니다.

시그널링 프로세스

  1. Offer 생성: 호스트가 SDP (Session Description Protocol) Offer를 생성합니다.
  2. Offer 전송: 시그널링 서버를 통해 게스트에게 Offer를 전송합니다.
  3. Answer 생성: 게스트가 SDP Answer를 생성하여 호스트에게 전송합니다.
  4. ICE Candidate 교환: 양쪽이 ICE (Interactive Connectivity Establishment) Candidate를 교환합니다.
  5. P2P 연결 완료: 최적의 경로가 결정되면 직접 연결이 수립됩니다.

WEB REMOTE의 시그널링 구조

WEB REMOTE는 Socket.io를 사용하여 실시간 양방향 통신을 구현합니다. 호스트와 게스트는 각각 고유한 세션 코드를 통해 시그널링 서버에 연결되며, 서버는 이들 간의 메시지를 중계합니다.

// 게스트: 세션 참가
socket.emit('join_session', { code: '123456789' });

// 호스트: Offer 전송
socket.emit('signal', {
  target: guestSocketId,
  type: 'offer',
  payload: offer
});

// 게스트: Answer 수신
socket.on('signal', async (data) => {
  if (data.type === 'offer') {
    await peerConnection.setRemoteDescription(data.payload);
    const answer = await peerConnection.createAnswer();
    socket.emit('signal', { target: hostId, type: 'answer', payload: answer });
  }
});

보안 메커니즘: 안전한 원격 제어

원격 제어 서비스는 본질적으로 보안에 민감합니다. WEB REMOTE는 다층 보안 체계를 통해 사용자의 데이터를 보호합니다.

1. 일회성 세션 코드

매 세션마다 9자리 랜덤 코드가 생성되며, 세션이 종료되면 코드는 무효화됩니다. 이를 통해 무단 접속을 원천적으로 차단합니다.

2. WebRTC 암호화

모든 미디어 스트림은 SRTP (Secure Real-time Transport Protocol)로 암호화되며, 시그널링 데이터는 DTLS로 보호됩니다.

3. HTTPS 강제

모든 웹 페이지는 HTTPS를 통해 제공되며, HTTP로 접속 시 자동으로 HTTPS로 리다이렉트됩니다.

4. 세션 모니터링 및 Kick 기능

호스트는 실시간으로 접속 중인 게스트를 확인할 수 있으며, 의심스러운 접속은 즉시 강제 종료할 수 있습니다.

🔒 개인정보 보호

WEB REMOTE는 세션이 종료되면 어떤 데이터도 서버에 저장하지 않습니다. 화면 녹화나 로그 저장 기능이 없으므로, 프라이버시가 완벽하게 보호됩니다.

시스템 아키텍처: 3-Tier 구조

WEB REMOTE는 클라이언트-서버-호스트 3-Tier 아키텍처로 구성되어 있습니다.

1. 호스트 (Electron App)

Mac 또는 Windows에서 실행되는 Electron 기반 네이티브 앱입니다. RobotJS를 사용하여 OS 레벨의 마우스/키보드 제어를 수행하며, SQLite로 사용자 설정을 영구 저장합니다.

2. 중계 서버 (Node.js)

Express.jsSocket.io로 구축된 중계 서버는 다음 역할을 수행합니다:

3. 게스트 (Web Browser)

순수 HTML/CSS/JavaScript로 구현된 웹 클라이언트입니다. 별도의 설치 없이 브라우저만으로 실행되며, 모든 주요 브라우저(Chrome, Safari, Edge, Firefox)를 지원합니다.

// 시스템 구성
┌─────────────┐      ┌─────────────┐
│ Host (Mac)  │◄────►│ Relay      │
│ Electron    │ P2P  │ Server     │
│ App         │      │ (Node.js)  │
└─────────────┘      └─────────────┘
                         ▲
                         │ Signaling
                         ▼
                 ┌─────────────┐
                 │ Guest       │
                 │ (Browser)  │
                 └─────────────┘

성능 최적화: 초저지연을 위한 노력

원격 제어 서비스에서 가장 중요한 것은 지연 시간(Latency)입니다. WEB REMOTE는 다양한 최적화 기법을 통해 지연을 최소화합니다.

1. STUN/TURN 서버 활용

NAT (Network Address Translation) 환경에서도 P2P 연결이 가능하도록 STUN (Session Traversal Utilities for NAT) 서버를 사용합니다. 직접 연결이 불가능한 경우에만 TURN (Traversal Using Relays around NAT) 서버를 통해 중계합니다.

2. 적응형 비트레이트

네트워크 상태에 따라 자동으로 비디오 품질을 조절하여 끊김 없는 스트리밍을 제공합니다.

3. 효율적인 좌표 계산

마우스 좌표를 전송할 때 정규화된 좌표(0.0 ~ 1.0)를 사용하여 해상도에 관계없이 정확한 위치를 계산합니다.

// 정규화된 좌표 계산
const normalizedX = (mouseX - videoStartX) / videoDisplayWidth;
const normalizedY = (mouseY - videoStartY) / videoDisplayHeight;

// 호스트에서 실제 좌표로 변환
const actualX = normalizedX * screenWidth;
const actualY = normalizedY * screenHeight;

🚀 더 알고 싶으신가요?

WEB REMOTE의 기술에 대해 더 궁금한 점이 있으시면 언제든지 문의해 주세요.

문의하기