All files / src/hooks/use-notification/use-notification-connect-sse index.ts

11.25% Statements 9/80
100% Branches 0/0
0% Functions 0/1
11.25% Lines 9/80

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 811x 1x 1x 1x 1x 1x 1x 1x 1x                                                                                                                                                
import { useEffect, useRef, useState } from 'react';
 
import { useQueryClient } from '@tanstack/react-query';
import Cookies from 'js-cookie';
 
import { notificationKeys } from '@/lib/query-key/query-key-notification';
import { useAuth } from '@/providers/provider-auth';
 
export const useConnectSSE = () => {
  const [receivedNewNotification, setReceivedNewNotification] = useState(false);

  const { isAuthenticated } = useAuth();
  const eventSourceRef = useRef<EventSource | null>(null);
  const queryClient = useQueryClient();

  // 알림 수신 후 3초 뒤 receivedNewNotification이 false로 변경됨
  useEffect(() => {
    if (!receivedNewNotification) return;

    const timer = setTimeout(() => {
      setReceivedNewNotification(false);
    }, 3000);

    return () => clearTimeout(timer);
  }, [receivedNewNotification]);

  // SSE 연결 관련 로직
  useEffect(() => {
    if (!isAuthenticated) return;

    // 기존 연결이 있으면 정리
    if (eventSourceRef.current) {
      console.log('[DEBUG] SSE 기존 연결 정리');
      eventSourceRef.current.close();
    }

    const token = Cookies.get('accessToken');

    // SSE 연결 시도
    const es = new EventSource(
      `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/v1/notifications/subscribe?accessToken=${token}`,
    );

    eventSourceRef.current = es;

    // SSE 연결 성공 시
    es.addEventListener('connect', (event) => {
      console.log('[DEBUG] SSE 연결 확인:', event.data);
    });

    // SSE 알림 수신 시
    es.addEventListener('notification', (event) => {
      try {
        const data = JSON.parse(event.data);
        console.log('[DEBUG] SSE 수신 성공:', data);
        setReceivedNewNotification(true);
        queryClient.invalidateQueries({ queryKey: notificationKeys.unReadCount() });
        queryClient.invalidateQueries({ queryKey: notificationKeys.list() });
        // TODO: 알림 타입별 처리 추가 예정
      } catch (error) {
        console.error('[DEBUG] SSE 데이터 파싱 실패:', error);
      }
    });

    // SSE 연결 실패 시
    es.onerror = (_error) => {
      console.log('[DEBUG] SSE 오류 발생:');
      // todo: 재 연결 로직 추가 필요
    };

    // SSE Cleanup
    return () => {
      console.log('[DEBUG] SSE 연결 정리');
      es.close();
      eventSourceRef.current = null;
    };
  }, [isAuthenticated, queryClient]);

  return { receivedNewNotification };
};