본문으로 건너뛰기
김신건의 로그

[Network] Realtime 전송 비교: Polling / SSE / WebSocket / WebRTC

· 수정 · 📖 약 3분 · 981자/단어 #realtime #network #websocket #sse #polling #webrtc #backend
realtime comparison, long polling, polling, SSE vs WebSocket, WebRTC DataChannel, push notification

정의

실시간 (서버 → 클라이언트) 데이터 전송 의 7가지 패턴 비교.

결정 트리

flowchart TD
    Q1{양방향 필요?}
    Q1 -->|아니오| Q2{영속 연결 OK?}
    Q1 -->|예| Q3{브라우저 / 네이티브?}
    Q2 -->|예| SSE[SSE]
    Q2 -->|아니오| Q4{레거시 호환?}
    Q4 -->|예| LP[Long Polling]
    Q4 -->|아니오| Poll[Polling]
    Q3 -->|브라우저| WS[WebSocket]
    Q3 -->|P2P 미디어| RTC[WebRTC]

7가지 비교

패턴방향영속프로토콜사용
Short PollingC → S짧음HTTP단순 / legacy
Long PollingC → S짧음 (hold)HTTPlegacy fallback
HTTP/2 server pushS → C(폐기)HTTP/2(deprecated)
SSES → C영속HTTP알림, 라이브 피드
WebSocket양방향영속RFC 6455채팅, 게임
WebTransport양방향 (datagrams)영속HTTP/3 + QUIC차세대 (실험적)
WebRTC DataChannel양방향 (P2P)영속DTLS + SCTP게임 P2P, 파일

Polling

sequenceDiagram
    loop 5초마다
        C->>S: GET /new
        S-->>C: 200 [] (변화 없음)
    end
    Note over C,S: 5초 후
    C->>S: GET /new
    S-->>C: 200 [msg1]
  • 가장 단순. 가장 비효율적.
  • 평균 지연 = polling 간격 / 2.
  • 메시지 없어도 매 요청 발생 → 서버 부담.

CAUTION

자주 polling = 서버 부담. 드물게 polling = 지연 큼. 둘 다 안 좋음.

Long Polling

sequenceDiagram
    C->>S: GET /new (대기 30s)
    Note over S: 이벤트 없음, hold
    Note over S: 메시지 도착!
    S-->>C: 200 [msg1]
    C->>S: GET /new (즉시 다음 요청)
    Note over S: timeout 30s
    S-->>C: 200 [] (timeout)
    C->>S: GET /new (재시도)
  • 적은 빈도, 낮은 지연.
  • legacy 환경 (옛 IE, 일부 프록시) 의 fallback.
  • connection 점유 가 polling 보다 길다 → 서버 connection pool 압박.

SSE (단방향 영속)

자세한 건 SSE 참고.

sequenceDiagram
    C->>S: GET /stream
    S-->>C: 200 (영속)
    S-->>C: data: msg1\n\n
    S-->>C: data: msg2\n\n
    Note over C: 끊김 시 자동 재연결
    S-->>C: data: msg3\n\n
  • 서버 → 클라이언트 일방향 충분하면 제일 단순.
  • 자동 재연결 + Last-Event-ID 재개.
  • 프록시 / 방화벽 친화 (HTTP).

WebSocket (양방향 영속)

자세한 건 WebSocket 참고.

sequenceDiagram
    C->>S: HTTP Upgrade (handshake)
    S-->>C: 101 Switching Protocols
    C-->>S: WS frame
    S-->>C: WS frame
  • 양방향 + 영속. 채팅 / 게임 / 협업 / 트레이딩.
  • HTTP 위에서 시작하지만 별도 프레임 프로토콜.

WebTransport (실험적, 차세대)

HTTP/3 (QUIC) 위 양방향 + unreliable datagram + bidirectional streams. WebSocket + UDP datagram 의 결합.

  • 2026 시점 모던 브라우저 지원 진입.
  • 게임 + 라이브 영상 + AR/VR.
  • 아직 대중적 도입 전.

WebRTC DataChannel (P2P)

  • 클라이언트 클라이언트 직접. 서버는 signaling 만.
  • DTLS + SCTP 위.
  • P2P 게임, 파일 전송, 영상통화 보조.
  • NAT traversal (STUN/TURN) 복잡도.

처리량 vs 지연 vs 복잡도

실시간 패턴: 처리량 vs 지연 (가상 직관)
WebSocket / WebTransport 가 처리량+지연 모두 우수. SSE 는 단방향이지만 그만큼 단순.

WebRTC 시그널링: STUN / TURN

P2P 연결 수립을 위한 시그널링 서버 + NAT traversal.

sequenceDiagram
    participant A as Client A
    participant Sig as Signaling Server
    participant ST as STUN/TURN
    participant B as Client B
    A->>Sig: SDP Offer
    Sig->>B: SDP Offer
    B->>Sig: SDP Answer
    Sig->>A: SDP Answer
    A->>ST: STUN Binding Request
    ST-->>A: Public IP:Port
    B->>ST: STUN Binding Request
    ST-->>B: Public IP:Port
    A-->>B: ICE Candidates 교환
    Note over A,B: P2P 연결 수립
