프로젝트에서 WebSocket을 활용해 방(room) 입장, 알림(notification) 수신, 에러(error) 감지 등의 기능을 제공하고 있었습니다.
하지만 WebSocket 연결이 끊겼다가 다시 연결될 때, 기존에 등록한 구독(subscription)이 자동으로 복구되지 않는 문제가 발생했습니다.
이로 인해 방에서 실시간으로 메시지를 받아야 하지만, 다시 연결되면 더 이상 메시지를 수신하지 못하는 문제가 있었습니다.
subscribe
함수를 재호출하는 것이 아니라, 구독 유형별로 재등록할 수 있도록 해야 함.접근 방식:
onConnect
이벤트 발생 시 기존 구독들을 다시 등록하도록 변경pendingSubscriptions
)을 추가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 });
},
}));