AI를 활용한 사내 캘린더 프로젝트에서 SSE를 이용해 일정 생성 및 알림 생성 시 실시간 알림 기능을 구현하게 되었다.
이 과정에서 SSE 연결 유지 시간을 어느 정도로 설정하는 것이 적절할지에 대한 고민이 생겼다.
❗️ 짧은 연결 시간의 문제점:
클라이언트가 빈번하게 재연결 요청을 보내네트워크 오버헤드
가 증가
네트워크가 불안정한 환경(ex. 모바일)에서 연결 안정성이 저하될 가능성
❗️ 긴 연결 시간의 문제점:
사용하지 않는 연결도 리소스를 점유하여서버 부하 증가
연결이 끊어진 클라이언트를 감지하는 데 시간이 오래 걸릴 수 있음
서버에서 클라이언트로 데이터를 실시간으로 전송할 수 있는 단방향 통신 방식
단방향 실시간 통신: 서버 → 클라이언트로만 데이터 전송.
HTTP 기반: 클라이언트는 EventSource 객체를 사용해 간단히 설정 가능.
자동 재연결: 네트워크 문제가 발생해도 자동으로 복구 시도.
일반적으로 SSE 연결 유지 시간은 5분 ~ 30분으로 잡고, Ping 메시지를 주기적으로 보내 연결 상태를 확인한다.
SseEmitter emitter = new SseEmitter(30 * 60 * 1000L); // 30분 유지
서버와 클라이언트 간의 연결 상태를 확인하고, 비활성 연결을 감지하거나 네트워크 문제를 조기에 발견하기 위해 주기적으로 전송되는 작은 데이터 패킷
/**
* 모든 클라이언트에게 Ping 메시지 전송
*/
private void sendBroadcastPing() {
emitters.forEach((userId, emitter) -> {
try {
emitter.send(SseEmitter.event().name("ping").data("keep-alive"));
} catch (IOException | IllegalStateException e) {
log.warn("Ping 메시지 전송 실패 - 사용자: {}, 이유: {}", userId, e.getMessage());
emitters.remove(userId);
}
});
}
/**
* 1분마다 자동으로 Ping 메시지 전송
*/
@Scheduled(fixedRate = 60 * 1000L) // 1분마다 ping 전송
public void scheduledPing() {
sendBroadcastPing();
}
여러 클라이언트에게 동시에 동일한 메시지를 전송하는 방식
✅ 결론
- SSE 연결 유지 시간은 5~30분이 일반적이며, 클라이언트의 빈번한 재연결을 방지하는 것이 목표이다
- Ping 메시지는 30~60초마다 보내는 것이 적절하며, 부하를 고려하여 주기를 조절해야 한다
- 브로드캐스트 방식으로 Ping을 보내면 서버 부하를 줄일 수 있다
🗂️ 레퍼런스
https://developer.mozilla.org/ko/docs/Web/API/Server-sent_events
https://velog.io/@baekgom/SSE-Server-Sent-Event-%EC%95%8C%EB%A6%BC-%EA%B8%B0%EB%8A%A5
https://inma.tistory.com/179