[Spring Boot] SSE(EventSource) 이벤트 리스너로 실시간 데이터 처리하기

KangWook·2024년 9월 25일
0

Server-Sent Events(SSE)는 서버가 클라이언트로 실시간 데이터를 푸시할 수 있는 웹 표준 기술입니다. 주로 실시간 알림, 주식 가격 업데이트, 실시간 대시보드 등에서 사용됩니다. 이번 글에서는 Spring Boot로 SSE를 구현하는 방법과 JavaScript를 이용한 클라이언트 이벤트 리스너를 소개합니다.

SSE란?
SSE는 서버에서 클라이언트로 일방향 실시간 데이터 전송을 제공하는 기술입니다. 웹 브라우저의 EventSource API를 사용하여 클라이언트에서 서버에 연결을 열고, 서버는 지속적으로 클라이언트에게 데이터를 보낼 수 있습니다.

  • 단방향 통신: 서버에서 클라이언트로 데이터를 보냅니다.
  • 자동 재연결: 연결이 끊어지면 클라이언트가 자동으로 다시 연결을 시도합니다.
  • 텍스트 기반 데이터 전송: 일반적으로 JSON이나 텍스트 형식의 데이터를 주고받습니다.

SSE와 WebSocket 차이점
SSE: 서버에서 클라이언트로 일방향 푸시. HTTP 기반이며 설정이 간단.
WebSocket: 클라이언트와 서버 간 양방향 통신 가능. 양방향 데이터 전송이 필요하면 WebSocket이 적합.

Spring Boot로 SSE 구현하기
1. 프로젝트 설정
먼저 Spring Boot 프로젝트에서 spring-boot-starter-web 의존성을 추가합니다.


2. SSE 서버 구현
SseEmitter 클래스를 사용하여 SSE 기능을 제공할 수 있습니다. 아래는 서버에서 클라이언트로 메시지를 실시간으로 전송하는 간단한 예제입니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@RestController
public class SseController {

    @GetMapping("/sse-stream")
    public SseEmitter streamSse() {
        SseEmitter emitter = new SseEmitter(30000L); // 타임아웃 30초

        ExecutorService service = Executors.newSingleThreadExecutor();

        service.execute(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    emitter.send("서버에서 보낸 메시지: " + i);
                    TimeUnit.SECONDS.sleep(1); // 1초마다 전송
                }
                emitter.complete();
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e);
            } finally {
                service.shutdown();
            }
        });

        return emitter;
    }
}

3. Spring Boot 애플리케이션 실행
서버가 실행되면 /sse-stream 경로로 클라이언트가 연결하여 실시간 데이터를 받을 수 있습니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>SSE Example</title>
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            const eventSource = new EventSource("http://localhost:8080/sse-stream");

            eventSource.onmessage = function (event) {
                console.log("서버에서 받은 메시지:", event.data);
                const messageContainer = document.getElementById("messages");
                messageContainer.innerHTML += "<p>" + event.data + "</p>";
            };

            eventSource.onerror = function (event) {
                console.error("SSE 오류 발생:", event);
                eventSource.close();
            };
        });
    </script>
</head>
<body>
    <h1>Server-Sent Events (SSE)</h1>
    <div id="messages"></div>
</body>
</html>

실행 흐름

  • 클라이언트는 /sse-stream에 연결하고, 서버에서 실시간으로 데이터를 받습니다.
  • 서버는 SseEmitter를 통해 1초 간격으로 데이터를 클라이언트로 푸시합니다.
  • 클라이언트는 onmessage 리스너로 서버에서 전송된 데이터를 화면에 표시합니다.

SSE의 장점과 활용 사례
장점:

  • 자동 재연결: 네트워크 문제가 발생해도 클라이언트가 자동으로 재연결을 시도합니다.
  • 단순성: 서버에서 클라이언트로 일방향 실시간 데이터를 쉽게 전송할 수 있습니다.
  • HTTP 기반: HTTP/2를 사용할 경우 다수의 클라이언트와 연결을 효율적으로 처리할 수 있습니다.

활용 사례:

  • 실시간 알림 시스템: 사용자에게 실시간 알림을 전송할 수 있습니다.
  • 실시간 대시보드: 서버에서 발생하는 이벤트를 실시간으로 대시보드에 반영할 수 있습니다.
  • 주식 가격 업데이트: 실시간 주식 데이터를 클라이언트로 스트리밍하여 시장 변화를 즉각적으로 반영합니다.

결론
SSE(Server-Sent Events)는 서버에서 클라이언트로 실시간 데이터를 푸시하는 데 매우 유용한 기술입니다. Spring Boot에서는 SseEmitter 클래스를 사용하여 간단하게 구현할 수 있으며, 클라이언트에서는 HTML5의 EventSource API를 통해 서버 데이터를 실시간으로 처리할 수 있습니다. 실시간 데이터 전송이 필요한 다양한 애플리케이션에서 SSE를 활용해 보세요!

참고 자료:

  • MDN - Server-Sent Events
  • Spring Documentation - SseEmitter
profile
꾸준히 성장하는 개발자

0개의 댓글