Skip to content

모든 길 조회하기 API를 SSE 적용하기

YoonDH edited this page Feb 25, 2025 · 3 revisions

✅ SSE란?

  • SSE란 Server Sent Event로 클라이언트와 서버간의 실시간 단방향 통신으로 서버에서 클라이언트로 이벤트를 전송시키는 방법이다.

SSE를 적용한 이유

  • 백엔드에서 모든 길을 조회하는 API가 여러 명이 동시 요청을 하게 될 경우, OOM 문제가 발생하여 해당 API를 분할하여 요청하는 방식을 제안하였습니다.

[FE] 클라이언트의 SSE 결과

  • 기존 API 통신방법과 SSE 통신 방식을 코드로 비교해보았다.
const results = useSuspenseQueries({
		queries: [
			{
				queryKey: ["routes", university.id],
				queryFn: () => getAllRoutes(university.id),
				refetchInterval: 300000,
			},
		],
	});
  • useSuspenseQuery를 사용하여 모든 길 조회를 진행하고 있다. 이는 길이 매우 많아지게 될 경우, 로딩 시간이 길어지게 된다.
useEffect(() => {
		if (!map) return;

		const eventSource = new EventSource(
			`${import.meta.env.VITE_REACT_SERVER_BASE_URL}/${university.id}/routes/sse`,
		);

		eventSource.onmessage = (ev) => {
			if (ev.isTrusted) {
				const { batchSize } = JSON.parse(ev.data);
				...
				sseCounter.current += 1;
				if (sseCounter.current === batchSize) {
					eventSource.close();
				}
			}
		};

		eventSource.onerror = () => {
			sseCounter.current = 0;
		};

		return () => {
			eventSource.close();
		};
	}, [map]);
  • 클라이언트에서는 new EventSource에 URL을 등록하여 SSE를 수신할 수 있다.
  • 이때, useEffect에 의해 EventSource가 생성이 되면 서버는 이를 감지하고 모든 길을 분할하여 조회하고 조회된 결과를 이벤트로 전송한다. 모든 길을 전송한 이후에는 서버에서 연결을 해제한다.
  • 클라이언트는 EventSource를 close하기 전까지 계속 열려있다. 또한, 서버에서 이벤트를 닫아버린다면 클라이언트는 이를 오류로 감지하고 재연결을 한다. 이는 SSE 특징으로 오류가 발생한다면 무한으로 재요청한다는 점이다.
  • 이런 무한 재요청을 방지하기 위해서, 서버에서는 클라이언트에 Event가 발생할 횟수를 전달한다.
  • 클라이언트는 현재 수신한 이벤트의 개수와 전체 이벤트 개수를 비교하고 전체 개수만큼 이벤트를 받게 된다면 close를 한다.
  • 에러가 발생할 경우, 수신한 이벤트 개수를 초기화 한다.

동작 비교 (영상)

API

2025-02-25.11.10.05.mov

SSE

2025-02-25.11.10.20.mov
  • SSE가 초기 렌더링이 빨라진것을 확인할 수 있습니다.

Clone this wiki locally