Spring/Spring MVC

SseEmitter , SSE통신

doriver 2025. 2. 10. 15:36

 

SseEmitter

SseEmitter는 Spring MVC에서 Server-Sent Events(SSE)를 지원하는 클래스

 

 

서버에서는 클라이언트와 매핑되는 SSE 통신 객체를 만든다.


만료시간이 되면 브라우저에서 자동으로 서버에 재연결 요청을 보냅니다.

Emitter를 생성하고 나서 만료 시간까지 아무런 데이터도 보내지 않으면 재연결 요청시 503 Service Unavailable 에러가 발생할 수 있습니다. 따라서 처음 SSE 연결 시 더미 데이터를 전달해주는 것이 안전합니다.

 

SseEmitter의 send()가 실행되면 HTTP 메시지를 전송하는 것이 아니라, 데이터만 전송됨
( 이미 수립된 HTTP 연결을 통해 스트리밍됨,  )

 

SseEmitter관련 예외가 발생해 @ExceptionHandler가 호출되어 HTTP응답을 반환하면

스트리밍이 종료될수?? 있어 주의필요


SseEmitter에는
비동기 요청이 완료되거나 타임아웃 발생 시 실행할 콜백을 등록할 수 있습니다.
이 콜백은 SseEmitter를 관리하는 다른 스레드에서 실행된다. 
따라서 thread-safe한 자료구조를 사용하지 않으면 ConcurrnetModificationException이 발생할 수 있습니다. 
thread-safe한 자료구조인 CopyOnWriteArrayList등을 사용

 

 

SSE 연결이 종료되거나 오류가 발생했을 때 적절히 대응할 수 있도록
, onCompletion(), onTimeout(), onError() 등의 이벤트 핸들러를 제공

1. onCompletion(Runnable callback)

클라이언트와 SSE 연결이 정상적으로 완료될 때 실행
클라이언트가 EventSource.close()를 호출하거나, 서버에서 emitter.complete()를 호출하면 발생
정상 종료 시 처리해야 할 로직을 정의

emitter.onCompletion(() -> {
    // 정상 종료 시 처리해야 할 로직
});

 

 

 

2. onTimeout(Runnable callback)

설정한 타임아웃 시간이 지나면 실행됩니다.

emitter.onTimeout(() -> {

    emitter.complete(); // 연결을 안전하게 종료
});

클라이언트가 여전히 필요하다면 자동 재연결을 유도하도록 클라이언트 측 onerror()에서 처리.

 

 

 

 

 

 

 

https://jaehyeon48.github.io/network/polling-and-sse/

 

폴링, 롱폴링, HTTP 스트리밍, SSE

현재 실시간 양방향 통신을 구현할 때 흔히 사용하는 기술은 웹소켓 기술입니다. 이 포스트에선 웹소켓이 등장하기 전에 (실시간) 양방향 통신을 구현하던 방법인 폴링과 롱폴링, 스트리밍, 그

jaehyeon48.github.io

 

 

🔹 emitter.complete() 호출 시 서버와 클라이언트에서 일어나는 일

✅ 서버에서 일어나는 일

  • SSE 연결 종료

서버는 해당 SseEmitter객체를 더 이상 사용하지 않음.
이후에 emitter.send()를 호출시 예외 발생 

 

  • onCompletion() 이벤트 실행 (존재하는 경우)

만약 onCompletion()을 등록했다면 해당 콜백이 실행됨.

보통 여기에서 관리 중인 SseEmitter를 정리.

 

  • HTTP 응답 완료

SSE는 기본적으로 HTTP Streaming 방식이다. complete()가 호출되면 HTTP응답이 완료됨.

브라우저 측에서 EventSource 연결이 닫힘.


✅ 클라이언트에서 일어나는 일

  • EventSource 연결 종료 (onclose 또는 onerror 발생)
    • EventSource 객체는 자동으로 연결을 닫음.
    • onerror가 호출될 수 있음.
    • 이후 서버로부터 새로운 이벤트를 받을 수 없음.
  • 자동 재연결 (EventSource의 기본 동작)
    • 기본적으로 EventSource는 연결이 끊어지면 자동 재연결을 시도함.
    • 하지만, 서버가 더 이상 연결을 유지하지 않으므로 클라이언트는 계속 실패할 수 있음.