제6장: Phase 3 - 스트리밍 프로토콜

"실시간 감정 분석은 라이브 상호작용, 화상 회의, 게임, 운전자 모니터링 등에서 필수적입니다. Phase 3는 지연 시간을 최소화하고 연속적인 감정 데이터 스트림을 제공하는 WebSocket 프로토콜을 정의합니다."


6.1 실시간 WebSocket 프로토콜

6.1.1 연결 설정

# WebSocket 연결 URL
wss://stream.{provider}.com/wia/emotion/v1/stream

# 연결 요청 예시
GET /wia/emotion/v1/stream HTTP/1.1
Host: stream.provider.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Authorization: Bearer {access_token}
X-WIA-Version: 1.0.0

6.1.2 핸드셰이크 프로세스

단계 방향 메시지
1 클라이언트 → 서버 WebSocket 업그레이드 요청
2 서버 → 클라이언트 101 Switching Protocols
3 클라이언트 → 서버 세션 초기화 (session.start)
4 서버 → 클라이언트 세션 확인 (session.started)
5 양방향 데이터 스트리밍 시작

6.1.3 세션 초기화

// 클라이언트 → 서버: 세션 시작
{
    "type": "session.start",
    "session_id": "client-generated-uuid",
    "timestamp": "2025-01-15T14:30:00.000Z",
    "config": {
        "modalities": ["facial", "voice"],
        "facial_config": {
            "frame_rate": 15,
            "detect_action_units": true,
            "detect_micro_expressions": true,
            "resolution": "640x480"
        },
        "voice_config": {
            "sample_rate": 16000,
            "encoding": "LINEAR16",
            "language": "ko-KR"
        },
        "output_config": {
            "include_dimensional": true,
            "include_raw_scores": false,
            "confidence_threshold": 0.5,
            "emit_interval_ms": 100
        }
    }
}
// 서버 → 클라이언트: 세션 확인
{
    "type": "session.started",
    "session_id": "server-assigned-session-id",
    "timestamp": "2025-01-15T14:30:00.050Z",
    "config_applied": {
        "modalities": ["facial", "voice"],
        "max_frame_rate": 15,
        "session_timeout_seconds": 3600
    },
    "server_info": {
        "version": "1.0.0",
        "region": "ap-northeast-2"
    }
}

6.2 이벤트 기반 스트리밍

6.2.1 메시지 타입

타입 방향 설명
session.start C → S 세션 초기화 요청
session.started S → C 세션 초기화 확인
data.frame C → S 비디오/오디오 프레임 전송
emotion.event S → C 감정 분석 결과
emotion.aggregate S → C 집계된 감정 요약
heartbeat.ping 양방향 연결 유지 핑
heartbeat.pong 양방향 핑 응답
session.end C → S 세션 종료 요청
session.ended S → C 세션 종료 확인
error S → C 오류 알림

6.2.2 데이터 프레임 전송

// 비디오 프레임 전송
{
    "type": "data.frame",
    "modality": "facial",
    "timestamp": "2025-01-15T14:30:01.000Z",
    "sequence": 150,
    "data": {
        "frame": "{base64_encoded_frame}",
        "format": "jpeg",
        "resolution": "640x480"
    }
}

// 오디오 청크 전송
{
    "type": "data.frame",
    "modality": "voice",
    "timestamp": "2025-01-15T14:30:01.000Z",
    "sequence": 450,
    "data": {
        "audio": "{base64_encoded_audio_chunk}",
        "encoding": "LINEAR16",
        "duration_ms": 100
    }
}

6.2.3 감정 이벤트 수신

