세 가지 구성 요소, 하나의 목표
Timmy의 내부 구조는 꽤 실용적으로 만들었습니다: Flutter 는 앱에, WebRTC 는 실시간 오디오와 영상에, 그리고 Firebase 는 연결 조정에 사용합니다. 모든 것을 클라우드로 보내는 거대한 플랫폼을 만들고 싶지는 않았습니다. 각 부분은 가능한 한 적은 정보만 알면서도 서로 안정적으로 작동해야 합니다.
WebRTC: 기본으로 암호화되는 직접 연결
WebRTC(Web Real-Time Communication)는 아기 기기와 부모 기기 사이에서 오디오와 영상을 전송합니다. 가장 좋은 경우 데이터는 두 기기 사이에서 직접, P2P 방식으로 흐르며 중간에 미디어 서버가 없습니다.
모든 WebRTC 연결은 기본적으로 DTLS-SRTP를 사용합니다. 누군가 네트워크 패킷을 가로채도 읽을 수 있는 오디오나 영상을 얻지 못합니다. 이 암호화는 프로토콜의 일부이므로 WebRTC에서 임의로 끌 수 없습니다.
저에게 중요한 점은 바로 이것이었습니다. 아기방 미디어는 제 서버에 있을 이유가 없습니다. 두 기기 사이에만 머뭅니다.
Firebase Firestore를 통한 시그널링
WebRTC를 시작하기 전에 기기들은 서로를 찾고 어떤 방식으로 연결할지 협의해야 합니다. 이 과정을 시그널링이라고 합니다. Timmy는 이를 위해 Google의 클라우드 데이터베이스인 Firebase Firestore를 사용합니다.
교환되는 것은 기술적인 연결 데이터뿐입니다:
- SDP 오퍼와 응답: 기기의 기능(지원 코덱, 해상도 등)을 설명합니다.
- ICE 후보: 기기들이 서로 도달할 수 있는 가능한 네트워크 경로입니다.
오디오와 영상은 Firebase에 저장되지 않습니다. Firestore는 기술적인 연결 데이터만 전달합니다. Timmy는 이 시그널링 계층도 암호화하므로, Firestore가 SDP와 ICE가 평문으로 모이는 장소가 되지 않습니다.
TURN 서버: 직접 연결이 안 될 때
엄격한 방화벽이나 일부 이동통신사처럼 직접 연결을 차단하는 네트워크도 있습니다. 이때 WebRTC에는 TURN 릴레이 (NAT 주변 릴레이를 통한 연결)가 필요합니다.
Timmy는 먼저 로컬 TURN 서버를 시도하고, 로컬 릴레이를 사용할 수 없거나 과부하 상태면 Cloudflare를 대체 경로로 사용합니다. 릴레이는 암호화된 패킷을 전달합니다. 소리나 영상의 키는 알 수 없으며 WebRTC 암호화는 그대로 유지됩니다.
TURN 자격 증명은 Firebase Cloud Function에서 발급되며 24시간만 유효합니다. 베이비 모니터 앱에 영구 자격 증명을 두는 것은 제 기준으로 너무 위험합니다.
Nearby Connections: 기기가 자동으로 서로를 찾습니다
아기 기기와 부모 기기를 번거롭게 설정하지 않아도 되도록 Timmy는 Nearby Connections를 사용합니다. Google은 Bluetooth와 Wi-Fi를 이용해 이 기기 탐색 계층을 제공합니다.
Timmy의 자동 페어링 은 코드를 직접 입력하지 않아도 작동합니다. 기기들이 서로를 발견하고 키 교환을 위한 동일한 접점을 찾습니다. 이 방식이 실패하면 4자 코드를 직접 입력할 수 있습니다. 페어링 코드는 기기를 절대 벗어나지 않습니다; Firestore에는 문서 식별자로 암호학적 해시(SHA-256)만 보입니다.
익명 인증
Timmy는 Firebase 익명 인증을 사용합니다. 처음 실행할 때 각 기기에는 임시 익명 ID가 부여됩니다. 계정, 이메일 주소, 비밀번호가 필요하지 않습니다. 이 ID는 Firestore 규칙을 적용하기 위한 것으로, 인증된 기기만 세션 데이터를 읽거나 쓸 수 있습니다.
구조: 누가 보내고 누가 받는가
Timmy에는 두 가지 모드가 있습니다:
- 아기 모드(송신): 기기가 마이크로 소리를 수집해 WebRTC로 부모 기기에 보냅니다. 필요하면 카메라를 켤 수 있고, 영상도 직접 전송됩니다.
- 부모 모드(수신): 기기가 오디오와 영상을 받아 카메라 영상을 보여주고, 아기 기기로 짧은 음성 메시지를 보낼 수 있는 푸시투토크 기능을 제공합니다.
푸시투토크와 카메라 켜기/끄기 같은 제어 기능은 DataChannel을 사용합니다. 이는 작은 암호화 메시지를 기기 간에 직접 전송하는 또 하나의 WebRTC 채널입니다.
왜 Flutter인가요?
Flutter는 여러 플랫폼용 앱을 만드는 Google의 프레임워크입니다. Timmy에서는 많은 로직을 한 번 작성해 Android와 iOS에서 사용할 수 있다는 뜻입니다. Timmy는 Android에서 사용할 수 있으며, iOS 버전도 출시를 앞두고 있습니다. 중복 코드가 적으면 버그가 생길 수 있는 곳도 줄어듭니다.
정리
기술 원칙은 간단합니다. Timmy는 꼭 필요한 데이터만 다뤄야 합니다. WebRTC는 미디어를 보호하고, Firebase는 연결 설정을 조정하며, TURN은 암호화된 패킷만 보고, Nearby Connections는 페어링의 번거로움을 줄입니다.
좋은 기술은 일상 속에 자연스럽게 녹아듭니다. 아기방을 클라우드 프로젝트로 만들지 않으면서도 잘 작동합니다.