SSE 의 개념

SSE 의 정의

  • 서버에서 클라이언트로 실시간 데이터를 단방향으로 지속적으로 보내는 기술
  • 연결이 이뤄지면 Client 의 별도 추가 요청 없어도 서버가 event를 전송(push) 한다.
  • HTTP 프로토콜을 사용한다.

SSE 의 사용 목적

  • 웹 브라우저에서 새로고침이나 조작 없이 실시간으로 데이터 업데이트, 알림 등을 구현할 때 사용

SSE 의 장점

장점 항목 설명
단순한 구현 - 웹소켓에 비해 서버 설정 및 코딩이 간단함
HTTP 기반 - 기존 HTTP 인프라(로드 밸런서, 프록시, 방화벽)와 호환성이 좋음
- 포트 설정이 별도로 필요 없음
자원 효율성 - 단방향 통신이므로 웹소켓보다 자원 소모가 적음
자동 재연결 - 브라우저의 EventSource 객체에 자동 재연결 기능이 내장되어 있음
명확한 의미론 - 단방향 통신 패턴으로 데이터 흐름이 직관적임
- 애플리케이션 로직이 단순함

SSE 의 단점

단점 항목 설명
단방향 통신 - 서버에서 클라이언트로만 데이터 전송 가능.
- 클라이언트 → 서버는 별도 HTTP 요청 필요
텍스트 기반 - 주로 텍스트 데이터만 지원.
- 바이너리 데이터는 인코딩(Base64 등) 필요
HTTP/1.1 연결 제한 - 브라우저당 호스트당 최대 연결 수 제한 있음 (보통 6개).

SSE 가 적용된 예시

  • ChatGPT와 같은 LLM의 스트리밍 응답
  • 실시간 뉴스 피드 및 소셜 업데이트
  • 주식 시세 및 금융 데이터
  • 진행 바 및 작업 모니터링 (예: 오래 걸리는 백엔드 작업 진행률)
  • 서버 로그 스트리밍 (본문의 파드 로그 예시)
  • 협업 편집 (업데이트 알림용)
  • 게임 리더보드
  • 위치 추적 시스템

단, ChatGPT의 API 응답은 text/event-stream 형식을 사용하지만, 순수한 SSE 구현과는 차이가 있으며, WebSocket 또는 HTTP chunked 전송과 혼용되는 경우도 있다~ 고 한다.

SSE 와 다른 통신의 비교

SSE

Short Polling

Long Polling

비교표

특성 SSE
(Server-Sent Events)
WebSocket Polling (Short/Long)
통신 방향 서버 → 클라이언트 (단방향) 클라이언트 ↔ 서버 (양방향) 클라이언트 요청 → 서버 응답
프로토콜 HTTP WS (WebSocket 프로토콜)
HTTP 핸드셰이크 후 업그레이드
HTTP
연결 유지 하나의 HTTP 연결 지속 (text/event-stream) 전용 TCP 연결
(전이중 통신)
요청마다 연결 생성/해제
또는 일정 시간 유지
구현 복잡성 간단 (표준 HTTP) 복잡
(별도 라이브러리/서버 설정)
간단 (정기적 요청)
인프라 호환성 HTTP 인프라에 친화적 일부 인프라에서 제한적 HTTP 인프라에 친화적
자원 효율성 비교적 효율적
(단방향 지속 연결)
높은 자원 효율
(지속 연결)
낮음 (잦은 요청/응답)
자동 재연결 브라우저 내장 지원
(EventSource)
수동 구현
또는 외부 라이브러리 필요
해당 없음
데이터 형식 주로 텍스트
(UTF-8 인코딩)
텍스트 및 바이너리 모두 지원 텍스트 기반
주요 용도 실시간 뉴스
로그 스트리밍
주식 시세 등
채팅
게임
협업 편집 등 양방향
단순 주기적 갱신
트래픽 적은 환경

SSE 구현 원리

동작 방식

1)클라이언트 요청

  • 클라이언트가 SSE 연결 요청을 보냄
  • 요청을 보낼 때 HTTP 요청 헤더에는 Accept: text/event-stream 포함
  • 이는 곳 “이제부터 서버가 무슨 일이 생기면 계속 알려줘. 나는 듣기만 할게”라는 의미

2)서버 응답 및 연결 유지

  • 서버가 요청을 수락하고 응답함
  • 응답할 때는 Content-Typetext/event-stream로 설정
  • Connection 헤더를 포함하여 연결 유지
  • 하나의 TCP 연결을 유지하면서 데이터 전송 가능

3)실시간 메시지 전송

  • 서버에서 이벤트 발생 시 메시지를 클라이언트에 전송
  • 클라이언트는 수신한 데이터로 필요한 작업 수행 (예: 화면 업데이트)
  • 클라이언트 → 서버 방향의 통신은 별도 HTTP 요청 필요

4)자동 재연결

  • 연결이 끊기면 클라이언트가 자동으로 재연결 시도
  • EventSource 객체가 재접속 기능 내장
  • 메시지에 ID가 있을 경우, Last-Event-ID로 이어서 수신 가능

5)연결 종료

  • 클라이언트 또는 서버가 명시적으로 연결 종료 가능
  • 자원 낭비 방지 및 필요 시 통신 종료 처리

HTTP Connection 유지 방법

  • HTTP/1.0: Connection: keep-alive 헤더를 사용하여 연결 유지.
  • HTTP/1.1 이상: 기본적으로 연결을 유지하므로 별도 설정 불필요.

HTTP 헤더

구분 설명
Request Header 헤더에 Accept: text/event-stream을 포함
Response Header 서버는 Content-Type: text/event-stream
Cache-Control: no-store를 포함하여 응답.

Stream Event Format

항목 설명
data - data:로 시작하며 전송할 텍스트 데이터를 담는다.
id - id:로 시작하며 각 메시지에 고유한 ID를 부여한다.
- 클라이언트는 재접속 시 이 ID로 이어받을 수 있음
event - event:로 시작하며 이벤트의 유형을 명시한다.
- 클라이언트는 유형에 따라 별도로 처리 가능하다.
retry - retry:로 시작하며 연결이 끊길 시 재접속을 시도할 시간(ms)을 지정한다.
  • 주석 : :로 시작하는 줄은 주석이며 클라이언트에서 무시된다.
  • 메시지 구분 : 각 메시지는 두 개의 줄 바꿈 (\n\n)으로 구분된다.
  • 인코딩 : 메시지는 UTF-8 로 인코딩된다.

FastAPI 를 이용한 SSE 구현하기

Reference

얄코 - SSE (Server Sent Events) - 서버가 그대에게 보낸다
https://hyuk0309.tistory.com/24
https://news.hada.io/topic?id=18450
https://alive-wong.tistory.com/47

Comments