아동247 24회기 — 영상 완료 자동전환 실패 2건 재현 경로

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

2026-06-23 prod에서 발생한 “영상 재생 완료 시 활동 자동 전환 실패 2건”을 LogRocket 아동·진행자 세션과 Grafana ppi-socket-prod 로그로 대조한 재현 경로 문서다. 결론은 영상 시작 이벤트는 서버에 도달했지만 guest-video-end가 0건이고, 이후 진행자가 Host changed step으로 수동 전환했다는 것이다.
대상아동247 24회기 · 2026-06-23 · prod · 진행자 엘리스
roomId77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24
아동 세션LogRocket guest session — 아동247, Edge 149 / Windows 11
진행자 세션LogRocket facilitator session — 엘리스, Chrome 148 / macOS
Grafanappi-socket — ppi-socket-prod, env=prod, service=ppi-socket, 조회 범위 2026-06-23 20:28~20:58 KST
판정재현 경로 확정 영상 시작 있음 → guest-video-end 없음 → 진행자 수동 step 변경
REPRO PATH
이번 케이스의 최소 재현 경로
① 영상 step 시작Guest video play started가 ppi-socket에 기록됨
② 종료 이벤트 부재guest-video-end, video-end, video ended 검색 0건
③ 자동 전환 미발생게스트 로컬 onEnd → goToNextStep() 경로가 실행되지 않은 상태
④ 진행자 개입Host changed step가 먼저 찍히고 직후 Guest step update가 따라옴

1. 관찰 단서 — LogRocket

아동 세션

진행자 세션

LogRocket MCP 요약은 raw console export가 아니므로 문자열 존재 여부 확정에는 한계가 있다. 이번 확정 근거는 Grafana Loki에서 roomId로 직접 조회한 ppi-socket 로그다.

2. 관찰 단서 — Grafana ppi-socket-prod

대시보드 쿼리 구조는 {service="$service", env=~"$env", instance=~"$instance"} !~ "/health|/metrics"이며, 아래 roomId 문자열로 Loki query_range를 직접 조회했다.

{service="ppi-socket", env=~"prod", instance=~".*"} |= "77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24"

핵심 카운트

검색어결과의미
Guest video play started9건영상 step 시작/재생 시작 이벤트는 서버까지 도달.
guest-video-end, video-end, video end, video ended, guest-video0건영상 종료 이벤트는 ppi-socket에 도달하지 않음.
Host changed step2건자동 전환 대신 진행자 수동 step 변경이 발생.
disconnect수업 종료 부근 5건11:55:49Z 이후 cleanup. 실패 시점의 직접 원인은 아님.
Producer/Consumer생성 로그 존재아동 Producer ↔ 진행자 Consumer 연결 흐름 자체는 생성됨.

3. 두 실패 구간 타임라인

2026-06-23T11:30:58.742Z · KST 20:30:58
영상 시작
{"msg":"Guest video play started in room 77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24","prefix":"SFU-SessionHandlers","data":{"serverTimestamp":1782214258742}}

첫 영상 step 시작은 서버가 받았다.

2026-06-23T11:32:41.752Z · KST 20:32:41
실패 1 — 진행자 수동 전환
{"msg":"Host changed step in room 77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24","prefix":"SFU-SessionHandlers","data":{"activityIndex":0,"stepIndex":1,"stepType":"full:video","mediaType":"resource:video_pingpong16_new_hi_nomal_0"}}

guest-video-end 없이 Host changed step가 먼저 찍혔으므로 자동 전환이 아니라 진행자 수동 전환이다.

2026-06-23T11:32:41.763Z · KST 20:32:41
수동 전환 후 게스트 상태 동기화
{"msg":"Guest step update in room 77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24","prefix":"SFU-SessionHandlers","data":{"activityIndex":0,"stepIndex":1,"layoutMode":"full:video"}}

host step change 11ms 뒤 게스트 상태가 따라온다. 순서상 자동 전환이 아니다.

2026-06-23T11:46:51.288Z · KST 20:46:51
실패 2 — 진행자 수동 전환
{"msg":"Host changed step in room 77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24","prefix":"SFU-SessionHandlers","data":{"activityIndex":2,"stepIndex":0,"stepType":"full:ai","mediaType":""}}

