SSE VS WebSocket

Jinmin Kim·2025년 9월 2일

SSE (Server-Sent Events)

  • HTTP 기반 단방향 스트리밍
  • 클라이언트 → 서버는 일반 요청만, 서버 → 클라이언트로만 연속 이벤트 푸시.
  • 브라우저 표준 API: EventSource.
  • 텍스트 기반(Content-Type: text/event-stream), 자동 재연결 지원.
// 클라이언트
const es = new EventSource("/stream");
es.onmessage = (e) => console.log("data:", e.data);
es.onerror = () => console.log("error, will retry...");

WebSocket

  • TCP 기반 양방향 스트림.
  • 연결 수립 시 ws:// 또는 wss:// 프로토콜 업그레이드.
  • 서버/클라이언트가 자유롭게 메시지를 주고받을 수 있음.
  • 브라우저 표준 API: WebSocket.
// 클라이언트
const ws = new WebSocket("wss://example.com/ws");
ws.onopen = () => ws.send("hello server");
ws.onmessage = (e) => console.log("data:", e.data);

처리 로직 설계 패턴

SSE 처리 시

  • 서버에서 한 줄씩 data: ...\n\n 형식으로 전송.
  • 클라이언트는 onmessage로 수신 → 상태(Zustand) 누적.
  • 중단/취소: EventSource.close().
  • 재연결: 브라우저가 기본 지원하지만, 인증 토큰 만료 처리 필요.

WebSocket 처리 시

  • 연결 수립 후 양방향 이벤트 송수신.
  • 상태 관리: 연결 상태(OPEN/CLOSE) 추적, 메시지 큐/버퍼.
  • 클라이언트 종료: ws.close().
  • 서버 스케일링 시 브로커(Redis/Kafka)로 메시지 전달 보장.

실제 사용 시 장단점

구분SSEWebSocket
방향서버 → 클라이언트 (단방향)양방향
프로토콜HTTP/1.1, HTTP/2 호환ws/wss (HTTP 업그레이드)
브라우저 지원대부분 브라우저 지원대부분 지원
구현 난이도매우 단순(EventSource)세션/상태 관리 필요
네트워크 친화성프록시/로드밸런서 친화일부 방화벽에서 차단 가능
사례GPT 텍스트 스트리밍, 알림채팅, 협업툴, 게임, 음성

추가로 롱폴링(Long Polling)이란?

  • 기본 원리: 클라이언트가 서버에 HTTP 요청을 보낸 뒤, 서버가 새로운 데이터가 생길 때까지 응답을 지연시킵니다.
  • 데이터가 생기면 응답 → 클라이언트는 즉시 새 요청을 다시 보냄.
  • 즉, 계속 요청-응답을 반복하면서 “실시간”처럼 보이게 만드는 방식.
  • 전통적인 AJAX 기반 서비스(채팅, 알림)에서 많이 사용되던 기법.
// 예시 (pseudo-code)
function poll() {
  fetch("/updates").then(res => res.json()).then(data => {
    render(data);
    poll(); // 응답을 받은 즉시 다시 요청
  });
}
poll();

정리

롱폴링

  • 서버 리소스 많이 사용 (많은 커넥션 유지)
  • 응답 지연으로 “실시간”이 완벽히 보장되지 않음

SSE

  • 인증 헤더 미지원 (EventSource는 Authorization 헤더 불가)
    • 해결: JWT/세션 토큰을 쿼리파라미터, 쿠키, 혹은 fetchstream 대체.
  • 브라우저 연결 제한 (HTTP/1.1은 도메인당 6개)
    • 해결: HTTP/2 업그레이드, 연결 수 줄이기.

WebSocket

  • 상태 관리 복잡 (연결 유지, 클라이언트 식별, 메시지 ACK 필요)
  • 부하 분산 문제: 로드밸런서 환경에서 연결 유지 필요 → sticky session or 외부 pub/sub.
  • 메시지 폭주: 서버에 backpressure → 메시지 큐로 완충.
profile
Let's do it developer

0개의 댓글