본문 바로가기
React

SSE 실시간 알림 기능 구현

by @kkkk_biiin 2023. 11. 20.
728x90

 중고 의류 거래 플랫폼 프로젝트를 진행하면서 채팅 기능, 찜하기 기능, 상점 팔로우 기능이 있었고, 누군가가 나에게 채팅을 보내거나 내 상품을 찜하거나, 나의 상점을 팔로우했을 때 알림이 오는 기능을 구현해야 했다. 

 

 채팅을 웹소켓으로 구현을 했지만, 양방향 통신을 지원하는 웹소켓에 비해 단방향 통신을 지원하는 SSE를 사용하는 것이 서버 리소스와 네트워크 트래픽을 절약할 수 있다고 판단해 SSE를 활용해 알림 기능을 구현하기로 하였다.

 

SSE(Server Sent Event)

  • 단방향 데이터 흐름(서버 -> 클라이언트)
  • 단순성: 표준 HTTP를 통해 작동하기 때문에 WebSocket에 비해 간단함(캐싱, 프록시, 방화벽과 같은 기존 웹 인프라와 쉽게 통합)
  • 자동 재연결 메커니즘 내장

WebSocket

  • 양방향 통신
  • 실시간 상호 작용: 최소한의 대기 시간으로 양방향 동시 데이터 흐름을 처리할 수 있음
  • 유연성: 바이너리 데이터를 포함하여 더 복잡하고 다양한 메시지 유형과 형식을 허용

프로젝트에서 구현

 React에서는 EventSource 라이브러리를 제공하기 때문에 쉽게 구현할 수 있었다. 구현은 EventSource를 통해 서버에서 보내는 알림을 감지하고 Toast 라이브러리를 활용해 알림을 디자인하는 방식으로 하였다.

 

코드

useEffect(() => {
    if (token) {
      const eventSource = new EventSourcePolyfill('https://api.re-use.store/api/subscribe', {
        headers: {
          Authorization: token,
        },
        withCredentials: true,
      });

      eventSource.addEventListener('WISH', event => {
        const messageEvent = event as MessageEvent;

        toast.success(messageEvent.data, {
          icon: <img style={{ width: '20px', height: '20px' }} src="https://ifh.cc/g/00y5Y2.png" alt="pic" />,
          position: 'top-right',
          draggable: true,
          autoClose: 5000,
        });
      });
      
      return () => {
        eventSource.close();
      };
    }
  }, []);

 

 일단 로그인 한 유저만 알림이 오고, 감지를 하기 위해서는 token 값이 있어야 하기 때문에 token 값이 있을 경우에만 실행되도록 로직을 구성하였다. 이후 addEventListener를 통해 알림을 감지하였고, 이벤트가 감지되었을 경우 toast를 통해 알림을 웹 페이지 상에 보여주는 방법을 사용하였다.

 

 코드를 보면 eventSource가 아닌 EventSourcePolyfill 라이브러리를 사용한 것을 볼 수 있는데, 이를 사용한 이유는 eventSource는 type에 headers가 존재하지 않았기 때문이다. 우리 서비스에서는 알림을 감지하기 위해 서버에 token 값을 헤더에 보내줘야 했기 때문에 eventSource를 사용할 수 없었고, 이에 따라 EventSourcePolyfill 라이브러리를 사용하였다.

 

 

 

 

 

reference

https://yeo-computerclass.tistory.com/480

https://surviveasdev.tistory.com/entry/%EC%9B%B9%EC%86%8C%EC%BC%93-%EA%B3%BC-SSEServer-Sent-Event-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B3%A0-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0

https://velog.io/@ongsim123/Devlog-SSE%EB%A1%9C%EC%A7%81-%EA%B5%AC%ED%98%84-%EC%A4%91-EventSource%EC%97%90-headers%EB%8B%B4%EA%B8%B0

728x90

'React' 카테고리의 다른 글

useCallback을 활용한 성능 최적화  (0) 2023.11.29
useMemo를 사용한 성능 최적화  (1) 2023.11.27
이미지 최적화(Browser image Compression)  (0) 2023.11.20
React lazy, Suspense  (2) 2023.11.20
React memo  (1) 2023.11.20