[SSE] Server-sent-Events를 통한 알림 구현 (Client)

나라·2024년 1월 13일
0

[PROJECT] USports

목록 보기
1/5

개요

  • 팀 프로젝트에서 SSE를 통한 알림 구현 기능을 하기로 했다
  • 공식 MDN 참고

🔎 SSE(server sent events)란?

웹소켓 과 거의 동일하게 작동하되 WSS 프로토콜을 따로 사용하는 웹소켓과 달리
SSE는 HTTP 프로토콜을 사용하기 때문에 비교적 구현이 용이하며 클라이언트와 서버가 연결을 맺으면 그 뒤로 서버는 클라이언트에게 지속적으로 데이터를 보낼 수 있다
이는 단방향 연결이므로 클라이언트에서는 서버로 이벤트를 보낼 수 없다

과정

1. EventSource 인스턴스 생성

const eventSource = new EventSource(`${process.env.NEXT_PUBLIC_BACKEND_SERVER}/subscribe`);

매개변수 자리에 연결을 맺을 해당 서버 url을 넣어 새로운 인스턴스를 생성

  • 하지만 본인은 request header에 유저 인증 토큰을 포함시켜야 했으므로
  • EventSourcePolyfill 을 사용하기 위한 추가 작업 진행
  • event-source-polyfill 안내 문서 참고
npm install event-source-polyfill

설치 후

import { EventSourcePolyfill, NativeEventSource } from 'event-source-polyfill'
const EventSource = EventSourcePolyfill || NativeEventSource

2. custom event 수신

   eventSource.addEventListener('sse', (event: any) => {
      const { data } = event
      if (!data.includes(`EventStream Created`)) 
       // 알림 수신 시 처리 로직
    })
  • 백엔드와 협의된 커스텀 이벤트 명으로 이벤트 리스너를 달아주면 끝이다
  • 필자는 'sse'라는 이벤트명으로 지정되었으므로 위 코드와 같이 작성
  • 서버로부터 이벤트 발생 시 지정된 이름의 이벤트로 수신된다

본 프로젝트에서는 서버로부터 최초 연결 시 'EventStream Created' 라는 메세지를 수신받게 됐는데, 클라이언트 측은 최초의 연결 성공 메세지를 제외한 알림 내역 (메세지) 을 관리해야 하므로 추가 필터링 작업 진행

전체코드

'use client'
import React, { useEffect, useRef, useState } from 'react'
import { useRecoilState } from 'recoil'
import { EventSourcePolyfill, NativeEventSource } from 'event-source-polyfill'
import { useRouter } from 'next/navigation'
//중략 
const SseComponent = () => {
  const EventSource = EventSourcePolyfill || NativeEventSource
  useEffect(() => {
    const eventSource = new EventSource(
      `${process.env.NEXT_PUBLIC_BACKEND_SERVER}/subscribe`,
      {
        headers: {
          Authorization: `Bearer ${token.accessToken}`,
          Connection: 'keep-alive',
        },
      },
    )
    eventSource.addEventListener('sse', (event: any) => {
      const { data } = event
      if (!data.includes(`EventStream Created`))
        // 처리 로직 
    })
    return () => {
      eventSource.close()
    }
  }, [user])
    //중략 
    
export default SseComponent

결과

실시간 알림 도착 시 (서버로부터 수신) 상단에 팝업 (알림 내용:data) 을 띄우고 좌측 알림 메뉴 아이콘은 요란법석을 떨도록 작업 진행했다

profile
FE Dev🔥🚀

0개의 댓글