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

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

호스트 모니터링 claim / 그룹 모니터링 — 코드레벨 동작 흐름 P2 …: 입력: 개요 · 범위, 주요 처리 단계: 룸 모니터링 종료 HOST_STOP_MONITORING L232, 결과: 파일 · 라인 레퍼런스 흐름
동작 흐름 요약
  1. 입력: 개요 · 범위
  2. 주요 처리 단계: 룸 모니터링 종료 HOST_STOP_MONITORING L232
  3. 결과: 파일 · 라인 레퍼런스
문서 읽는 법 · 설명식

이 문서는 이렇게 읽으면 됩니다

호스트 모니터링 claim / 그룹 모니터링 — 코드레벨 동작 흐름의 핵심을 설명식으로 먼저 안내합니다. 기술적 결론과 원문 근거는 아래 본문에 보존되어 있습니다.

핵심 흐름 펼쳐 보기
  1. 비유와 핵심 질문으로 먼저 전체 구조를 잡습니다.
  2. 실제 컴포넌트·파일·데이터 흐름을 따라 내려갑니다.
  3. 코드 라인과 주의사항에서 구현 근거를 확인합니다.
  • 개요 · 범위
  • claim 식별 키
  • 룸 모니터링 시작 HOST_START_MONITORING L138
작성일: 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)