사내 고객 화상회의 앱을 만들고 정적 사이트에 붙여봤습니다
WebSocket 시그널링 + WebRTC mesh로 동작하는 화상회의 데모를 만들고, 정적으로 배포되는 블로그에 실시간 백엔드를 어떻게 연결했는지 정리했습니다.

목차
사내 담당자가 고객과 빠르게 화상회의를 열 수 있는 가벼운 도구를 만들어봤습니다. 카메라·마이크 테스트, 대기실 승인, 채팅, 화면 공유, 갤러리/발표자/자유배치 레이아웃까지 브라우저만으로 동작합니다.
WebRTC mesh + WebSocket 시그널링
여러 명이 동시에 영상을 주고받으려면 참가자들끼리 미디어 트랙을 교환할 방법이 필요합니다. 이 프로젝트는 SFU 같은 중계 서버 없이 참가자 브라우저끼리 직접 연결하는 mesh 구조를 택했습니다. 대신 최초 연결을 트는 "누가 누구에게 접속을 시도할지" 정보는 WebSocket으로 오가는 시그널링 서버가 중개합니다.
참가자가 동시에 offer를 주고받으면 충돌이 나는데, 이를 정리하는 표준 패턴이 perfect negotiation입니다. 먼저 있던 참가자는 "무례한(impolite)" 쪽이 되어 자기 offer를 밀어붙이고, 새로 들어온 참가자는 "공손한(polite)" 쪽이 되어 충돌 시 자기 offer를 양보합니다. 역할만 명확히 나누면 코드는 생각보다 단순합니다.
정적 사이트에 실시간 백엔드를 붙이는 문제
이 블로그(idea-blog)는 Cloudflare Pages에 정적으로 배포됩니다. 문제는 화상회의가 필요로 하는 건 "요청 한 번에 응답 한 번" 하는 서버가 아니라, 누가 어느 방에 있는지를 메모리에 계속 들고 있는 상시 프로세스라는 점입니다. 정적 호스팅이나 엣지 함수로는 애초에 흉내 낼 수 없는 종류의 서버입니다.
그래서 화면(정적 파일)과 시그널링 서버는 완전히 분리했습니다. 시그널링 서버는 별도 Node 프로세스로 항상 떠 있고, 로컬 개발 중에는 리버스 프록시가 /client-meet/* 요청만 그 프로세스로 넘겨줍니다. 화면 쪽 자바스크립트는 어떤 시그널링 서버가 붙어 있는지 몰라도 되게 만들어서(같은 오리진의 /client-meet/ws에 접속하는 것만 알면 됨), Node 서버든 나중에 만든 Go 서버든 자바스크립트 코드 수정 없이 그대로 교체할 수 있습니다.
다음에 할 일
지금은 로컬 검증 단계라, 데모에서 새 회의방을 만드는 기능은 비밀번호로 잠가두었습니다(초대 링크로 들어오는 게스트 입장은 그대로 가능합니다). 실제로 외부에 상시 공개하려면 시그널링 서버를 별도의 항상 켜져 있는 호스트에 올리고, TURN 서버(NAT 뒤에 있는 사용자끼리도 연결되게 중계)까지 붙여야 서로 다른 네트워크에서도 안정적으로 연결됩니다. 이 부분은 별도로 정리할 예정입니다.
관련 글
원격 데스크톱을 직접 설계해보니 — '직접 연결 먼저, 안 되면 릴레이'의 정체
상대 PC를 보고 조작하는 원격 제어 도구를 설계하며 정리한 연결 전략(WebRTC ICE), 입력 주입, 그리고 보안 우선 설계 이야기입니다.
2026.07.12탭 2~3개만 쓰는 나를 위한 저메모리 브라우저 만들기
크롬이 왜 그렇게 무거운지 파고들다 WebView2로 개인용 미니 브라우저를 만들었습니다. 탭 서스펜드, 메모리 모니터, EasyList 광고 차단의 실제 구현 기록입니다.
2026.07.11아이패드를 노트북 보조 모니터로 — 웹으로는 못 만드는 도구를 만든 이야기
Windows 가상 디스플레이 생성, 화면 캡처, H264 하드웨어 인코딩, WebRTC 전송까지 — 브라우저 밖에서만 가능한 화면 확장 도구의 개발 기록입니다.
2026.07.11