1. 3개 핵심 컴포넌트 분석

LiveKit은 WebRTC 기반의 SFU(Selective Forwarding Unit) 플랫폼으로, WebRTC 위에 룸 모델, 권한 관리, 확장 기능을 제공합니다. 순수 WebRTC P2P와 달리, 각 클라이언트가 SFU로 한 번만 업로드하고 SFU가 다른 참가자에게 선택적으로 전달하는 구조입니다.

1.1 Frontend (React + LiveKit Client SDK)

역할: 사용자 인터페이스 및 WebRTC 클라이언트###

주요 기능:

  • 🎥 미디어 캡처: getUserMedia(), getDisplayMedia()
  • 🔗 LiveKit 연결: JWT 토큰으로 룸 참가
  • 📺 미디어 렌더링: 원격 참가자 비디오/오디오 재생
  • 💬 실시간 채팅: DataChannel 기반 메시징

핵심 파일 예시:

// LiveKitRoomService.ts
await this.room.connect(serverUrl, token);
 
// TokenService.ts
const tokenResponse = await fetch('/api/token', { ... });

1.2 Backend (Node.js + LiveKit Server SDK)

역할: 인증 서버 및 API 제공

주요 기능:

  • 🎫 JWT 토큰 생성: 룸 접근 권한 제어
  • 🔐 사용자 인증: 참가자 신원 확인
  • 🤖 AI 에이전트 개발: 봇을 룸에 참가시키는 로직
  • 📊 서버 API: LiveKit 서버 관리

핵심 파일 예시:

// TokenController.ts
const token = new AccessToken(apiKey, apiSecret, {
  identity: participantName,
  ttl: '10m'
});

1.3 LiveKit Server (Self-hosted Docker or Cloud)

역할: WebRTC SFU 미디어 서버

주요 기능:

  • 🌐 WebRTC SFU: 선택적 스트림 포워딩
  • 🔀 미디어 라우팅: 참가자 간 실시간 미디어 전달
  • 🎛️ 품질 제어: Simulcast, adaptive bitrate
  • 🔌 ICE/STUN/TURN: NAT 통과 및 연결성 보장

💡 LiveKit 서버가 꼭 필요한 이유

“livekit-server-sdk만으로는 충분하지 않나요?”라는 질문을 자주 받습니다. 절대적으로 LiveKit 서버가 필요합니다!

  • livekit-server-sdk: JWT 토큰 생성, API 호출 등의 유틸리티 라이브러리
  • LiveKit 서버: WebRTC SFU 미디어 서버 (실제 통신 담당)
기능livekit-server-sdkLiveKit 서버
토큰 생성
WebRTC 연결
미디어 포워딩

LiveKit은 P2P가 아닌 SFU 방식이므로 중앙 미디어 서버가 반드시 필요합니다.

설정 파일 예시:

# livekit.yaml
rtc:
  node_ip: "127.0.0.1"  # localhost 강제 설정
  port_range_start: 7882
  port_range_end: 7892

2. WebRTC 구조와 LiveKit 매핑

2.1 WebRTC 핵심 구조 (기존 다이어그램)

flowchart LR
   Signaling server for SDP and ICE exchange
  SIG[Signaling server<br/>SDP and ICE exchange]

   Between PeerConnections
  PCA <-->|ICE connectivity checks| PCB
  PCA <-->|DTLS handshake| PCB

   Peer B mirrored, App at far right
  subgraph PeerB[Peer B]
    direction LR
    PCB[RTCPeerConnection B]
    AT_B[MediaStreamTrack<br/>audio]
    VT_B[MediaStreamTrack<br/>video]
    MSB[MediaStream]
    DCB[RTCDataChannel]
    AppB[App]

    PCB -->|ontrack| AT_B
    PCB -->|ontrack| VT_B
    AT_B --> MSB
    VT_B --> MSB
    MSB --> AppB

    PCB -->|ondatachannel| DCB
    DCB <-->|file send and onmessage| AppB
  end

