From e9d22953eec5bb8efad16e4c00c3f339b2d34600 Mon Sep 17 00:00:00 2001 From: YuMin Kim Date: Sun, 24 Nov 2024 01:41:14 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20WebSocket=E5=86=8D?= =?UTF-8?q?=E6=8E=A5=E7=B6=9A=E3=83=AD=E3=82=B8=E3=83=83=E3=82=AF=E3=81=8A?= =?UTF-8?q?=E3=82=88=E3=81=B3=E7=8A=B6=E6=85=8B=E7=AE=A1=E7=90=86=E3=81=AE?= =?UTF-8?q?=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manageSubComponents/LiveClass.tsx | 165 ++++++++---------- 1 file changed, 76 insertions(+), 89 deletions(-) diff --git a/src/app/classes/[cId]/[mId]/components/manageSubComponents/LiveClass.tsx b/src/app/classes/[cId]/[mId]/components/manageSubComponents/LiveClass.tsx index 183d072..c47b114 100644 --- a/src/app/classes/[cId]/[mId]/components/manageSubComponents/LiveClass.tsx +++ b/src/app/classes/[cId]/[mId]/components/manageSubComponents/LiveClass.tsx @@ -82,16 +82,16 @@ const LiveClass: React.FC = ({ const connectWebSocketRef = useRef<(() => void) | null>(null); const wsUrl = useMemo(() => { const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; - const baseUrl = `${protocol}://${window.location.host}/mediasoup/socket.io`; + const host = window.location.host; + const baseUrl = `${protocol}://${host}/mediasoup`; - const safeNickname = encodeURIComponent(nickname || `User_${userId}`); const params = new URLSearchParams({ roomId: classId.toString(), userId: userId.toString(), - nickname: safeNickname, + nickname: encodeURIComponent(nickname || `User_${userId}`), }); - return `${baseUrl}?${params.toString()}`; + return `${baseUrl}?${params}`; }, [classId, userId, nickname]); const getOptimalEncodings = (kind: string) => { @@ -199,63 +199,90 @@ const LiveClass: React.FC = ({ }, }); - const MAX_RECONNECT_ATTEMPTS = 3; - const RECONNECT_INTERVAL = 2000; + const handleEndClass = useCallback(() => { + producersRef.current.forEach(producer => producer.close()); + producersRef.current.clear(); - const connectWebSocket = useCallback(() => { - let reconnectAttempts = 0; + consumersRef.current.forEach(consumer => consumer.close()); + consumersRef.current.clear(); - const connect = () => { - if (wsRef.current?.readyState === WebSocket.CONNECTING) { - console.log('WebSocket connection already in progress'); - return; - } + producerTransportRef.current?.close(); + consumerTransportRef.current?.close(); - console.log('Attempting WebSocket connection:', wsUrl); + if (localStreamRef.current) { + localStreamRef.current.getTracks().forEach(track => track.stop()); + } + if (screenStreamRef.current) { + screenStreamRef.current.getTracks().forEach(track => track.stop()); + } - const ws = new WebSocket(wsUrl); - wsRef.current = ws; + wsRef.current?.close(); - const connectionTimeout = setTimeout(() => { - if (ws.readyState === WebSocket.CONNECTING) { - ws.close(); - handleReconnect(); - } - }, 10000); + setClassStarted(false); + setStreams({}); + setConnectionState('disconnected'); + setIsSharingScreen(false); + }, []); - ws.onopen = () => { - clearTimeout(connectionTimeout); - console.log('WebSocket connected successfully'); - setConnectionState('connected'); - reconnectAttempts = 0; - }; + const handleReconnect = useCallback((): void => { + if (reconnectAttempts < 5) { + const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000); + console.log(`Reconnecting (${reconnectAttempts + 1}/5) in ${delay}ms`); - ws.onerror = error => { - console.error('WebSocket error:', error); - handleReconnect(); - }; + setTimeout(() => { + setReconnectAttempts(prev => prev + 1); + connectWebSocketRef.current?.(); + }, delay); + } else { + console.error('Max reconnection attempts reached'); + handleEndClass(); + } + }, [reconnectAttempts, handleEndClass]); - ws.onclose = () => { - console.log('WebSocket closed'); - handleReconnect(); - }; + const connectWebSocket = useCallback(() => { + if (wsRef.current?.readyState === WebSocket.CONNECTING) { + console.log('WebSocket connection already in progress'); + return; + } + + console.log('Connecting to WebSocket:', wsUrl); + const ws = new WebSocket(wsUrl); + wsRef.current = ws; + + ws.onopen = () => { + console.log('WebSocket connected successfully'); + setConnectionState('connected'); + setReconnectAttempts(0); }; - const handleReconnect = () => { - if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { - console.log(`Reconnecting... Attempt ${reconnectAttempts + 1}`); - setTimeout(() => { - reconnectAttempts++; - connect(); - }, RECONNECT_INTERVAL); - } else { - console.error('Max reconnection attempts reached'); - setConnectionState('disconnected'); - } + ws.onerror = error => { + console.error('WebSocket error:', error); + setConnectionState('disconnected'); + handleReconnect(); + }; + + ws.onclose = event => { + console.log('WebSocket closed:', event); + setConnectionState('disconnected'); + handleReconnect(); }; - connect(); - }, [wsUrl]); + // 연결 타임아웃 설정 + const connectionTimeout = setTimeout(() => { + if (ws.readyState === WebSocket.CONNECTING) { + console.log('Connection timeout, closing socket'); + ws.close(); + handleReconnect(); + } + }, 10000); + + return () => { + clearTimeout(connectionTimeout); + if (ws.readyState === WebSocket.OPEN) { + ws.close(); + } + }; + }, [wsUrl, handleReconnect]); useEffect(() => { connectWebSocketRef.current = connectWebSocket; @@ -332,31 +359,6 @@ const LiveClass: React.FC = ({ } }; - const handleEndClass = useCallback(() => { - producersRef.current.forEach(producer => producer.close()); - producersRef.current.clear(); - - consumersRef.current.forEach(consumer => consumer.close()); - consumersRef.current.clear(); - - producerTransportRef.current?.close(); - consumerTransportRef.current?.close(); - - if (localStreamRef.current) { - localStreamRef.current.getTracks().forEach(track => track.stop()); - } - if (screenStreamRef.current) { - screenStreamRef.current.getTracks().forEach(track => track.stop()); - } - - wsRef.current?.close(); - - setClassStarted(false); - setStreams({}); - setConnectionState('disconnected'); - setIsSharingScreen(false); - }, []); - const subscribeToTrack = async ( producerId: string, producerUserId: number @@ -411,21 +413,6 @@ const LiveClass: React.FC = ({ [userId] ); - const handleReconnect = useCallback((): void => { - if (reconnectAttempts < 5) { - const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000); - console.log(`Reconnecting (${reconnectAttempts + 1}/5) in ${delay}ms`); - - setTimeout(() => { - setReconnectAttempts(prev => prev + 1); - connectWebSocketRef.current?.(); - }, delay); - } else { - console.error('Max reconnection attempts reached'); - handleEndClass(); - } - }, [reconnectAttempts, handleEndClass]); - useEffect(() => { handleReconnectRef.current = handleReconnect; }, [handleReconnect]);