// 서버 → 클라이언트: 감정 이벤트
{
    "type": "emotion.event",
    "event_id": "evt-12345-abcde",
    "timestamp": "2025-01-15T14:30:01.100Z",
    "sequence": 150,
    "latency_ms": 85,
    "emotions": [
        {
            "category": "happiness",
            "intensity": 0.78,
            "confidence": 0.91
        }
    ],
    "action_units": [
        {
            "au": "AU6",
            "intensity": 0.72,
            "confidence": 0.89
        },
        {
            "au": "AU12",
            "intensity": 0.81,
            "confidence": 0.93
        }
    ],
    "dimensional": {
        "valence": 0.72,
        "arousal": 0.55
    },
    "source_modality": "facial",
    "face_detected": true,
    "micro_expression": false
}

6.2.4 집계 이벤트

// 서버 → 클라이언트: 주기적 집계 (매 5초)
{
    "type": "emotion.aggregate",
    "timestamp": "2025-01-15T14:30:05.000Z",
    "window_start": "2025-01-15T14:30:00.000Z",
    "window_end": "2025-01-15T14:30:05.000Z",
    "frame_count": 75,
    "aggregate": {
        "dominant_emotion": "happiness",
        "emotion_distribution": {
            "happiness": 0.65,
            "neutral": 0.25,
            "surprise": 0.10
        },
        "average_valence": 0.68,
        "average_arousal": 0.52,
        "emotional_stability": 0.85,
        "engagement_score": 0.72
    },
    "modality_quality": {
        "facial": {
            "average_confidence": 0.88,
            "frames_processed": 75,
            "frames_dropped": 0
        },
        "voice": {
            "average_confidence": 0.82,
            "segments_processed": 50
        }
    }
}

6.3 프레임 레이트 및 지연시간 요구사항

6.3.1 프레임 레이트 권장사항

모달리티 최소 권장 최대
표정 분석 5 fps 15 fps 30 fps
미세표정 25 fps 30 fps 60 fps
음성 분석 100ms 청크 100ms 청크 50ms 청크

6.3.2 지연시간 요구사항

사용 사례 최대 지연시간 목표 지연시간
실시간 화상 통화 200ms 100ms
게임/인터랙션 100ms 50ms
운전자 모니터링 150ms 75ms
고객 서비스 500ms 250ms
녹화 분석 N/A 실시간 아님

6.3.3 품질 vs 지연시간 트레이드오프

// 저지연 모드 설정
{
    "type": "session.start",
    "config": {
        "mode": "low_latency",
        "facial_config": {
            "frame_rate": 15,
            "detect_action_units": false,
            "detect_micro_expressions": false,
            "lightweight_model": true
        },
        "output_config": {
            "include_dimensional": true,
            "include_raw_scores": false,
            "emit_interval_ms": 50
        }
    }
}

// 고품질 모드 설정
{
    "type": "session.start",
    "config": {
        "mode": "high_quality",
        "facial_config": {
            "frame_rate": 30,
            "detect_action_units": true,
            "detect_micro_expressions": true,
            "high_precision_model": true
        },
        "output_config": {
            "include_dimensional": true,
            "include_raw_scores": true,
            "emit_interval_ms": 200
        }
    }
}

6.4 보안 및 인증

6.4.1 연결 보안

요구사항 사양
전송 암호화 TLS 1.3 필수 (최소 TLS 1.2)
WebSocket 보안 wss:// 프로토콜만 허용
인증서 신뢰할 수 있는 CA 발급 필수
암호화 스위트 AES-256-GCM, CHACHA20-POLY1305

6.4.2 인증 토큰

// JWT 토큰 구조
{
    "header": {
        "alg": "RS256",
        "typ": "JWT"
    },
    "payload": {
        "sub": "user-12345",
        "iss": "https://auth.provider.com",
        "aud": "wia-emotion-stream",
        "iat": 1705329000,
        "exp": 1705332600,
        "scope": ["stream:read", "stream:write"],
        "session_limit": 5,
        "rate_limit": {
            "frames_per_second": 30,
            "max_concurrent_sessions": 3
        }
    },
    "signature": "..."
}

6.4.3 세션 보안