2.2 LiveKit 3개 컴포넌트 매핑

WebRTC 구성 요소LiveKit 컴포넌트역할
Peer A AppFrontend (React)사용자 인터페이스, 미디어 제어
Signaling ServerBackend + LiveKit ServerSDP/ICE 교환, 토큰 인증
RTCPeerConnectionLiveKit Client SDKWebRTC 연결 추상화
Media RoutingLiveKit Server (SFU)미디어 선택적 포워딩

🔑 핵심 차이점:

  • 순수 WebRTC: Peer A ↔ Peer B (직접 P2P)
  • LiveKit: Frontend ↔ LiveKit Server ↔ Other Clients (SFU 중재)

3. 실제 통신 흐름

💡 JWT 토큰은 어떻게 전달되나요?

“Backend가 LiveKit 서버로 토큰을 중계하나요?”라는 질문을 받습니다. 아니요, Frontend가 직접 연결합니다!

❌ 잘못된 이해: Frontend → Backend → LiveKit (중계)
✅ 실제 흐름: Frontend → Backend (토큰 요청) → Frontend → LiveKit (직접 연결)

실제 통신 흐름:

  1. Frontend가 Backend에서 JWT 토큰만 받음
  2. Frontend가 해당 토큰으로 LiveKit 서버에 직접 연결
  3. 이후 모든 미디어 통신은 Frontend ↔ LiveKit 서버 직접 진행

3.1 전체 시퀀스 다이어그램

sequenceDiagram
    autonumber
    participant User as 👤 사용자
    participant Frontend as 🌐 Frontend<br/>(React)
    participant Backend as 🖥️ Backend<br/>(Node.js)
    participant LiveKit as 🎥 LiveKit Server<br/>(Docker/Cloud)
    participant Other as 👥 다른 참가자

    User->>Frontend: 룸 입장 요청
    Frontend->>Backend: JWT 토큰 요청<br/>POST /api/token
    Backend->>Backend: LiveKit Server SDK로<br/>JWT 토큰 생성
    Backend->>Frontend: JWT 토큰 응답
    Frontend->>LiveKit: 토큰과 함께<br/>WebSocket 연결
    LiveKit->>Frontend: 연결 성공 응답<br/>(Room 상태 정보)
    Frontend->>LiveKit: 로컬 미디어 트랙 전송<br/>(오디오/비디오)
    LiveKit->>Other: 미디어 스트림<br/>선택적 포워딩
    Other->>LiveKit: 원격 미디어 응답
    LiveKit->>Frontend: 다른 참가자<br/>미디어 수신
    Frontend->>User: 실시간 화상회의<br/>화면 표시

3.2 각 단계 상세 설명

  1. 사용자 룸 입장 요청: 웹 UI에서 방 이름과 참가자 이름 입력
  2. JWT 토큰 요청: Frontend가 Backend API에 인증 토큰 요청
  3. 토큰 생성: Backend가 LiveKit Server SDK로 JWT 생성 (권한 포함)
  4. 토큰 응답: 서명된 JWT를 Frontend에 반환
  5. LiveKit 연결: Frontend가 토큰을 사용해 LiveKit 서버에 직접 연결
  6. 연결 성공: WebSocket 연결 성립, 룸 상태 정보 수신
  7. 미디어 전송: 로컬 카메라/마이크를 LiveKit 서버로 업로드
  8. 미디어 포워딩: SFU가 다른 참가자들에게 선택적으로 전달
  9. 원격 미디어: 다른 참가자들의 미디어를 LiveKit에서 수신
  10. 화면 표시: 모든 참가자의 비디오를 웹 화면에 렌더링
  11. 실시간 통신: 지속적인 양방향 미디어 스트리밍

4. Self-hosted vs LiveKit Cloud 비교

💡 LiveKit Cloud는 Docker 없이도 사용 가능한가요?

네, 완전히 가능합니다! LiveKit Cloud 사용 시:

  • ✅ Docker 불필요 (livekit.yaml, docker-compose.yml 불필요)
  • ✅ 관리형 서비스로 자동 스케일링
  • ✅ 글로벌 저지연 네트워크

