From 7747f59060bfee01488159d48c64babb45acfd4b Mon Sep 17 00:00:00 2001 From: Bas van den Aakster Date: Fri, 12 Dec 2025 21:35:34 +0100 Subject: [PATCH] Fix: Use ondatachannel instead of createDataChannel for answerer CRITICAL BUG FIX: As the answerer, we should NOT create our own data channel. The host (offerer) creates the channel, and we receive it via ondatachannel event. This was causing messages to be sent on a different channel than the one the host was listening to, so no messages were being received. Changes: - Remove pc.createDataChannel() call - Add pc.ondatachannel event handler - Wrap data channel setup in setupDataChannel() function - Called when channel is received from host --- test-connect.js | 144 +++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 70 deletions(-) diff --git a/test-connect.js b/test-connect.js index 6a90c3d..6c9ca6d 100644 --- a/test-connect.js +++ b/test-connect.js @@ -82,84 +82,88 @@ async function main() { console.log('\n3. Creating WebRTC peer connection...') const pc = new RTCPeerConnection(RTC_CONFIG) - // 4. Create data channel - console.log('4. Creating data channel...') - const dc = pc.createDataChannel('chat') - - // Set up data channel handlers + // 4. Wait for data channel (we're the answerer, host creates the channel) + console.log('4. Waiting for data channel from host...') + let dc = null let identified = false - dc.onopen = () => { - console.log(' āœ“ Data channel opened!') - console.log(` Data channel state: ${dc.readyState}`) + // Function to setup data channel handlers + const setupDataChannel = (channel) => { + dc = channel - // Longer delay to ensure both sides are ready - setTimeout(() => { - console.log(` Data channel state before send: ${dc.readyState}`) - if (dc.readyState !== 'open') { - console.error(` āŒ Data channel not open: ${dc.readyState}`) - return + dc.onopen = () => { + console.log(' āœ“ Data channel opened!') + console.log(` Data channel state: ${dc.readyState}`) + + // Longer delay to ensure both sides are ready + setTimeout(() => { + console.log(` Data channel state before send: ${dc.readyState}`) + if (dc.readyState !== 'open') { + console.error(` āŒ Data channel not open: ${dc.readyState}`) + return + } + + // Send identify message (demo protocol) + console.log(`šŸ“¤ Sending identify message...`) + const identifyMsg = JSON.stringify({ + type: 'identify', + from: rondevu.getUsername() + }) + console.log(` Message:`, identifyMsg) + dc.send(identifyMsg) + console.log(` āœ“ Identify message sent, bufferedAmount: ${dc.bufferedAmount}`) + }, 500) + } + + dc.onclose = () => { + console.log(' āŒ Data channel closed!') + } + + dc.onmessage = (event) => { + console.log(`šŸ“„ RAW DATA:`, event.data) + try { + const msg = JSON.parse(event.data) + console.log(`šŸ“„ Parsed message:`, JSON.stringify(msg, null, 2)) + + if (msg.type === 'identify_ack' && !identified) { + identified = true + console.log(`āœ… Connection acknowledged by @${msg.from}`) + + // Now send the actual chat message + console.log(`šŸ“¤ Sending chat message: "${MESSAGE}"`) + dc.send(JSON.stringify({ + type: 'message', + text: MESSAGE + })) + + // Keep connection open longer to see if we get a response + setTimeout(() => { + console.log('\nāœ… Test completed successfully!') + dc.close() + pc.close() + process.exit(0) + }, 5000) + } else if (msg.type === 'message') { + console.log(`šŸ’¬ @${msg.from || 'peer'}: ${msg.text}`) + } else { + console.log(`šŸ“„ Unknown message type: ${msg.type}`) + } + } catch (err) { + console.log(`šŸ“„ Parse error:`, err.message) + console.log(`šŸ“„ Raw data was:`, event.data) } + } - // Send identify message (demo protocol) - console.log(`šŸ“¤ Sending identify message...`) - const identifyMsg = JSON.stringify({ - type: 'identify', - from: rondevu.getUsername() - }) - console.log(` Message:`, identifyMsg) - dc.send(identifyMsg) - console.log(` āœ“ Identify message sent, bufferedAmount: ${dc.bufferedAmount}`) - }, 500) - } - - dc.onclose = () => { - console.log(' āŒ Data channel closed!') - } - - dc.onerror = (error) => { - console.error('āŒ Data channel error:', error) - process.exit(1) - } - - dc.onmessage = (event) => { - console.log(`šŸ“„ RAW DATA:`, event.data) - try { - const msg = JSON.parse(event.data) - console.log(`šŸ“„ Parsed message:`, JSON.stringify(msg, null, 2)) - - if (msg.type === 'identify_ack' && !identified) { - identified = true - console.log(`āœ… Connection acknowledged by @${msg.from}`) - - // Now send the actual chat message - console.log(`šŸ“¤ Sending chat message: "${MESSAGE}"`) - dc.send(JSON.stringify({ - type: 'message', - text: MESSAGE - })) - - // Keep connection open longer to see if we get a response - setTimeout(() => { - console.log('\nāœ… Test completed successfully!') - dc.close() - pc.close() - process.exit(0) - }, 5000) - } else if (msg.type === 'message') { - console.log(`šŸ’¬ @${msg.from || 'peer'}: ${msg.text}`) - } else { - console.log(`šŸ“„ Unknown message type: ${msg.type}`) - } - } catch (err) { - console.log(`šŸ“„ Parse error:`, err.message) - console.log(`šŸ“„ Raw data was:`, event.data) + dc.onerror = (error) => { + console.error('āŒ Data channel error:', error) + process.exit(1) } } - dc.onerror = (error) => { - console.error('āŒ Data channel error:', error) - process.exit(1) + // Receive data channel from host (we're the answerer) + pc.ondatachannel = (event) => { + console.log(' āœ“ Data channel received from host!') + setupDataChannel(event.channel) } // 5. Set up ICE candidate exchange FIRST