SSE (Server Sent Event)

Jisu·2024년 1월 28일
0

Techs

목록 보기
5/8

배경

사내에서 새로 추진되는 프로젝트에 플랫폼 엔지니어어로 참여하게 되었다. 프로젝트 아키텍처 다이어그램을 봤는데 처음 접하는 용어들이 몇몇 있었다. 그 중 중요도가 높은 SSE에 대해서 서술해보고자 한다.


Server Sent Event

클라이언트가 서버로 부터 데이터를 실시간으로 계속 받을 수 있는 기술이다. (단방향)
클라이언트측에서는 서버에서 보내주는 데이터를 받고 계속해서 업데이트해야되는 상황이 있다. 그럴 때마다 새로고침을 하거나, 서버로 request를 보내지않아도 된다는 장점을 가지고 있다.

HTTP 프로토콜을 기반으로 하여 동작하기 때문에, 기존의 웹 서버와 클라이언트 사이에서 사용되는 HTTP 통신을 이용하여 상대적으로 쉽게 구현할 수 있다.


SSE의 한계

SSE는 서버와 클라이언트 간의 실시간 통신을 위해 연결 상태를 유지하고 있다. 서버는 상황에 따라 여러 클라이언트와의 동시 연결을 관리하는데, 만약 서버 측에서 부하 및 장애가 발생하면 연결이 끊어질 수 있다. 이는 클라이언트가 서버로부터 데이터를 수신할 수 없는.. 유저에게 서비스가 올바르게 제공되지 못하는 심각한 상황에 이르게 된다.

SSE는 단방향 통신으로 클라이언트에서 서버로의 요청을 보낼 수 없어 클라이언트에서 발생한 문제나 에러를 서버로 전달하기 어렵다. 이는 클라이언트 측에서 발생한 장애가 서버로 전파되어 서버 측에서 처리하기 어려운 상황을 만들 수 있다. (이는 곧 서버의 부하증가로도 이어진다...)

이러한 이유로, SSE를 사용하는 시스템에서는 장애가 전파될 가능성을 고려하여 적절한 예외 처리와 오류 처리 메커니즘을 꼼꼼하게 구현해야한다. 이 말은.. 서비스가 추가될 때마다 항상 예외처리를 포함한 여러 코드가 추가되어 확장성에 한계를 가진다는 말이다..


예시 코드

SSE Endpoint BE코드

import express from "express";

const app = express();

// SSE 연결을 위한 라우트 핸들러
app.get("/sse", (req, res) => {
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");
  res.setHeader("Access-Control-Allow-Origin", "*");

  // SSE 연결 유지를 위한 빈 데이터 전송
  res.write(":\n\n");

  // 일정 간격으로 데이터 전송
  const interval = setInterval(() => {
    const data = new Date().toISOString();
    res.write(`data: ${data}\n\n`);
  }, 1000);

  // 클라이언트 연결 종료 시 SSE 연결 종료
  req.on("close", () => {
    clearInterval(interval);
    res.end();
  });
});

// 서버 실행
app.listen(3000, () => {
  console.log("Server started on port 3000");
});

FE 코드

// SSE 연결을 수행하는 함수
function connectToSSE(): void {
  const eventSource = new EventSource("/sse"); // SSE를 지원하는 엔드포인트 주소

  // 이벤트 수신 시 처리할 로직
  eventSource.addEventListener("message", (event: MessageEvent) => {
    const data = event.data;
    console.log("Received data:", data);
    // 데이터를 받아 처리하는 로직을 작성합니다.
  });

  // SSE 연결 상태 처리
  eventSource.onopen = () => {
    console.log("SSE connection opened.");
  };

  eventSource.onerror = () => {
    console.error("Error occurred in SSE connection.");
  };
}

// SSE 연결 시작
connectToSSE();

Reference

SSE 블로그 글
SSE 블로그 글2

profile
비즈니스에 관심많은 DevOps Engineer 장지수입니다.

0개의 댓글