
회사에서 미러링 서비스를 도맡아 개발하게 되었다.
웹사이트를 편집하면서 편집중인 화면이 모바일에서 어떻게 보이는지 실시간으로 보고 싶을 때 이용 가능한 서비스이다. 예를 들어 피그마 앱에도 해당 기능이 있는데, 디자인하며 실시간으로 스마트폰에서 비춰지는 모습을 확인하는 것이다.

우선 미러링 서비스를 위해서는 앱과 웹 사이 연결이 이루어져야 한다.
Firebase를 이은 차세대 강자 Supabase의 Realtime 서비스를 기존에도 활용하고 있었기 때문에, 이번에도 사용하기로 했다.
필요한 요구사항은,
1. 앱과 웹의 미러링 상태 상호 구독
2. 블록*이 변경될 때 정보를 웹 -> 앱에 전달한다.
3. 블록 변경 정보뿐 아니라, 블록 편집 정보를 웹 -> 앱에 전달한다.
블록: 웹사이트 편집 간 하나하나의 섹션을 블록이라고 부른다. 헤더, 히어로, 헤더, 상품, 공지사항 등등..
편집 정보: 캐러셀 블록을 편집중이라면 몇 번째 슬라이드를 편집중인지 등
세 가지 방법이 있었다.
• Broadcast: 클라이언트 간 임의의 메시지를 실시간으로 주고받는 PUB/SUB 브로드캐스트 채널.
• RealtimeDB: Postgres의 테이블 변경사항을 실시간으로 스트리밍
• Presence: 같은 채널에 접속한 사용자들의 온라인 상태·참여 정보(존재 상태)를 추적하는 기능, 피그마에서 접속되어있는 사용자 정보를 보는 것과 동일한 개념이다.

편집 정보를 주고 받는데 갑자기 웬 Postgres changes가 나오는지 의아할 수 있겠는데, 정보를 잃어버리지 않기 위한 목적이었다.
예를 들어 Broadcast나 Presence는 폰이 시간이 지나 잠금 상태가 되거나, 백그라운드 상태가 되면 연결이 끊길 수 있다. 이외에도 와이파이 상태 불량 등 연결이 끊어질 수 있는 많은 케이스가 존재하고, 이는 정보의 불일치를 불러일으키게 된다.
그래서 웹에서 DB에 정보를 넣어두면, 앱에서 정보를 받아오는 식으로 구현하면 이를 해소할 수 있다. Mermaid를 사용하여 그려보면 이런 느낌이다.

그러나 나는 DB를 사용한다는 게 뭔가뭔가였다.
결국 우리가 필요한 것은 블록들의 최종 상태이며, 블록이 변해가는 중간 과정까지 읽어와야 할 필요가 있나? 싶었다.
또한 실시간 미러링 정보 또한 최신 상태가 가장 중요한 것이고, 누가 나갔다 들어왔는지, 미러링을 켜둔 상태인지 아닌지 과거의 기록은 필요하지 않다고 생각했다.
DB 사용 -> 불필요한 오버헤드만 늘어난다고 생각했기 때문에 Presence + Broadcast Service를 사용하는 것을 건의드렸고, 회의실에 모여 모든 요구 사항을 만족하는지 1-2시간 정도 얘기를 나누게 되었다.
에디터(뷰어)에서 미러링 버튼을 눌렀을때 뷰어(앱)에 메시지가 전달되어야함. 앱은 이때 꺼진 상태였다가 다시 연결될 가능성 있음
에디터에서 페이지 뷰를 바꾸었을때 이 상태가 뷰어에 전달되어야함. 앱은 이때 꺼진 상태였다가 다시 연결될 가능성 있음
에디터에서 특정 블록에 대해 slide를 바꾸었을때 이 상태가 앱에
전달되어야함. 여러개의 블록의 슬라이드가 각각의 값을 가지고 있을 수 있음. 앱은 이때 꺼진 상태였다가 다시 연결될 가능성 있음
뷰어가 먼저 미러링을 눌렀을때, 에디터가 켜진 상태라면 미러링이 시작되어야함
뷰어에서 의도적으로 미러링을 닫았을때(미러링 나가기 버튼), 에디터에서는 이를 인지할 수 있어야함. 반대도 마찬가지.
유저 액션 없이 확실히 한쪽의 커넥션이 끊겼다고 판단될때(앱 강제 종료 등). 일정시간 후 다른 한쪽에서는 이를 인지할 수 있어야함.
말고도 정말 여러 케이스들이 있는데...(웹에서 다중 탭 켜져있는 경우? 앱이 여러 디바이스로 여러 개 켜져있는 경우?) 이건 너무 길어지니 다음 글에 적겠다..
일단은 여러 논리 검증을 통해 Presence + Broadcast Service로 충분히 가능할 것 같다! 는 결론을 내렸다.
이후 결정해야하는 것은 Presence에 각각 클라이언트(뷰어, 에디터)는 몇 개의 미러링 상태를 지니고 있어야 하는가?이다.
interface EditorPresenceState {
mirroring_state: 'mirroring' | 'idle' | 'rejected' ...
}
에디터에서 미러링이 켜져있는 상태이고, 이후에 뷰어가 접속한 상태라면 "미러링을 연결하시겠습니까?" 모달을 띄워야 한다. 아니오를 누르면 그 이후에는 뷰어가 다시 미러링 연결을 누를 때까지 모달이 떠서는 안된다.
뭐 이런 여러 UI 플로우와 앞서 나열한 케이스들에 따라 필요한 상태값 개수가 달라질 수 있다. 과연 내가 내린 결론은 무엇이었을까?
다음 글에 계속 . . .