호스트 모니터링 claim / 그룹 모니터링 — 코드레벨 동작 흐름 P2코드레벨

마지막 업데이트 2026-07-22

작성일: 2026-06-14 대상: 개발자 — 진행자 모니터링 점유/중복 방지 파악 핵심 파일: sfu-socket/handlers/monitoring-handlers.ts

개요 · 범위

치료사(호스트)가 특정 세션(룸) 또는 그룹을 모니터링할 때 누가 점유 중인지(claim)를 관리해 중복 모니터링을 막고, 좀비 점유를 정리하는 서버측 로직. 모니터 대시보드(#13)의 진입 게이트, SFU 서버(#2) 핸들러군의 일부.

peers Map의 3가지 호스트 종류(peerKind): monitor-presence(접속만, MONITOR_CONNECTED #2) / monitoring-claim(특정 룸 점유) / group-monitoring-claim(그룹 카드뷰 점유). claim은 presence peer와 별도 peerId로 관리된다.

claim 식별 키

종류peerId의미
룸 모니터링monitoring-claim:{hostId}:{roomId}한 룸을 한 호스트가 점유(1:1/포커스뷰)
그룹 모니터링group-monitoring:{hostId}:{groupId}:{socketId}그룹 카드뷰 점유(socketId 포함 → 탭별)

룸 모니터링 시작 HOST_START_MONITORING L138

  1. 1idempotent: 같은 socket이 이미 같은 claim을 가지면 success 반환.
  2. 2중복 점유 확인: resolveOtherMonitor로 다른 socket(다른 탭/유저)이 이 룸을 점유 중인지 검사 — 메모리 + Redis(cross-instance) 양쪽(MONITOR_CLAIM_SOURCE).
  3. 3좀비 vs 살아있음: 다른 점유자가 있으면 isMonitorAlive로 소켓 생존 확인. 죽었으면(좀비) removePeer로 full cleanup 후 진행. 살아있으면 ALREADY_MONITORED(점유자 정보 동봉) 반환.
  4. 4claim 등록: monitoring-claim PeerInfo 생성(monitoringRoomId/monitoringGroupId). groupId 있으면 socket.join("monitor-group-{groupId}").
  5. 5broadcastRoomList(모니터링 상태 포함 갱신).

룸 모니터링 종료 HOST_STOP_MONITORING L232

  • monitoring-claim:{hostId}:{roomId} deletePeer.
  • 레거시 호환 정리: claim이 아닌 peer가 같은 roomId를 monitoringRoomId로 들고 있으면(구버전 잔재) null로 비움.
  • 그룹이면 socket.leave("monitor-group-{groupId}"). broadcast.

그룹 모니터링 HOST_START_GROUP_MONITORING L277

카드뷰(그룹 그리드) 진입 시 그룹 단위 점유. claim peerId에 socketId 포함 → 한 호스트가 여러 탭에서 같은 그룹을 봐도 탭별 claim. group-monitoring-claim PeerInfo 생성 + socket.join("monitor-group-{groupId}").

monitor-group-{groupId} socket room은 그룹 단위 broadcast(카드 상태·토스트 등)를 같은 그룹을 보는 모든 호스트에게 전달하는 통로다.

함정 · 주의

  • claim ≠ presence: 모니터 접속(presence)과 룸/그룹 점유(claim)는 별도 peerId. presence만 보고 점유 판단하면 안 됨.
  • cross-instance 점유 확인 필수: 다른 인스턴스의 호스트가 이미 점유 중일 수 있어 메모리만이 아니라 Redis도 봐야 한다(resolveOtherMonitor). 메모리/Redis 불일치는 warn 로깅.
  • 좀비 정리: 소켓이 죽었는데 claim이 남은 경우(isMonitorAlive false) removePeer로 정리 후 진행. 이 단계를 빼면 죽은 점유 때문에 영영 ALREADY_MONITORED.
  • 룸 claim은 1개, 그룹 claim은 탭별: 룸은 한 호스트 점유(중복 거부), 그룹은 socketId 포함이라 탭마다 별도. 키 생성 규칙 혼동 주의.
  • 레거시 monitoringRoomId 잔재: claim 도입 전 peer가 monitoringRoomId를 들고 있을 수 있어 stop 시 함께 정리.

파일 · 라인 레퍼런스

파일/심볼역할
monitoring-handlers.ts (HOST_START_MONITORING L138, STOP L232, GROUP L277)claim 등록·해제
resolveOtherMonitor / isMonitorAlive (L59~)cross-instance 점유·생존 확인
broadcast-utils.tsbroadcastRoomList/ConnectedHosts
connection-handlers.ts (MONITOR_CONNECTED)presence 등록(#2)