11'use client' ;
22
3- import React , { useRef , useState , useEffect } from 'react' ;
3+ import React , { useRef , useState } from 'react' ;
44import io , { Socket } from 'socket.io-client' ;
55import SimplePeer , { Instance } from 'simple-peer' ;
66import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
@@ -15,59 +15,38 @@ const AudioSharing = () => {
1515 const [ connectionStatus , setConnectionStatus ] = useState <
1616 'Not Connected' | 'Connecting' | 'Connected'
1717 > ( 'Not Connected' ) ;
18-
19- // Use refs for persistent state across remounts
2018 const socketRef = useRef < Socket | null > ( null ) ;
2119 const peerRef = useRef < Instance | null > ( null ) ;
2220 const audioStreamRef = useRef < MediaStream | null > ( null ) ;
23- const audioElementsRef = useRef < HTMLAudioElement [ ] > ( [ ] ) ;
24- const mountCountRef = useRef ( 0 ) ;
25- const lastCleanupTimeRef = useRef ( 0 ) ;
21+ const initializedRef = useRef ( false ) ;
2622
27- // Constants
28- const CLEANUP_THRESHOLD = 1000 ; // Minimum time between cleanups in ms
2923 const SERVER_URL =
3024 process . env . NEXT_PUBLIC_AUDIO_SERVER_URL || 'http://localhost:5555' ;
25+
26+ // Add TURN server credentials from environment variables
3127 const TURN_SERVER = process . env . NEXT_PUBLIC_TURN_SERVER || '' ;
3228 const TURN_USERNAME = process . env . NEXT_PUBLIC_TURN_USERNAME ;
3329 const TURN_CREDENTIAL = process . env . NEXT_PUBLIC_TURN_PASSWORD ;
3430
35- const cleanupAudio = ( force = false ) => {
36- const now = Date . now ( ) ;
37-
38- // Prevent rapid cleanup unless forced
39- if ( ! force && now - lastCleanupTimeRef . current < CLEANUP_THRESHOLD ) {
40- console . log ( 'Skipping cleanup due to threshold' ) ;
41- return ;
42- }
43-
44- console . log ( 'Cleaning up audio connections...' ) ;
45- lastCleanupTimeRef . current = now ;
46-
31+ if ( ! TURN_SERVER || ! TURN_USERNAME || ! TURN_CREDENTIAL ) {
32+ // Log which specific TURN variables are missing
33+ console . error ( 'Missing TURN env:' , {
34+ server : ! ! TURN_SERVER ,
35+ username : ! ! TURN_USERNAME ,
36+ credential : ! ! TURN_CREDENTIAL ,
37+ } ) ;
38+ }
39+ const cleanupAudio = ( ) => {
4740 if ( audioStreamRef . current ) {
4841 audioStreamRef . current . getTracks ( ) . forEach ( ( track ) => {
4942 track . stop ( ) ;
5043 } ) ;
5144 audioStreamRef . current = null ;
5245 }
53-
5446 if ( peerRef . current ) {
5547 peerRef . current . destroy ( ) ;
5648 peerRef . current = null ;
5749 }
58-
59- // Only disconnect socket if we're actually cleaning up (not remounting)
60- if ( force && socketRef . current ) {
61- socketRef . current . disconnect ( ) ;
62- socketRef . current = null ;
63- }
64-
65- audioElementsRef . current . forEach ( ( audio ) => {
66- audio . pause ( ) ;
67- audio . srcObject = null ;
68- } ) ;
69- audioElementsRef . current = [ ] ;
70-
7150 setIsAudioEnabled ( false ) ;
7251 setConnectionStatus ( 'Not Connected' ) ;
7352 } ;
@@ -82,8 +61,10 @@ const AudioSharing = () => {
8261 trickle : false ,
8362 config : {
8463 iceServers : [
64+ // Maintain existing STUN servers
8565 { urls : 'stun:stun.l.google.com:19302' } ,
8666 { urls : 'stun:global.stun.twilio.com:3478' } ,
67+ // Add TURN server configuration
8768 {
8869 urls : TURN_SERVER ,
8970 username : TURN_USERNAME ,
@@ -94,45 +75,42 @@ const AudioSharing = () => {
9475 } ) ;
9576
9677 peer . on ( 'signal' , ( data : SignalData ) => {
78+ console . log ( 'Sending signal data:' , data ) ;
9779 socketRef . current ?. emit ( 'signal' , data ) ;
9880 } ) ;
9981
10082 peer . on ( 'stream' , ( remoteStream : MediaStream ) => {
10183 console . log ( 'Received remote stream' ) ;
10284 const audio = new Audio ( ) ;
10385 audio . srcObject = remoteStream ;
104- audioElementsRef . current . push ( audio ) ;
10586 audio
10687 . play ( )
10788 . catch ( ( error ) => console . error ( 'Error playing audio:' , error ) ) ;
10889 } ) ;
10990
11091 peer . on ( 'error' , ( err : Error ) => {
11192 console . error ( 'Peer connection error:' , err ) ;
112- cleanupAudio ( true ) ;
93+ cleanupAudio ( ) ;
11394 } ) ;
11495
11596 peer . on ( 'close' , ( ) => {
11697 console . log ( 'Peer connection closed' ) ;
117- cleanupAudio ( true ) ;
98+ cleanupAudio ( ) ;
11899 } ) ;
119100
101+ // Add connection state logging
120102 peer . on ( 'connect' , ( ) => {
121- console . log ( 'Peer connection established' ) ;
103+ console . log ( 'Peer connection established successfully ' ) ;
122104 setConnectionStatus ( 'Connected' ) ;
123105 } ) ;
124106
125107 return peer ;
126108 } ;
127109
128110 const initializeSocketAndPeer = ( ) => {
129- // If socket exists and is connected, reuse it
130- if ( socketRef . current ?. connected ) {
131- console . log ( 'Reusing existing socket connection' ) ;
132- return ;
133- }
111+ if ( initializedRef . current ) return ;
112+ initializedRef . current = true ;
134113
135- console . log ( 'Initializing new socket connection' ) ;
136114 socketRef . current = io ( SERVER_URL , {
137115 transports : [ 'websocket' ] ,
138116 path : '/socket.io/' ,
@@ -147,10 +125,12 @@ const AudioSharing = () => {
147125
148126 socketRef . current . on ( 'connect_error' , ( error : Error ) => {
149127 console . error ( 'Connection error:' , error ) ;
150- cleanupAudio ( true ) ;
128+ cleanupAudio ( ) ;
151129 } ) ;
152130
153131 socketRef . current . on ( 'signal' , async ( data : SignalData ) => {
132+ console . log ( 'Received signal data:' , data ) ;
133+
154134 if ( data . type === 'offer' && ! peerRef . current ) {
155135 try {
156136 const stream = await navigator . mediaDevices . getUserMedia ( {
@@ -167,7 +147,7 @@ const AudioSharing = () => {
167147 peerRef . current = createPeer ( stream , false ) ;
168148 } catch ( error ) {
169149 console . error ( 'Error accessing audio devices:' , error ) ;
170- cleanupAudio ( true ) ;
150+ cleanupAudio ( ) ;
171151 }
172152 }
173153
@@ -176,7 +156,7 @@ const AudioSharing = () => {
176156 peerRef . current . signal ( data as SimplePeer . SignalData ) ;
177157 } catch ( error ) {
178158 console . error ( 'Error signaling peer:' , error ) ;
179- cleanupAudio ( true ) ;
159+ cleanupAudio ( ) ;
180160 }
181161 }
182162 } ) ;
@@ -211,39 +191,10 @@ const AudioSharing = () => {
211191 }
212192 } catch ( error ) {
213193 console . error ( 'Error toggling audio:' , error ) ;
214- cleanupAudio ( true ) ;
194+ cleanupAudio ( ) ;
215195 }
216196 } ;
217197
218- // Mount/unmount handling
219- useEffect ( ( ) => {
220- mountCountRef . current ++ ;
221- console . log ( `Component mounted (count: ${ mountCountRef . current } )` ) ;
222-
223- // Only do full cleanup when actually leaving the page
224- return ( ) => {
225- mountCountRef . current -- ;
226- console . log ( `Component unmounting (count: ${ mountCountRef . current } )` ) ;
227-
228- // If this is the last mount point, do a full cleanup
229- if ( mountCountRef . current === 0 ) {
230- cleanupAudio ( true ) ;
231- }
232- } ;
233- } , [ ] ) ;
234-
235- // Handle page unload
236- useEffect ( ( ) => {
237- const handleUnload = ( ) => {
238- cleanupAudio ( true ) ;
239- } ;
240-
241- window . addEventListener ( 'beforeunload' , handleUnload ) ;
242- return ( ) => {
243- window . removeEventListener ( 'beforeunload' , handleUnload ) ;
244- } ;
245- } , [ ] ) ;
246-
247198 return (
248199 < div className = "flex items-center gap-4" >
249200 < button
0 commit comments