콘텐츠로 이동

연결과 인증

클라이언트는 /sohri로 WebSocket 핸드셰이크를 수행합니다. credential은 다음 순서로 찾습니다.

  1. Authorization: Bearer <credential>
  2. Sec-WebSocket-Protocol: sohri.apikey, <api-key> 또는 sohri.token, <token>
  3. ?api_key=<credential> 또는 ?token=<credential>

형식이 sr_live_/sr_test_이면 workspace API key, JWT 형태이면 app-backend가 발급한 Ed25519 세션 에페메랄 토큰으로 분기합니다. API key는 workspace, key ID, key type을 스탬핑하고, 토큰은 aud=sohri-realtime, iss=sohri-app-backend, exp, sub, workspaceId를 검증해 workspace와 member ID를 스탬핑합니다.

인증 모드

app.auth.mode credential 없음 유효 credential 무효 credential
disabled 통과 검증 없이 통과 검증 없이 통과
permissive 미귀속으로 통과 검증·귀속 거절
enforced 401 검증·귀속 거절

API key 미존재·폐기·IP 불일치는 403입니다. 토큰의 형식 오류·만료·공개키 미설정은 401, 서명 또는 필수 클레임 불일치는 403입니다. 브라우저 서브프로토콜 방식을 쓰면 서버가 marker를 에코해야 핸드셰이크가 성립합니다.

연결과 엔진 확정 순서

sequenceDiagram
    participant C as Client/Gateway
    participant A as Handshake Auth
    participant W as Connection Handler
    participant DB as PostgreSQL
    participant R as Engine Router
    participant O as OpenAI Realtime
    participant E as EPD

    C->>A: GET /sohri Upgrade + credential
    A->>A: 채널 추출 → 형식 분기 → 검증
    alt 인증 거절
        A-->>C: HTTP 401 또는 403
    else 인증 승인
        A->>W: workspace/member/apiKey attributes
        W->>W: IP rate limit · 세션 상한 등록
        W->>DB: dialog 생성(started_at)
        DB-->>W: dialogId
        W-->>C: connection_established
    end

    opt PCM보다 먼저 명시 선택
        C->>R: conversation_session_update(engine)
        alt engine = openai_realtime
            R->>O: upstream 연결 + session.update
            O-->>R: session.updated
        else engine = sohri
            R->>R: SOHRI 선택 기록
        end
        R-->>C: conversation_session_updated
    end

    alt 명시 선택 없이 첫 PCM 도착
        C->>R: Binary PCM
        R->>R: SOHRI를 원자적으로 선택·잠금
        R->>E: 첫 PCM에서 EPD 지연 연결 후 전송
    else 선택 후 PCM 도착
        C->>R: Binary PCM
        R->>R: 선택된 엔진으로 전달
    end

    C->>R: 다른 엔진으로 재설정
    R-->>C: 409 CONVERSATION_ENGINE_INVALID

엔진은 첫 conversation_session_update 또는 첫 PCM으로 잠깁니다. 같은 OpenAI 엔진으로 다시 설정하면 사용자 컨텍스트와 instructions를 session.update로 갱신할 수 있지만, 다른 엔진으로 바꿀 수는 없습니다. 최초 OpenAI 설정이 실패하면 선택 기록을 제거하므로 유효한 설정으로 다시 시도할 수 있습니다.

연결 ACK는 엔진 준비 ACK가 아닙니다

connection_established는 WebSocket 세션과 대화 행이 준비됐다는 뜻입니다. OpenAI Realtime 준비 완료는 별도의 conversation_session_updated로 확인해야 합니다.

연결 쿼리

연결 시 EPD(minSpeech, endSilence, epdTimeout), 연속 입력(continuousAudio), TTS 출력 샘플레이트(ttsSampleRate), TTS 스트리밍(ttsStream=v1)을 협상할 수 있습니다. 세부 값은 설정 참조를 참고하세요.