SSE 사용법 자세히 보기 (MDN)
SSE는 Server-Sent Events로, 서버에서 클라이언트로 단방향 이벤트 스트림을 전송하는 기술이다.
웹에서 실시간 통신을 구현할 때는 주로 아래 3가지 방식을 고려한다. 상황에 맞게 선택하는 것이 중요하다.
2~3초마다 주기적으로 서버에 요청을 보내는 방식이다.
최초 한 번만 HTTP 요청으로 연결을 맺은 후, 쌍방향 통신을 지속적으로 유지한다.
HTTP 기반의 단방향 통신 방식으로, 서버에서 클라이언트로만 데이터 전송이 가능하다.
📎 나의 경험:
무인매장 관리 시스템에서 실시간 알림을 구현할 때 SSE를 사용한 경험이 있다.
이번 프로젝트에서도 읽지 않은 메시지 수를 실시간으로 업데이트 하기 위해 SSE를 선택했다.
브라우저에서 기본적으로 제공하는 EventSource
객체를 이용해 서버와 SSE 연결을 할 수 있다.
eventSource = new EventSource(
`${process.env.VUE_APP_API_BASE_URL}/sse/subscribe?token=${token}`
);
eventSource.addEventListener("unread-count", (event) => {
try {
const data = JSON.parse(event.data);
callback(data);
console.log("unread-count 이벤트 data:", data);
} catch (error) {
console.error("SSE unread-count 데이터 파싱 에러", error);
}
});
eventSource.onerror = (error) => {
console.error("SSE 연결 오류", error);
disconnectSSE();
};
⚠️ 알아야 할 점
EventSource
는 GET 메서드만 지원하고, 헤더 설정이 불가능하다.EventSource
와 사용법은 거의 동일하나 헤더를 직접 추가할 수 있는 라이브러리이다.
그래서 나는 이 라이브러리로 헤더에 token을 보내는 방법으로 수정했다.
npm install event-source-polyfill
import { EventSourcePolyfill } from "event-source-polyfill";
eventSource = new EventSourcePolyfill(
`${process.env.VUE_APP_API_BASE_URL}/sse/subscribe`,
{
headers: {
Authorization: `Bearer ${token}`,
},
withCredentials: true,
}
);
기존에는 @RequestParams
으로 토큰을 받았다면, 이제는 @RequestHeader
로 헤더를 받아 처리한다.
// MediaType.TEXT_EVENT_STREAM_VALUE : SSE를 위한 HTTP 응답 타입 설정 이다.
// 이걸 설정하면 프론트가 sse 스트림이라고 인식할 수 있다.
@GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribe(@RequestHeader("Authorization") String authorizationHeader){
String token = authorizationHeader.replace("Bearer ", "");
Claims claims = Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.getBody();
String email = claims.getSubject();
System.out.println(email + " SSE 구독 연결됨");
return sseService.subscribe(email);
}
MediaType.TEXT_EVENT_STREAM_VALUE
을 지정하면 프론트가 스트림을 응답으로 인식할 수 있다.
개발자 도구(F12) → Network 탭에서 연결 상태 및 메시지를 확인할 수 있다. (물론 서버 로그로도 확인 가능)
subscribe 요청 확인
Headers : 인증 헤더 포함 여부, 상태코드(200/401) 확인
Response : 실시간 전달되는 메시지 스트림 확인