설정 변경만으로 전환 가능:

// 기존: Self-hosted
LIVEKIT_WS_URL=ws://localhost:7880
 
// 변경: LiveKit Cloud
LIVEKIT_WS_URL=wss://your-project.livekit.cloud

4.1 상세 비교표

항목Self-hostedLiveKit Cloud
💰 초기 비용무료 (완전 오픈소스)무료 티어: 1,000분/월
🔧 설정 복잡도Docker/K8s 설정 필요웹 콘솔에서 원클릭
⚡ 성능지역에 따라 다름Ultra-low latency 글로벌
🛠️ 커스터마이징완전 제어웹 UI 범위 내
🔒 데이터 주권완전 제어LiveKit 인프라
📊 모니터링별도 구성내장 대시보드

4.2 선택 가이드

Self-hosted 추천 상황:

  • 🔒 데이터 보안이 최우선 (금융, 의료)
  • 💰 예산 제한 + 기술 역량 보유
  • 🛠️ 완전한 커스터마이징 필요

LiveKit Cloud 추천 상황:

  • ⚡ 빠른 프로토타이핑 필요
  • 🌍 글로벌 서비스 제공
  • 👥 작은 개발팀 (운영 인력 부족)

5. AI 봇/에이전트 개발 가이드

💡 AI 봇이나 에이전트는 어디서 개발해야 하나요?

Backend (Node.js)에서 개발하시면 됩니다!

개발 위치: @backend/src/agents/AIBotAgent.ts

LiveKit 공식 문서: “Agents can be full participants using Node.js SDKs”

5.1 개발 구조

@backend/
├── src/
│   ├── agents/
│   │   ├── AIBotAgent.ts          ← AI 봇 로직
│   │   ├── GeminiLiveAgent.ts     ← Gemini 연동
│   │   └── VisionAgent.ts         ← 화면 분석
│   ├── services/
│   │   ├── STTService.ts          ← 음성→텍스트
│   │   ├── LLMService.ts          ← AI 응답 생성
│   │   └── TTSService.ts          ← 텍스트→음성
│   └── ...

5.2 AI 에이전트 참가 흐름

sequenceDiagram
    autonumber
    participant Backend as 🤖 Backend Agent
    participant LiveKit as 🎥 LiveKit Server
    participant User as 👤 사용자

    Backend->>Backend: AI 봇용 JWT 토큰 생성
    Backend->>LiveKit: 토큰으로 룸 참가
    LiveKit->>Backend: 연결 성공
    User->>LiveKit: 음성 메시지 전송
    LiveKit->>Backend: 음성 스트림 수신
    Backend->>Backend: STT → LLM → TTS 파이프라인
    Backend->>LiveKit: AI 응답 음성 전송
    LiveKit->>User: AI 응답 재생

5.3 핵심 구현 예시

// AIBotAgent.ts 예시
export class AIBotAgent {
  async joinRoom(roomName: string) {
    // 1. 봇용 토큰 생성
    const token = new AccessToken(apiKey, apiSecret, {
      identity: 'AI-Assistant',
      name: 'Gemini Bot'
    });
 
    // 2. 룸 참가
    const room = new Room();
    await room.connect(serverUrl, token);
 
    // 3. 이벤트 리스너 등록
    room.on(RoomEvent.TrackSubscribed, this.handleAudioTrack);
  }
 
  private async handleAudioTrack(track: RemoteAudioTrack) {
    // STT → LLM → TTS 파이프라인
    const text = await this.sttService.transcribe(track);
    const response = await this.llmService.generate(text);
    const audio = await this.ttsService.synthesize(response);
 
    // AI 응답 전송
    await this.publishAudio(audio);
  }
}

6. 참고 문서

6.1 WebRTC 공식

6.2 MDN Web APIs

6.3 LiveKit 공식

6.4 RFC 표준

6.5 GitHub 리포지토리