컴포넌트역할
STUN공인 IP:Port 탐색 (cheap, UDP)
TURNNAT 뒤 relay (expensive, 모든 트래픽 경유)
ICESTUN + TURN 조합으로 최적 경로 탐색
SDP미디어 능력 / 코덱 협상

CAUTION

TURN 서버 없으면 Symmetric NAT (기업 방화벽) 뒤 클라이언트 연결 불가. 실서비스는 TURN 필수. TURN 비용 = 전체 트래픽 relay.

스케일링 전략

각 패턴별 서버 사이드 스케일링 고려사항:

flowchart TD
    LB[L7 Load Balancer]
    LB -->|"SSE / WebSocket"| Sticky["Sticky Session 필요"]
    LB -->|"Polling"| Stateless["완전 Stateless 분산"]
    Sticky --> Redis["Redis Pub/Sub<br/>노드 간 메시지 팬아웃"]
    Redis --> N1[Node 1]
    Redis --> N2[Node 2]
    Redis --> N3[Node 3]
패턴스케일링 방식핵심 도구
PollingStateless, 그냥 확장없음
Long PollingConnection 수 관리Nginx keep-alive 튜닝
SSESticky session + 팬아웃Redis Pub/Sub
WebSocketSticky session + 팬아웃Redis Pub/Sub, Socket.IO
WebRTC시그널링 서버 분리STUN/TURN 별도

자세히는 redis-pubsub-vs-streams, sticky-session.

구현 패턴 비교

기술Node.js 서버브라우저 클라이언트
SSEres.write('data: ...\n\n')new EventSource('/stream')
WebSocketws, socket.io, uWebSockets.jsnew WebSocket('wss://...')
Long Polling일반 HTTP, timeout 30sfetch + 재시도 루프
WebRTCnode-webrtc, MediasoupRTCPeerConnection API

SSE 연결 한계: HTTP/1.1 = 브라우저당 도메인 6 연결 제한. HTTP/2 에서는 다중 SSE 가능.

브라우저 지원 & 제약

기능ChromeFirefoxSafariIE/Edge legacy
SSE지원지원지원SSE 없음
WebSocket지원지원지원IE11 지원
WebRTC지원지원지원 (iOS 제한)미지원
WebTransport지원 (실험)지원 (실험)미지원미지원

NOTE

iOS Safari 는 SSE 응답 버퍼링 문제 가 있음 (iOS 14 이전). text/event-stream + 작은 청크 크기로 완화. iOS WebRTC 는 Audio 백그라운드 제한 있음.

흔한 함정

WARNING

  1. SSE + nginx 버퍼링 = 기본 response buffering 으로 메시지 지연. X-Accel-Buffering: no + proxy_buffering off 필수.
  2. WebSocket + ALB 60s idle timeout = heartbeat ping/pong 으로 연결 유지.
  3. WebRTC + CORS = 시그널링 서버 CORS 설정 + TURN 서버 credential 보호.
  4. Long Polling 서버 연결 수 = 클라이언트 N명 = 서버 N개 연결 점유. non-blocking I/O (Node.js, async Python) 필수.
  5. SSE 재연결 폭풍 = 서버 재시작 시 모든 클라이언트 동시 재연결. Last-Event-ID + jitter 로 분산.

관련 위키

이 글의 용어 (6개)
[Django] Channels: WebSocket, Consumer, Groupdjango
정의 Django Channels는 Django에 WebSocket, 비동기 프로토콜, 백그라운드 작업을 추가하는 공식 확장. 기본 Django는 HTTP만, Channels는 …
[Network] HTTP/2: multiplexing, HPACK, server push의 종말network
정의 HTTP/2 (2015, RFC 9113) 는 HTTP/1.1 의 문법은 유지하되 전송을 바이너리 + 멀티플렉싱 으로 바꾼다. Head-of-Line Blocking (HT…
[Network] HTTP/3: QUIC 위의 HTTP, 0-RTT, connection migrationnetwork
정의 HTTP/3 (2022, RFC 9114)는 HTTP의 전송 레이어를 TCP 에서 QUIC 으로 교체한 버전이다. UDP 위에 QUIC, QUIC 위에 HTTP 구조다. 핵…
[Redis] Pub/Sub vs Streams: 휘발 신호 vs 영속 로그database-internals
정의 - Pub/Sub ( / ): 지금 듣고 있는 구독자 에게만 메시지가 전달되는 휘발성 신호. 영속 없음, ACK 없음. fan-out. - Streams ( / / / ):…
SIMDalgorithm
정의 SIMD (Single Instruction Multiple Data) 는 한 명령어로 여러 데이터 를 병렬 처리하는 CPU 기능. x86 의 SSE / AVX / AVX2…
Sticky Sessionconcurrency
정의 Sticky Session (= Session Affinity)은 로드밸런서가 같은 클라이언트의 요청을 항상 같은 백엔드 서버로 라우팅하도록 하는 동작이다. 서버, 즉 세션…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기