노트

서버 전송 이벤트(SSE)

Server-Sent Events

프런트엔드#network#http · 연결된 개념 4개

쉽게 말하면

SSE는 서버가 라디오 방송처럼 소식이 생길 때마다 흘려보내고 브라우저는 틀어 놓고 듣기만 하는 방식이에요. 주문 상태나 알림처럼 받기만 하면 되는 걸 계속 물어보지 않아도 돼요.

비유가 깨지는 곳 라디오와 달리 끊기면 브라우저가 알아서 다시 연결하고, 마지막으로 받은 id를 보내 이어 받을 수 있어요. 대신 서버→클라이언트 한 방향 텍스트라 채팅처럼 자주 보내야 하면 WebSocket을 써요.

서버 전송 이벤트(Server-Sent Events, SSE)는 HTTP(HyperText Transfer Protocol) 응답 하나를 닫지 않고 열어 둔 채, 서버가 원할 때마다 텍스트 이벤트를 흘려보내는 서버 → 클라이언트 단방향 푸시 방식이다. HTML 표준에 정의돼 있고 브라우저는 EventSource로 받는다.

const source = new EventSource('/api/orders/stream')
source.onmessage = (e) => render(JSON.parse(e.data))       // 이름 없는 이벤트
source.addEventListener('status', (e) => update(e.data))   // event: status
source.onerror = () => { /* 브라우저가 알아서 다시 연결한다 */ }
Content-Type: text/event-stream
 
event: status
id: 42
data: {"step":"shipping"}
 
: 주석 줄(연결 유지용 핑)
retry: 5000
  • 응답 타입은 text/event-stream, 인코딩은 항상 UTF-8. 필드는 event(이벤트 이름), data(본문, 여러 줄이면 이어 붙임), id, retry(재연결 대기 ms)이고 빈 줄이 이벤트 하나의 끝이다
  • 자동 재연결이 표준에 들어 있다. 끊기면 브라우저가 다시 연결하면서 마지막으로 받은 id를 Last-Event-ID 헤더로 보내 서버가 이어서 보낼 수 있다. 서버가 204 No Content로 답하면 재연결을 멈춘다
  • EventSource는 URL과 withCredentials만 받는다. 요청 헤더나 본문을 넣을 수 없어 인증은 쿠키로 하거나, fetch + ReadableStream으로 같은 형식을 직접 파싱한다
  • HTTP/1.1에서는 브라우저의 도메인당 동시 연결 제한(6개)에 걸려 탭을 여러 개 열면 막힐 수 있다. HTTP/2에서는 한 연결 안의 스트림으로 다뤄져 여유가 크다
  • 응답이 캐시되지 않도록 Cache-Control: no-cache를 함께 보낸다

WebSocket과 비교

SSEWebSocket
방향서버 → 클라이언트양방향
프로토콜평범한 HTTP 응답HTTP에서 업그레이드한 별도 프로토콜
데이터UTF-8 텍스트텍스트·바이너리
재연결·이어받기표준 내장직접 구현

알림, 진행 상태, LLM(Large Language Model) 토큰 스트리밍처럼 받기만 하면 되는 경우는 SSE가 단순하다. 채팅·협업 편집처럼 클라이언트도 자주 보내야 하면 WebSocket을 쓴다. 이벤트를 받아 TanStack Query 캐시를 갱신하면 주기적 재요청(polling)을 대신할 수 있다.

RSC 스트리밍과 무엇이 다른가

둘 다 응답을 조금씩 흘려보내지만 언제, 무엇을 흘리느냐가 다르다.

  • 스트리밍 SSR·RSC 페이로드는 한 번의 요청(첫 로드나 이동)으로 한 화면을 점진적으로 완성한다. 서버가 UI(HTML, 직렬화된 컴포넌트 트리)를 보내고, 화면이 다 채워지면 응답이 끝난다
  • SSE는 화면이 자리 잡은 뒤에도 연결을 유지하며 서버가 자기 시점에 데이터를 보낸다. 받은 데이터로 UI를 그리는 일은 클라이언트 몫이다

그래서 "첫 화면을 구역별로 빨리 보여 주기"는 RSC를 쓰는 앱이라면 Suspense 경계로 이미 풀리고, "로드 이후 서버가 먼저 알려 주기"는 RSC가 대신하지 못해 SSE나 WebSocket이 필요하다.

출처: MDN - Using server-sent events · HTML Standard - Server-sent events

연결된 개념

이 노트를 가리키는 문서

아직 없습니다.

뜻이 가까운 노트

  • XSS

    XSS(Cross-Site Scripting)는 공격자가 넣은 스크립트가 내 사이트의 출처(origin) 권한으로 사용자 브라우저에서 실행되는 공격이다. 같은 출처의 코드로 돌기 때문에 same-origin-policy가 막아 주지 못한다. 그 스크립트는 페이지를 바꾸고, 로그인한 사용자 행세를 하며 요청을 보내고, JS가 읽을 수 있는 데이터(localStorage의 토큰 등)를 빼 갈 수 있다.

  • CSR·SSR·SSG·ISR

    렌더링 전략은 HTML(HyperText Markup Language)을 언제, 어디서 만드느냐의 선택이다. 브라우저에서 만들면 CSR(Client-Side Rendering), 요청마다 서버에서 만들면 SSR(Server-Side Rendering), 빌드 때 미리 만들면 SSG(Static Site Generation), 미리 만든 것을 주기적으로 다시 만들면 ISR(Incremental Static Regeneration)이다.

  • React 서버 컴포넌트(RSC)

    React 서버 컴포넌트(React Server Components, RSC)는 서버에서만 실행되고, 컴포넌트 코드가 아니라 실행 결과(직렬화된 엘리먼트 트리)만 클라이언트로 보내는 컴포넌트다. Next.js App Router에서는 'use client'를 붙이지 않은 컴포넌트가 기본으로 서버 컴포넌트다.

  • HTTP와 HTTPS

    HTTPS는 HTTP(Hypertext Transfer Protocol) 메시지를 TLS(Transport Layer Security)로 감싸 보내는 방식이다. HTTP 자체는 바뀌지 않고, 그 아래에 암호화 계층이 하나 끼어든다. 기본 포트는 HTTP가 80, HTTPS가 443이다.

  • 서버 함수와 서버 액션

    서버 함수(Server Function)는 'use server'로 표시해 서버에서만 실행되지만 클라이언트에서 네트워크 요청으로 호출할 수 있는 async 함수다. 그중 폼 제출이나 데이터 변경처럼 action 맥락(form action, transition)에서 쓰이는 것을 서버 액션(Server Action)이라 부른다. 서버 액션은 서버 함수의 부분집합이다.

보기 옵션