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)로 메시지 전달 보장.
실제 사용 시 장단점
| 구분 | SSE | WebSocket |
|---|
| 방향 | 서버 → 클라이언트 (단방향) | 양방향 |
| 프로토콜 | HTTP/1.1, HTTP/2 호환 | ws/wss (HTTP 업그레이드) |
| 브라우저 지원 | 대부분 브라우저 지원 | 대부분 지원 |
| 구현 난이도 | 매우 단순(EventSource) | 세션/상태 관리 필요 |
| 네트워크 친화성 | 프록시/로드밸런서 친화 | 일부 방화벽에서 차단 가능 |
| 사례 | GPT 텍스트 스트리밍, 알림 | 채팅, 협업툴, 게임, 음성 |
추가로 롱폴링(Long Polling)이란?
- 기본 원리: 클라이언트가 서버에 HTTP 요청을 보낸 뒤, 서버가 새로운 데이터가 생길 때까지 응답을 지연시킵니다.
- 데이터가 생기면 응답 → 클라이언트는 즉시 새 요청을 다시 보냄.
- 즉, 계속 요청-응답을 반복하면서 “실시간”처럼 보이게 만드는 방식.
- 전통적인 AJAX 기반 서비스(채팅, 알림)에서 많이 사용되던 기법.
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 → 메시지 큐로 완충.