Server-Sent Events의 기본 개념과 연결 원리 정리

HTTP 기반 지속 연결과 자동 재연결 동작 요약

ext/event-stream 포맷과 event/data/id/retry 필드 규칙 설명

백엔드(res.write)·프론트(EventSource) 예제 코드 포함으로 실무 적용 가이드 제공


목차

  1. SSE의 개요
  2. SSE의 연결
  3. SSE의 구조
  4. SSE의 송수신 데이터
  5. SSE의 예시코드

SSE

개요

  • Server-Sent Events

정의

  • 온라인 통신을 위한 “서버 → 클라이언트 스트림”
  • 서버가 클라이언트에게 계속 소식을 보내는 통신
  • 의미 : 서버가 클라이언트에게 데이터를 계속 “밀어주는” 방식

연결

  • 기반 프로토콜 : HTTP ( 보통 HTTP/1.1 또는 HTTP/2)

연결 원리

  • HTTP 범위 내에서 연결 일어남
  • 통신 과정
    1. 클라이언트가 EventSourse로 HTTP 요청
    2. 서버가 연결을 끊지 않음
    3. 서버가 이벤트를 텍스트 스트림으로 지속 전송
    4. 클라이언트는 실시간으로 수신만 수행
    5. 연결 끊기면 자동 재연결
  • 방송형 온라인 통신

구조

전체 구조

[브라우저]
  EventSource
      ↓  (HTTP 연결 유지)
[백엔드 서버]
  res.write() 로 이벤트 스트림 전송

백엔드에서 연결

[실시간 체결 데이터]
   ↓
[백엔드]
   ↓ SSE
[프론트]
  • 위의 구조가 흔함
    • 이유 보안 | WS는 노출 위험 큼 단방향 충분 | 서버→클라이언트면 SSE로 충분 안정성 | SSE 자동 재연결 인프라 | HTTP 기반이 운영 편함

송수신 데이터

  • text Stream : event : / data : 형태
  • 이벤트 단위 : 줄 단위 텍스트
  • 단순 이벤트 스트림에 적합

SEE 데이터 포맷 규칙

필드 설명
event 이벤트 이름 (선택)
data 실제 데이터 (필수)
id 이벤트 ID (재연결 시 사용)
retry 재연결 간격(ms)
event: trade
data: {"price":71200,"volume":3}
id: 10291

예시 코드

백엔드 예시

  • 기존 SSE 서버
import express from 'express';

const app = express();

app.get('/sse', (req, res) => {
  // SSE 필수 헤더
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  // 최초 연결 확인용 이벤트
  res.write(`event: connected\\n`);
  res.write(`data: connected\\n\\n`);

  let count = 0;

  const interval = setInterval(() => {
    count++;

    res.write(`event: tick\\n`);
    res.write(`data: ${JSON.stringify({ value: count, time: Date.now() })}\\n\\n`);
  }, 1000);

  // 클라이언트 연결 종료 처리
  req.on('close', () => {
    clearInterval(interval);
    console.log('SSE client disconnected');
  });
});

app.listen(3000, () => {
  console.log('SSE server running on port 3000');
});
​
포인트 의미
text/event-stream SSE 전용 MIME 타입
res.write 연결을 끊지 않고 데이터 전송
\n\n 이벤트 단위 종료 표시
req.on('close') 클라이언트 이탈 감지

 

프론트엔드 예시 (브라우저)

  • 기본 EventSource 사용
    const es = new EventSource('/sse');
    
    es.onopen = () => {
      console.log('SSE connected');
    };
    
    es.onmessage = (event) => {
      console.log('message', event.data);
    };
    
    es.onerror = (err) => {
      console.error('SSE error', err);
    };
    ​
    
  • 이벤트 타입 별로 받기
    const es = new EventSource('/sse');
    
    es.onopen = () => {
      console.log('SSE connected');
    };
    
    es.onmessage = (event) => {
      console.log('message', event.data);
    };
    
    es.onerror = (err) => {
      console.error('SSE error', err);
    };
    ​

SSE 의 장점이 코드에서 드러나는 부분

  • 자동 재연결 : 네트워크 끊기면 브라우저가 자동 재 시도
  • 단순성 : WebSocket 보다 코드 단순
  • HTTP 기반 : 프록시/보안 설정 유

실무에서 자주 쓰이는 패턴

  • 실시간 체결 스트
event: execution
data: { price, volume, time }
  • 알림
event: notification
data: { title, body }

 

devTool

항목 모습
Network Fetch/XHR
Status 200
상태 Pending 유지
Response 텍스트가 계속 누적
Messages 탭 없음

+ Recent posts