학습 하며 정리한 내용들로, 부족한 점은 양해 부탁드립니다.
알려주시면 감사하겠습니다. 🍀
앞서 LongPolling 방식으로 구현 후,
다른 URL 통한 SSE 방식의 알람 서비스 방식을 추가적으로 구현 해보며,
주요 학습 했던 것들과 느낀 차이점들을 정리해보고자 합니다.
기본적 차이는
당시 구현할 때는 큰 차이 보단 좀 불편한 느낌이었는데
Pub/Sub 으로 가면서 .. 주요하게 느낀 점이 있었습니다.
Polling 🆚 Push ?
나의 구현은 ...SSE 통한 여러 차례 응답 처리를 하지 않았습니다. 🙃
응답 후 응답을 위한 정보를 바로 삭제 해서 다음 응답을 할 수가 없게 했어요.
sseAlarmLocalInMemory.delete(recipientId);
sseAlarmLocalInMemory.get(recipientId)
.ifPresentOrElse(session -> {
session.send(Alarm.from(alarmEntity), SseSession.Error.SEND);
sseAlarmLocalInMemory.delete(recipientId);
}, () -> log.info("The alarm is missed. [to: {}]", recipientId));
사실 적용까진 하지 않았지만, 정리 해 봅니다.
public SseEmitter()
public SseEmitter(Long timeout)
timeout 설정 안하면 , the underlying server 에 의해 결정 된다고 하는데요.. ?
톰캣 설정을 조금 봐보면
public void send(Object object) throws IOException
public void send(Object object, @Nullable MediaType mediaType)
throws IOException
// static import of SseEmitter.*
SseEmitter emitter = new SseEmitter();
emitter.send(event().data(myObject, MediaType.APPLICATION_JSON));
public void send(SseEmitter.SseEventBuilder builder)
throws IOException
// static import of SseEmitter
SseEmitter emitter = new SseEmitter();
emitter.send(event().name("update").id("1").data(myObject));
public static SseEmitter.SseEventBuilder event()
MediaType 힌트로 HttpMessageConverter 선택
스프링 부트는 요청 타입 설정시 자동으로 응답 타입 결정된다.
- 별도의 응답 타입 지정 없이 아래와 같은 결과의 응답 헤더 확인 할 수 있었다.
SseEventBuilder 는 이밴트를 포맷하기 위한 이용
예외 발생은 ResponseBodyEmitter 의 send() 기준
완료 or 타임아웃시
sseSession.checkEmitter(
() -> sseAlarmLocalInMemory.delete(sseSession.recipientId()));
저는 배포하지 않아서 정리만 해봅니다.
자세한 내용은 아래 블로그를 참고 하면 좋을 거 같습니다.
Spring에서 Server-Sent-Events 구현하기
( 자세한 내용은 해당 블로그를 참고해 주세요.)
UTF-8
로 인코딩된 텍스트 데이터만 가능SseEmitter
API를 제공Emitter 생성 후 만료시간 까지 보낸 데이터 없으면, 클라이언트에서 재연결 요청시 에러 발생
에러 방지 위해 처음 연결시 더미 데이터를 응답
// SseAlarmService - connect()
sseSession.send(ALARM_CONNECTION_MESSAGE, SseSession.Error.CONNECTION);
EventSource
인터페이스는 기본적으로 헤더 전달을 지원하지 않는다open-in-view
속성이 true 이면open-in-view
설정 반드시 false로 설정위에서 Response-line : HTTP/1.1 200 필요
Nginx에서 백엔드 WAS로 요청시 Connection: close
헤더 사용으로 연결 지속 X
proxy_set_header Connection '';
proxy_http_version 1.1;
X-Accel-Buffering: no