diff --git a/src/peer/answering-state.ts b/src/peer/answering-state.ts index 600bfc0..a14dd7f 100644 --- a/src/peer/answering-state.ts +++ b/src/peer/answering-state.ts @@ -23,16 +23,16 @@ export class AnsweringState extends PeerState { sdp: offerSdp }); + // Enable trickle ICE - set up handler before ICE gathering starts + this.setupIceCandidateHandler(); + // Create answer const answer = await this.peer.pc.createAnswer(); - await this.peer.pc.setLocalDescription(answer); + await this.peer.pc.setLocalDescription(answer); // ICE gathering starts here // Send answer to server immediately (don't wait for ICE) await this.peer.offersApi.answer(offerId, answer.sdp!); - // Enable trickle ICE - send candidates as they arrive - this.setupIceCandidateHandler(offerId); - // Transition to exchanging ICE const { ExchangingIceState } = await import('./exchanging-ice-state.js'); this.peer.setState(new ExchangingIceState(this.peer, offerId, options)); diff --git a/src/peer/creating-offer-state.ts b/src/peer/creating-offer-state.ts index b6b4e81..2dc1bcf 100644 --- a/src/peer/creating-offer-state.ts +++ b/src/peer/creating-offer-state.ts @@ -24,9 +24,13 @@ export class CreatingOfferState extends PeerState { this.peer.emitEvent('datachannel', channel); } + // Enable trickle ICE - set up handler before ICE gathering starts + // Handler will check this.peer.offerId before sending + this.setupIceCandidateHandler(); + // Create WebRTC offer const offer = await this.peer.pc.createOffer(); - await this.peer.pc.setLocalDescription(offer); + await this.peer.pc.setLocalDescription(offer); // ICE gathering starts here // Send offer to server immediately (don't wait for ICE) const offers = await this.peer.offersApi.create([{ @@ -36,10 +40,7 @@ export class CreatingOfferState extends PeerState { }]); const offerId = offers[0].id; - this.peer.offerId = offerId; - - // Enable trickle ICE - send candidates as they arrive - this.setupIceCandidateHandler(offerId); + this.peer.offerId = offerId; // Now handler can send candidates // Transition to waiting for answer const { WaitingForAnswerState } = await import('./waiting-for-answer-state.js'); diff --git a/src/peer/state.ts b/src/peer/state.ts index 6a27644..6ea8e68 100644 --- a/src/peer/state.ts +++ b/src/peer/state.ts @@ -35,13 +35,13 @@ export abstract class PeerState { * Setup trickle ICE candidate handler * Sends local ICE candidates to server as they are discovered */ - protected setupIceCandidateHandler(offerId: string): void { + protected setupIceCandidateHandler(): void { this.iceCandidateHandler = async (event: RTCPeerConnectionIceEvent) => { - if (event.candidate && offerId) { + if (event.candidate && this.peer.offerId) { const candidateData = event.candidate.toJSON(); if (candidateData.candidate && candidateData.candidate !== '') { try { - await this.peer.offersApi.addIceCandidates(offerId, [candidateData]); + await this.peer.offersApi.addIceCandidates(this.peer.offerId, [candidateData]); } catch (err) { console.error('Error sending ICE candidate:', err); }