// 보안 세션 설정
{
    "type": "session.start",
    "security": {
        "encryption": {
            "enable_payload_encryption": true,
            "algorithm": "AES-256-GCM"
        },
        "consent": {
            "user_consent_token": "{signed_consent_token}",
            "consent_scope": ["emotion_analysis", "data_storage"],
            "consent_timestamp": "2025-01-15T14:25:00.000Z"
        },
        "data_handling": {
            "store_raw_data": false,
            "anonymize_results": true,
            "retention_period": "session_only"
        }
    }
}

6.5 오류 처리

6.5.1 오류 메시지 형식

{
    "type": "error",
    "error_code": "PROCESSING_FAILED",
    "message": "프레임 처리에 실패했습니다",
    "timestamp": "2025-01-15T14:30:05.000Z",
    "details": {
        "sequence": 155,
        "modality": "facial",
        "reason": "face_not_detected"
    },
    "severity": "warning",
    "recoverable": true,
    "action": "skip_frame"
}

6.5.2 오류 코드

오류 코드 심각도 설명 조치
AUTH_EXPIRED critical 인증 토큰 만료 재인증 필요
SESSION_TIMEOUT critical 세션 시간 초과 세션 재시작
RATE_LIMITED warning 속도 제한 초과 프레임 레이트 감소
PROCESSING_FAILED warning 프레임 처리 실패 프레임 건너뛰기
MODALITY_UNAVAILABLE warning 모달리티 일시 불가 다른 모달리티 사용
QUALITY_LOW info 입력 품질 낮음 품질 개선 권장
SERVER_OVERLOAD critical 서버 과부하 재연결 대기

6.5.3 재연결 프로토콜

// 재연결 로직
{
    "reconnection_policy": {
        "max_attempts": 5,
        "backoff_strategy": "exponential",
        "initial_delay_ms": 1000,
        "max_delay_ms": 30000,
        "backoff_multiplier": 2.0,
        "jitter": 0.1
    },
    "session_resumption": {
        "enabled": true,
        "resume_token": "{session_resume_token}",
        "resume_from_sequence": 155,
        "max_gap_seconds": 30
    }
}

6.6 연결 관리

6.6.1 하트비트

// 클라이언트 → 서버: 핑
{
    "type": "heartbeat.ping",
    "timestamp": "2025-01-15T14:30:30.000Z",
    "client_sequence": 500
}

// 서버 → 클라이언트: 퐁
{
    "type": "heartbeat.pong",
    "timestamp": "2025-01-15T14:30:30.050Z",
    "client_sequence": 500,
    "server_sequence": 495,
    "latency_ms": 50
}

6.6.2 세션 종료

// 클라이언트 → 서버: 세션 종료 요청
{
    "type": "session.end",
    "timestamp": "2025-01-15T15:00:00.000Z",
    "reason": "user_initiated",
    "request_summary": true
}

// 서버 → 클라이언트: 세션 종료 확인
{
    "type": "session.ended",
    "session_id": "session-12345",
    "timestamp": "2025-01-15T15:00:00.100Z",
    "duration_seconds": 1800,
    "summary": {
        "total_frames_processed": 27000,
        "total_events_emitted": 18000,
        "dominant_emotion": "neutral",
        "average_engagement": 0.68,
        "average_valence": 0.35
    }
}

6.6.3 연결 상태

상태 설명
connecting WebSocket 연결 시도 중
authenticating 인증 진행 중
initializing 세션 초기화 중
streaming 데이터 스트리밍 활성
paused 스트리밍 일시 중지
reconnecting 재연결 시도 중
closing 세션 종료 중
closed 연결 종료됨

6.7 요약

Phase 3는 실시간 감정 분석을 위한 WebSocket 스트리밍 프로토콜을 정의합니다:

홍익인간 (弘益人間): 널리 인간을 이롭게 하라

실시간 감정 분석은 교육, 헬스케어, 안전 등 다양한 분야에서 사람들을 도울 수 있습니다.


← 이전: 제5장 - Phase 2: API 인터페이스 | 다음: 제7장 - Phase 4: 통합 →