두 번째 수동 전환도 Grafana에서 확인된다.

2026-06-23T11:47:25.385Z · KST 20:47:25
후속 영상 step 시작
{"msg":"Guest video play started in room 77b062db-a06e-4e7e-8987-d4ae1d26a5a3_24","prefix":"SFU-SessionHandlers","data":{"serverTimestamp":1782215245385}}

후속 영상들도 시작 이벤트는 계속 올라오지만, 전체 조회 범위에서 종료 이벤트는 0건이다.

4. 코드상 정상 경로와 이번 실패 지점

정상 경로

MeetVideo.onEnded
→ GuestLayoutContent.handleVideoEnd
→ session.notifyVideoEnd()
→ socket.emit("guest-video-end")
→ autoTransitionEnabled=true이면 session.goToNextStep()
→ guest-step-update
→ ppi-socket broadcast
→ 진행자/monitor 화면 동기화

확인한 파일/라인

파일라인의미
apps/web/shared/ui/meet-video.tsx232-240video native ended가 들어와야 props.onEnd?.() 호출.
apps/web/shared/ui/guest-layout-content.tsx113-118onEnd 수신 시 notifyVideoEnd()goToNextStep() 실행.
apps/web/entities/guest-socket/model/use-guest-socket.ts398-400socket.emit("guest-video-end", { roomId }).
apps/web/entities/guest-page-session/model/use-guest-page-session.ts1078-1108다음 step 계산 및 state 변경.
apps/socket/src/sfu-socket/handlers/session-handlers.ts207-247guest-step-update 수신 후 host/monitor로 broadcast.
apps/web/entities/host-socket/model/use-host-socket.ts115-132, 234-242진행자/monitor가 guest step update를 반영.
이번 Grafana 결과에서 guest-video-end가 0건이므로, 서버가 종료 이벤트를 받아놓고 유실한 문제가 아니다. 실패 지점은 아동 클라이언트의 영상 종료 감지 또는 notifyVideoEnd/goToNextStep 호출 이전이다.

5. 최종 재현 경로

전제 조건

  1. autoTransitionEnabled: true인 수업.
  2. 아동 화면이 full:video 또는 resource:video_* step에 진입.
  3. 영상 시작 시 Guest video play started는 서버에 도달.
  4. 영상 종료 시 guest-video-end가 발생하지 않음.
  5. 진행자가 자동 전환을 기다리다 수동으로 step을 넘김.

재현 단계

  1. 진행자가 monitor-dashboard에서 대상 수업을 시작한다.
  2. 아동이 /guest에서 입장 후 /client-guest/session으로 진입한다.
  3. 아동이 “시작”을 눌러 영상 step을 재생한다.
  4. Grafana ppi-socket-prodGuest video play started가 찍히는지 확인한다.
  5. 영상 종료 예상 시간이 지나도 guest-video-end가 0건이면 실패 상태다.
  6. 진행자가 수동으로 넘기면 Host changed step가 찍히고 직후 Guest step update가 따라온다.
이번 케이스의 재현 판정: 위 조건이 실제 로그로 충족됐다. 영상 시작 9건, 영상 종료 0건, 진행자 수동 전환 2건.

6. 반증 루프

가설검증 결과판정
SFU가 guest-video-end를 받았지만 host/monitor로 전달 실패 roomId 기준 guest-video-end 자체가 0건. 기각
진행자/monitor가 guest-step-update를 못 받아서 화면만 안 바뀜 실패 구간의 전환은 Host changed step가 먼저이고, 직후 Guest step update가 따라옴. 기각
아동 클라이언트에서 video 종료 감지/onEnd 경로가 미호출 영상 시작은 서버 도달, 종료 이벤트는 서버 미도달, 진행자가 수동 전환. 유지
수업 종료 부근 disconnect가 원인 disconnect는 11:55:49Z 이후 cleanup. 첫 수동 전환 11:32:41Z, 두 번째 11:46:51Z와 시간상 직접 원인 아님. 기각

7. 추가 확인/개선 포인트