크라우니텔 실시간 SSE 사이드카 (마스터플랜 W2 §②)
개요
crowny-tele 프로덕션화 마스터플랜(
docs/프로덕션화-마스터플랜.md) §② 실시간 수신 담당.
텔레서버.한선·
mobile-app.html은 병렬 다른 에이전트 소유라 절대 미접촉 —
신규
sidecar/ 디렉토리만 단독 작업.
무엇을 했는지
sidecar/tele-realtime.js (Node, 외부 npm 의존성 0 — 순수 http+fs+path+url):
- 포트 9620(env
TELE_RT_PORT로 오버라이드 가능) listen.
-
GET /rt/sub?token= —
http://127.0.0.1:9619/api/auth/verify?token=로 검증 →
실패 401, 성공 시 SSE 헤더(
text/event-stream·
no-cache·
keep-alive·
X-Accel-Buffering:no) 오픈 + userId로 등록(Map<userId,Set<res>>, 다기기
대비) + 25초 하트비트(
: ping).
-
POST /rt/presence {token,room,typing} — 검증 후 방 멤버(본인 제외)에
event:presence push. 404(방없음)/403(비멤버) 가드.
-
data/notify.log tail — 기동시점 오프셋부터,
fs.watch(data 디렉토리) +
1초 폴 백업(watch 유실 대비, 파일크기 비교)으로 신규 줄만 읽어
<epoch>|<room>|<kind>|<seq> 파싱 → 방.psv 멤버(5초 TTL 캐시) 중 접속
세션에
event:bump\ndata:{room,seq} push. truncate(자정 컴팩션) 감지 시
오프셋 0으로 리셋.
-
GET /rt/health 진단(클라이언트 수·notify 오프셋·방캐시 크기).
- 연결종료 시 클라이언트맵 정리, 전 구간 try/catch로 방어.
sidecar/tele-realtime.한선 — 동반 한선씨 로직 시뮬레이션(한선씨 우선 원칙).
실제 소켓 hold/fs.watch는 플랫폼락(Node 동시성)이라 구현 불가하지만,
"누구에게 보낼지 결정하는" 순수 판단 로직(알림줄파싱·방줄멤버파싱·
방멤버조회·팬아웃대상목록·프레즌스대상목록)은 한선씨로 명세 + 셀프테스트
4종 작성.
hanseonc_high로 컴파일·실행 확인(4/4 PASS).
sidecar/package.json — name/main/start스크립트, dependencies 빈 객체.
검증
node --check sidecar/tele-realtime.js → PASS.
hanseonc_high tele-realtime.한선 → crownyc run → PASS 4/4 (알림줄파싱·
방멤버조회·팬아웃대상목록·프레즌스대상목록).
- 포트 충돌 발견: 마스터플랜 지정 9620이 이미
canvas.crowny.org
(crownyc pid 38601, 라이브 프로덕션)가 점유 중. 해당 프로세스는 무접촉,
로컬검증은 격리 스크래치 루트(
TELE_ROOT)+임시포트(9703/9704)로 수행.
라이브 9619(dev role) 대상 실사용자 흐름으로 검증(추가만, 파괴적 조작 없음):
sidecarverify<rand> 신규 계정 signup+login으로 토큰 발급(tester1 비번
불명, 새 계정으로 대체 — 부작용 없음).
/api/room/dm으로 tester1과 실제 DM방 생성 → 방.psv에 정상 append 확인.
curl -N /rt/sub?token=<유효토큰> → : connected 수신, 잘못된 토큰 →
401 확인.
notify.log는 서버 에이전트 배선 전이라 실 데이터 디렉토리에 없음(정직
보고) → 격리 스크래치에 방.psv 복사 + notify.log 수동 append로 파이프라인
엔드투엔드 재현: append→
~1초 내 event: bump\ndata:{room,seq} 수신 확인.
presence: 정상멤버 200(notified:0, tester1 미접속이라 0명 정상)·
bad token 401·비멤버방 403·존재안하는방 404 전부 확인.
종료: lsof -ti:9703/9704 | xargs kill(pkill 미사용). canvas(9620)·
tele서버(9619) 무손상 재확인.
관련 파일
- /Users/ef/crowny-tele/sidecar/tele-realtime.js
- /Users/ef/crowny-tele/sidecar/tele-realtime.한선
- /Users/ef/crowny-tele/sidecar/package.json
잔여 이슈 / 리스크
- P0 아님이지만 시급: 게이트웨이 배선 전에 포트 9620 충돌을 오케스트레이터가
해결해야 함(canvas.crowny.org가 선점 중) —
crowny-ports.sh로 tele-realtime을
다른 포트(예 9703대 여유분)로 재배정하거나 canvas를 이동, 마스터플랜 문서·
게이트웨이 라우팅(
tele.crowny.org/rt/* → 127.0.0.1:9620) 동시 수정 필요.
실시간프로토콜.한선(notify.log SSOT+_notify 헬퍼 3곳 삽입)은 서버
에이전트 담당 — 아직 텔레서버.한선에 배선 안 됨. 배선 후 실 notify.log로
재검증 필요(이번엔 격리 스크래치 재현으로 대체 확증).
- 라이브 상주화(LaunchAgent)·게이트웨이
/rt/* 라우팅은 오케스트레이터 담당(범위 밖).
- 클라이언트측
mobile-app.html의 startRealtime()(EventSource 구독+폴백
강등)은 클라 에이전트 담당 — 미접촉.