Server-Sent Events(SSE)의 프로토콜 구조와 통신 원리

Server-Sent Events(SSE)는 브라우저의 EventSource API가 HTTP 응답 본문을 UTF-8 이벤트 스트림으로 읽는 방식입니다. WebSocket과 달리 브라우저 API는 서버에서 클라이언트로 흐르는 이벤트 수신에 초점을 둡니다. 표준이 정하는 것은 이벤트 형식과 클라이언트 동작이며, 서버의 저장소나 메시지 복구 시스템까지 포함하지 않습니다.

스트림은 text/event-stream 형식이며 data:, event:, id:, retry: 같은 줄을 사용합니다. 빈 줄이 이벤트를 끝내고, 콜론으로 시작하는 줄은 주석으로 처리됩니다. EventSource가 연결을 다시 세울 때 서버가 id:로 보낸 마지막 이벤트 ID를 Last-Event-ID로 전달할 수 있지만, 재전송할 기록을 보유하고 ID의 의미를 해석하는 일은 애플리케이션 책임입니다. 요청의 Accept 헤더는 브라우저가 설정할 수 있는 항목이지, 웹 코드가 EventSource 옵션으로 임의 지정하는 헤더가 아닙니다.

전문가 관점: 재연결 커서와 이벤트 복구는 별개

Ably의 Amber Dawson(Content Lead)은 LLM 스트리밍 구현 사례에서 Last-Event-ID가 해결하는 것은 재연결 때 클라이언트가 마지막으로 받은 ID를 서버에 알리는 단계뿐이라고 설명합니다. 서버가 이벤트 로그를 보관하고 해당 커서 뒤의 항목을 다시 내보내며, 중복과 보존 만료를 처리해야 비로소 재생이 됩니다. 이는 Ably의 실시간 서비스 경험에서 나온 구현 관점이지 SSE 규격이 제공하는 메시지 보장으로 일반화할 수 없습니다. WHATWG 표준도 재연결 동작을 정의할 뿐 서버의 기록·재전송을 규정하지 않습니다.

운영 설계: 표준 형식과 인프라 동작을 구분

EventSource는 서버에서 클라이언트로 UTF-8 텍스트 이벤트를 받는 API입니다. 브라우저는 연결이 끊기면 재시도하고, id:를 처리한 경우 재연결 요청에 Last-Event-ID를 포함할 수 있습니다. 이 API가 임의의 요청 헤더를 설정하는 것은 아니며, Accept 헤더도 표준상 사용자 에이전트가 설정할 수 있다고 되어 있습니다. 응답은 text/event-stream이어야 합니다. 버퍼링, 연결 제한, 유휴 타임아웃, 브라우저별 동시 연결 수는 프록시·서버·HTTP 버전 구성에 좌우되므로 실환경에서 점검하세요. HTTP/2 다중화는 여러 스트림을 한 연결에 실을 수 있지만, SSE 작동이나 전달 완전성을 보장하지 않습니다.

참고 문헌 및 자료 출처