엔지니어링 노트
PlainApp의 피어투피어 아키텍처, 트랜스포트 설계, 암호화에 대한 심층 분석 — 소스 코드에서 직접.
DLNA 캐스트: UPnP 송신기와 수신기를 처음부터 구축하기
PlainApp이 DLNA/UPnP AV 캐스팅을 양방향으로 구현하는 방법: 송신기로서 SOAP을 통해 TV를 스캔하고 제어하며, 수신기로서 스마트폰 자체를 UPnP MediaRenderer로 전환 — SSDP 디스커버리, DIDL-Lite 메타데이터, Range-request 미디어 서빙, GENA 이벤트 콜백, 그리고 송신자 IP 허용/차단 신뢰 모델까지, 모두 순수 Kotlin Multiplatform으로 구현.
Screen Mirror: 저지연 미러링 아키텍처
이 글에서는 PlainApp 화면 미러링 시스템의 엔드투엔드 설계를 다룹니다: Android에서 MediaCodec을 통해 H.264/Opus를 하드웨어 인코딩하는 방식, 커스텀 바이너리 프로토콜로 WebSocket을 통해 프레임을 전송하는 방식, Web 측에서 WebCodecs로 디코딩하고 WebGL2로 제로 CPU 복사로 렌더링하는 방식, 손실 감지, 방향 전환 처리, 원격 터치 제어 처리, 그리고 시스템 MediaProjection 생명주기 동기화 방식까지 설명합니다.
PlainApp 보안 심층 분석
PlainApp이 로컬 Wi-Fi에서 당신의 데이터를 어떻게 보호하는가 — 오픈소스 코드 기반의 증거와 함께.
Wi-Fi Aware 트랜스포트 설계 — 이웃 발견과 데이터 경로
이 글에서는 PlainApp이 피어 트랜스포트 폴백 체인의 중간 계층으로 Wi-Fi Aware(NAN — Neighbor Awareness Networking)를 사용하는 방법을 설명합니다. LAN(동일 서브넷 HTTPS)과 BLE(최후 수단 GATT RPC) 사이에 위치합니다. Wi-Fi Aware는 두 PlainApp 기기가 다른 SSID, 게스트 대 IoT VLAN, 또는 Wi-Fi 인프라가 전혀 없을 때 — DHCP 서버로부터 IP 주소가 전혀 필요 없이 — 통신하게 만드는 핵심 기술입니다.
BLE 트랜스포트 설계 — 메시지와 파일 다운로드
이 글에서는 PlainApp이 LAN이나 Wi-Fi Aware를 사용할 수 없을 때 Bluetooth Low Energy를 통해 채팅 메시지를 푸시하고 파일을 다운로드하는 방법을 설명합니다. BLE는 보장된 폴백입니다: 느리지만, IP 연결이 전혀 없어도 작동합니다. 이 글은 와이어 포맷, 2계층 청킹 설계, 동시 트래픽이 우선순위를 갖는 방식(그리고 갖지 않는 방식), 그리고 모든 연결이 각 요청 후 해체되는 이유를 다룹니다.
피어 및 채널 채팅 아키텍처
이 글에서는 PlainApp의 오프라인 우선 채팅이 종단 간으로 어떻게 작동하는지 설명합니다: 메시지가 UI의 탭에서 피어 트랜스포트를 통한 다른 기기까지 어떻게 이동하는지, 그룹 채널이 어떻게 다수의 멤버에게 메시지를 fan-out하는지, 그리고 네트워크가 사라질 때 시스템이 어떻게 회복력을 유지하는지를 다룹니다. 페어링(두 기기를 부트스트랩하는 신뢰 및 키 교환)은 별도의 Pairing Flow 글에서 설명합니다.
페어링 흐름
이 글에서는 두 대의 PlainApp 기기가 처음으로 신뢰를 설정하는 방법을 설명합니다. 즉, 기기들이 서로를 어떻게 발견하고, 키를 교환하며, 이후 모든 채팅 메시지·파일 전송·프레전스 핑을 암호화하는 데 사용되는 공유 ChaCha20 트랜스포트 키에 어떻게 도달하는지를 다룹니다. 이 키를 사용하는 채팅 및 채널 아키텍처는 별도의 Chat Architecture 글에서 설명합니다.