리액트 SSE 연결

0


오늘은 SSE 연결을 통해 서버에서 댓글이나 메세지를 받았을때 바로 알림을 받을 수 있는 기능을
구현 했다.
백엔드쪽 자료는 많았지만 프론트엔드쪽은 자료가 적어서 너무나 힘들었기에
많은 사람들에게 도움이 되면 좋겠지만 나의 글솜씨는 좋지 않기 때문에 너무 기대를 안했으면 좋겠다.

아래는 프론트엔드의 기본 적인 코드 나는 토큰을 쿠키에 담아서 저장했고 이걸 헤더에 담아 주었다.
아참 시작전에 EventSourcePolyfill을 설치하고 import 해주자

useEffect(() => {
    const accessToken = getCookie("access_token");
    const refreshToken = getCookie("refresh_token");

    const eventSourceInitDict: any = {
      headers: {
        accessToken: accessToken || "",
        refreshToken: refreshToken || "",
      },
    };

    sse.current = new EventSourcePolyfill(
      `${process.env.REACT_APP_SERVER_URL}/서버에서 준 주소,
      eventSourceInitDict
    );

    sse.current.onopen = (e) => {
      setIsStarted(true);
      console.log("[sse] 연결이 열렸습니다", { e });
    };

    sse.current.addEventListener("addComment", (event: any) => {
      const eventData = JSON.parse(event.data);
      console.log("댓글을 받았습니다:", eventData);
      setEventDataList((eventDataList) => [...eventDataList, eventData]);
    });

    sse.current.addEventListener("addMessageRoom", (event: any) => {
      const eventData = JSON.parse(event.data);
      console.log("메세지를 받았습니다:", eventData);
      setEventDataList((eventDataList) => [...eventDataList, eventData]);
    });


    sse.current.onerror = (err) => {
      console.log("[sse] 에러 발생", { err });
    };

    // 컴포넌트가 언마운트될 때 SSE 연결을 해제합니다.
    return () => {
         if (sse.current) {
        sse.current.close();
      }
    };
  }, []);

문제점

SSE가 받아 지는것을 성공했지만 위의 이미지처럼 나는 이걸 새로고침을 해도 저장할수 있어야
했지만 SSE는 그것이 불가능했다.

해결책

HTTP방식으로 서버단에서 따로 저장한것을 GET도 하는 방식을 추가 대신
우리가 지속적으로 요청을 하면 SSE를 사용하는 의미가 없으니

useEffect(() => {
  if (AlertData) {
    setEventDataList(AlertData);
  }
}, [AlertData]);

useEffect로 Get 데이터가 있으면 SSE데이터에 추가하는 방식이다.

문제점2

SSE로 받은 데이터를 삭제를 시도하면 HTTP방식으로는ㄴ 아직 데이터가 없는 상태이다.
즉 새로고침을 해줘야 GET으로 받은 데이터가 존재함이 되므로 삭제가 가능 하게 된다.

해결책2

useEffect로 SSE로 데이터를 받으면 queryClient 시켜서 새로고침을 시켜준다.

useEffect(() => {
  if (eventDataList) {
    queryClient.invalidateQueries("getAlert");
  }
}, [eventDataList]);

남은숙제

클릭하면 해당 메세지창이나 해당 댓글 페이지로 이동하기
메세지는 잘되는데
해당 댓글에는 두개의 쿼리스트링을 받는데 id값이 해당 게시물의 id가 아니라
댓글의 id로 따라가서 엉뚱한 게시물로 이동이 됨...

profile
𝙸 𝚊𝚖 𝚊 𝚌𝚞𝚛𝚒𝚘𝚞𝚜 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚠𝚑𝚘 𝚎𝚗𝚓𝚘𝚢𝚜 𝚍𝚎𝚏𝚒𝚗𝚒𝚗𝚐 𝚊 𝚙𝚛𝚘𝚋𝚕𝚎𝚖. 🇰🇷👩🏻‍💻

0개의 댓글