🛠 문제 정의

🔹 기존 문제 상황

프로젝트에서 WebSocket을 활용해 방(room) 입장, 알림(notification) 수신, 에러(error) 감지 등의 기능을 제공하고 있었습니다.

하지만 WebSocket 연결이 끊겼다가 다시 연결될 때, 기존에 등록한 구독(subscription)이 자동으로 복구되지 않는 문제가 발생했습니다.

이로 인해 방에서 실시간으로 메시지를 받아야 하지만, 다시 연결되면 더 이상 메시지를 수신하지 못하는 문제가 있었습니다.

🔹 주요 원인

  1. WebSocket 연결이 끊기면 기존 구독 정보가 삭제됨
  2. 각 구독을 개별적으로 관리할 필요가 있음

해결 과정

🔹 1차 해결 방안 – WebSocket 연결이 복구되었을 때 재구독 실행

접근 방식:

interface WebSocketState {
  client: Client | null;
  isConnected: boolean;
  pendingSubscriptions: PendingSubscription[];
  addPendingSubscription: (subscription: PendingSubscription) => void;
  resubscribeAll: () => void;
}

변경된 내용:

✅ 구독 정보(pendingSubscriptions)를 저장하고,

connectWebSocket()에서 WebSocket 연결이 복구될 때 resubscribeAll()을 실행해 자동으로 재구독


export const useWebSocketStore = create<WebSocketState>((set, get) => ({
  client: null,
  isConnected: false,
  pendingSubscriptions: [],

  addPendingSubscription: (subscription: PendingSubscription) => {
    set((state) => ({
      pendingSubscriptions: [...state.pendingSubscriptions, subscription],
    }));
  },

  resubscribeAll: () => {
    const { client, isConnected, pendingSubscriptions } = get();
    if (!client || !isConnected) return;

    pendingSubscriptions.forEach((sub) => {
      const subscriptionPath =
        sub.type === 'room'
          ? WEBSOCKET_CONFIG.SUBSCRIBE_ROOM(sub.identifier as string)
          : sub.type === 'notification'
          ? WEBSOCKET_CONFIG.SUBSCRIBE_NOTIFICATION(sub.identifier as number)
          : WEBSOCKET_CONFIG.SUBSCRIBE_ERROR();

      console.log(`Resubscribing to ${sub.type}: ${subscriptionPath}`);
      client.subscribe(subscriptionPath, (message) => {
        sub.callback(JSON.parse(message.body));
      });
    });
  },

  connectWebSocket: () => {
    if (get().client) return;

    const client = new Client({
      brokerURL: WEBSOCKET_URL,
      reconnectDelay: 10000,
      onConnect: () => {
        set({ isConnected: true });
        get().resubscribeAll(); // WebSocket 재연결 시 자동 구독 복원
      },
    });

    client.activate();
    set({ client });
  },
}));