From 3ce117774b547ec2ebd47e29d970ffadeab8753a Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 14 Sep 2023 12:19:06 +0200 Subject: [PATCH 1/6] patch up reconnect logic --- src/room/RTCEngine.ts | 32 ++++++++++++++++++++++++++++---- src/room/Room.ts | 21 +++++++++++++++++---- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/room/RTCEngine.ts b/src/room/RTCEngine.ts index 5272a5e353..6f7453055e 100644 --- a/src/room/RTCEngine.ts +++ b/src/room/RTCEngine.ts @@ -418,6 +418,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit const shouldEmit = this.pcState === PCState.New; this.pcState = PCState.Connected; if (shouldEmit) { + console.warn('primary connected, emitting'); this.emit(EngineEvent.Connected, joinResponse); } } else if (primaryPC.connectionState === 'failed') { @@ -435,9 +436,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } }; secondaryPC.onconnectionstatechange = async () => { - log.debug(`secondary PC state changed ${secondaryPC.connectionState}`); + log.warn(`secondary PC state changed ${secondaryPC.connectionState}`); // also reconnect if secondary peerconnection fails if (secondaryPC.connectionState === 'failed') { + log.warn('issuing reconnect for secondary PC failed'); this.handleDisconnect( 'secondary peerconnection', subscriberPrimary @@ -1084,7 +1086,16 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit log.debug('waiting for peer connection to reconnect'); while (now - startTime < this.peerConnectionTimeout) { + const needsPublisherPC = this.hasPublished && this.subscriberPrimary; + console.log( + 'needs publisher', + needsPublisherPC, + this.hasPublished, + this.subscriberPrimary, + this.publisher?.pc.connectionState, + ); if (this.primaryPC === undefined) { + console.warn('primary missing, connection hosed'); // we can abort early, connection is hosed break; } else if ( @@ -1092,11 +1103,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit // this means we'd have to check its status manually and update address // manually now - startTime > minReconnectWait && - this.primaryPC?.connectionState === 'connected' + this.primaryPC?.connectionState === 'connected' && + (!needsPublisherPC || this.publisher?.pc.connectionState === 'connected') ) { this.pcState = PCState.Connected; - } - if (this.pcState === PCState.Connected) { return; } await sleep(100); @@ -1205,32 +1215,46 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit /* @internal */ verifyTransport(): boolean { + console.log( + 'verifying transport', + this.hasPublished, + this.primaryPC?.connectionState, + this.publisher?.pc.connectionState, + ); // primary connection if (!this.primaryPC) { + log.warn('no primary PC'); return false; } if ( this.primaryPC.connectionState === 'closed' || this.primaryPC.connectionState === 'failed' ) { + log.warn('primary pc connectionState issue', { + state: this.primaryPC.connectionState, + subPrimary: this.subscriberPrimary, + }); return false; } // also verify publisher connection if it's needed or different if (this.hasPublished && this.subscriberPrimary) { if (!this.publisher) { + log.warn('publisher not present'); return false; } if ( this.publisher.pc.connectionState === 'closed' || this.publisher.pc.connectionState === 'failed' ) { + log.warn('publisher connection state issue', { state: this.publisher.pc.connectionState }); return false; } } // ensure signal is connected if (!this.client.ws || this.client.ws.readyState === WebSocket.CLOSED) { + log.warn('signal not connected'); return false; } return true; diff --git a/src/room/Room.ts b/src/room/Room.ts index a18a329af4..b7e96b293a 100644 --- a/src/room/Room.ts +++ b/src/room/Room.ts @@ -294,6 +294,7 @@ class Room extends (EventEmitter as new () => TypedEmitter) .on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate) .on(EngineEvent.DataPacketReceived, this.handleDataPacket) .on(EngineEvent.Resuming, () => { + console.log("we're resuming"); this.clearConnectionReconcile(); if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) { this.emit(RoomEvent.Reconnecting); @@ -1119,9 +1120,12 @@ class Room extends (EventEmitter as new () => TypedEmitter) // reconnection failed, handleDisconnect is being invoked already, just return here return; } - this.setAndEmitConnectionState(ConnectionState.Connected); - this.emit(RoomEvent.Reconnected); - this.registerConnectionReconcile(); + // only set as connected if _only_ the signal connection had been severed + if (this.engine.verifyTransport()) { + this.setAndEmitConnectionState(ConnectionState.Connected); + this.emit(RoomEvent.Reconnected); + this.registerConnectionReconcile(); + } // emit participant connected events after connection has been re-established this.participants.forEach((participant) => { @@ -1605,9 +1609,17 @@ class Room extends (EventEmitter as new () => TypedEmitter) } private registerConnectionReconcile() { + let stackError: string | undefined; + try { + throw new Error(); + } catch (e) { + stackError = (e as Error).stack; + } this.clearConnectionReconcile(); + console.log('registering connection reconcile', { stackError }); + let consecutiveFailures = 0; - this.connectionReconcileInterval = CriticalTimers.setInterval(() => { + this.connectionReconcileInterval = setInterval(() => { if ( // ensure we didn't tear it down !this.engine || @@ -1633,6 +1645,7 @@ class Room extends (EventEmitter as new () => TypedEmitter) private clearConnectionReconcile() { if (this.connectionReconcileInterval) { + console.log('clearing connection reconcile'); CriticalTimers.clearInterval(this.connectionReconcileInterval); } } From 8794dabb98ffa568823100eb65c157ef9ca442a7 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 14 Sep 2023 16:08:13 +0200 Subject: [PATCH 2/6] all reconnect scenarios working --- src/room/RTCEngine.ts | 79 +++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/src/room/RTCEngine.ts b/src/room/RTCEngine.ts index 6f7453055e..0f344104e6 100644 --- a/src/room/RTCEngine.ts +++ b/src/room/RTCEngine.ts @@ -63,7 +63,7 @@ const reliableDataChannel = '_reliable'; const minReconnectWait = 2 * 1000; const leaveReconnect = 'leave-reconnect'; -enum PCState { +enum EngineState { New, Connected, Disconnected, @@ -110,7 +110,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit private primaryPC?: RTCPeerConnection; - private pcState: PCState = PCState.New; + private engineState: EngineState = EngineState.New; private _isClosed: boolean = true; @@ -120,7 +120,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit // true if publisher connection has already been established. // this is helpful to know if we need to restart ICE on the publisher connection - private hasPublished: boolean = false; + private needsPublisher: boolean = false; // keep join info around for reconnect, this could be a region url private url?: string; @@ -200,13 +200,17 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this._isClosed = false; this.latestJoinResponse = joinResponse; + this.engineState = EngineState.New; this.subscriberPrimary = joinResponse.subscriberPrimary; if (!this.publisher) { + console.log('configuring publisher'); this.configure(joinResponse); } // create offer - if (!this.subscriberPrimary) { + if (!this.subscriberPrimary || this.needsPublisher) { + console.log('negotiate'); + this.negotiate(); } @@ -241,6 +245,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.clearPendingReconnect(); await this.cleanupPeerConnections(); await this.cleanupClient(); + this.engineState = EngineState.Closed; } finally { unlock(); } @@ -415,17 +420,18 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit primaryPC.onconnectionstatechange = async () => { log.debug(`primary PC state changed ${primaryPC.connectionState}`); if (primaryPC.connectionState === 'connected') { - const shouldEmit = this.pcState === PCState.New; - this.pcState = PCState.Connected; - if (shouldEmit) { - console.warn('primary connected, emitting'); + const initialFullConnection = + (this.engineState === EngineState.New && !this.needsPublisher) || + this.publisher?.pc.connectionState === 'connected'; + if (initialFullConnection) { + this.engineState = EngineState.Connected; this.emit(EngineEvent.Connected, joinResponse); } } else if (primaryPC.connectionState === 'failed') { // on Safari, PeerConnection will switch to 'disconnected' during renegotiation - if (this.pcState === PCState.Connected) { - this.pcState = PCState.Disconnected; - + if (this.engineState === EngineState.Connected) { + this.engineState = EngineState.Disconnected; + console.log('primary failed'); this.handleDisconnect( 'primary peerconnection', subscriberPrimary @@ -436,6 +442,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } }; secondaryPC.onconnectionstatechange = async () => { + if (secondaryPC.connectionState === 'connected') { + const initialFullConnection = + this.engineState === EngineState.New && primaryPC.connectionState === 'connected'; + if (initialFullConnection) { + this.engineState = EngineState.Connected; + this.emit(EngineEvent.Connected, joinResponse); + } + } log.warn(`secondary PC state changed ${secondaryPC.connectionState}`); // also reconnect if secondary peerconnection fails if (secondaryPC.connectionState === 'failed') { @@ -514,6 +528,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit }; this.client.onClose = () => { + console.log('signal closed, disconnect engine'); this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED); }; @@ -901,6 +916,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } if (recoverable) { + console.log('recoverable, disconnect first', e); this.handleDisconnect('reconnect', ReconnectReason.RR_UNKNOWN); } else { log.info( @@ -941,6 +957,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit await this.client.sendLeave(); } await this.cleanupPeerConnections(); + this.engineState = EngineState.Closed; await this.cleanupClient(); let joinResponse: JoinResponse; @@ -959,6 +976,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } if (this.shouldFailNext) { + console.warn('should fail'); this.shouldFailNext = false; throw new Error('simulated failure'); } @@ -966,7 +984,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.client.setReconnected(); this.emit(EngineEvent.SignalRestarted, joinResponse); - await this.waitForPCReconnected(); + await this.waitForPCInitialConnection(); this.regionUrlProvider?.resetAttempts(); // reconnect success this.emit(EngineEvent.Restarted); @@ -1015,6 +1033,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit throw new SignalReconnectError(message); } this.emit(EngineEvent.SignalResumed); + console.log('signal resumed'); if (this.shouldFailNext) { this.shouldFailNext = false; @@ -1024,10 +1043,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.subscriber.restartingIce = true; // only restart publisher if it's needed - if (this.hasPublished) { + if (this.needsPublisher) { + console.warn('needs publisher'); await this.publisher.createAndSendOffer({ iceRestart: true }); + } else { + console.warn('does not need publisher'); } + console.log('waiting for pc reconnect', this.needsPublisher); await this.waitForPCReconnected(); this.client.setReconnected(); @@ -1042,10 +1065,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } async waitForPCInitialConnection(timeout?: number, abortController?: AbortController) { - if (this.pcState === PCState.Connected) { + if (this.engineState === EngineState.Connected) { + console.log('already connected!!!!!'); return; } - if (this.pcState !== PCState.New) { + if (this.engineState !== EngineState.New) { throw new UnexpectedConnectionState( 'Expected peer connection to be new on initial connection', ); @@ -1082,18 +1106,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit private async waitForPCReconnected() { const startTime = Date.now(); let now = startTime; - this.pcState = PCState.Reconnecting; + this.engineState = EngineState.Reconnecting; log.debug('waiting for peer connection to reconnect'); while (now - startTime < this.peerConnectionTimeout) { - const needsPublisherPC = this.hasPublished && this.subscriberPrimary; - console.log( - 'needs publisher', - needsPublisherPC, - this.hasPublished, - this.subscriberPrimary, - this.publisher?.pc.connectionState, - ); + console.log(this.publisher?.pc); if (this.primaryPC === undefined) { console.warn('primary missing, connection hosed'); // we can abort early, connection is hosed @@ -1104,9 +1121,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit // manually now - startTime > minReconnectWait && this.primaryPC?.connectionState === 'connected' && - (!needsPublisherPC || this.publisher?.pc.connectionState === 'connected') + (!this.needsPublisher || this.publisher?.pc.connectionState === 'connected') ) { - this.pcState = PCState.Connected; + this.engineState = EngineState.Connected; return; } await sleep(100); @@ -1119,7 +1136,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit waitForRestarted = () => { return new Promise((resolve, reject) => { - if (this.pcState === PCState.Connected) { + if (this.engineState === EngineState.Connected) { resolve(); } const onRestarted = () => { @@ -1217,7 +1234,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit verifyTransport(): boolean { console.log( 'verifying transport', - this.hasPublished, + this.needsPublisher, this.primaryPC?.connectionState, this.publisher?.pc.connectionState, ); @@ -1238,7 +1255,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } // also verify publisher connection if it's needed or different - if (this.hasPublished && this.subscriberPrimary) { + if (this.needsPublisher && this.subscriberPrimary) { if (!this.publisher) { log.warn('publisher not present'); return false; @@ -1269,7 +1286,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit return; } - this.hasPublished = true; + this.needsPublisher = true; const handleClosed = () => { log.debug('engine disconnected while negotiation was ongoing'); @@ -1285,6 +1302,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit const negotiationTimeout = setTimeout(() => { reject('negotiation timed out'); + console.log('negotiation timeout'); this.handleDisconnect('negotiation', ReconnectReason.RR_SIGNAL_DISCONNECTED); }, this.peerConnectionTimeout); @@ -1317,6 +1335,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit if (e instanceof NegotiationError) { this.fullReconnectOnNext = true; } + console.log('publisher negotiation error'); this.handleDisconnect('negotiation', ReconnectReason.RR_UNKNOWN); }); }); From 44e4a2981e0ee6b081eb324132411ad16ba3ee7d Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 14 Sep 2023 16:24:12 +0200 Subject: [PATCH 3/6] cleanup --- src/room/RTCEngine.ts | 63 ++++++++++++------------------------------- 1 file changed, 17 insertions(+), 46 deletions(-) diff --git a/src/room/RTCEngine.ts b/src/room/RTCEngine.ts index 0f344104e6..21c5534f5d 100644 --- a/src/room/RTCEngine.ts +++ b/src/room/RTCEngine.ts @@ -63,7 +63,7 @@ const reliableDataChannel = '_reliable'; const minReconnectWait = 2 * 1000; const leaveReconnect = 'leave-reconnect'; -enum EngineState { +enum PCState { New, Connected, Disconnected, @@ -110,7 +110,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit private primaryPC?: RTCPeerConnection; - private engineState: EngineState = EngineState.New; + private pcState: PCState = PCState.New; private _isClosed: boolean = true; @@ -200,17 +200,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this._isClosed = false; this.latestJoinResponse = joinResponse; - this.engineState = EngineState.New; + this.pcState = PCState.New; this.subscriberPrimary = joinResponse.subscriberPrimary; if (!this.publisher) { - console.log('configuring publisher'); this.configure(joinResponse); } // create offer if (!this.subscriberPrimary || this.needsPublisher) { - console.log('negotiate'); - this.negotiate(); } @@ -245,7 +242,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.clearPendingReconnect(); await this.cleanupPeerConnections(); await this.cleanupClient(); - this.engineState = EngineState.Closed; + this.pcState = PCState.Closed; } finally { unlock(); } @@ -274,6 +271,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } this.primaryPC = undefined; + this.pcState = PCState.Closed; const dcCleanup = (dc: RTCDataChannel | undefined) => { if (!dc) return; @@ -421,17 +419,16 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit log.debug(`primary PC state changed ${primaryPC.connectionState}`); if (primaryPC.connectionState === 'connected') { const initialFullConnection = - (this.engineState === EngineState.New && !this.needsPublisher) || + (this.pcState === PCState.New && !this.needsPublisher) || this.publisher?.pc.connectionState === 'connected'; if (initialFullConnection) { - this.engineState = EngineState.Connected; + this.pcState = PCState.Connected; this.emit(EngineEvent.Connected, joinResponse); } } else if (primaryPC.connectionState === 'failed') { // on Safari, PeerConnection will switch to 'disconnected' during renegotiation - if (this.engineState === EngineState.Connected) { - this.engineState = EngineState.Disconnected; - console.log('primary failed'); + if (this.pcState === PCState.Connected) { + this.pcState = PCState.Disconnected; this.handleDisconnect( 'primary peerconnection', subscriberPrimary @@ -444,9 +441,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit secondaryPC.onconnectionstatechange = async () => { if (secondaryPC.connectionState === 'connected') { const initialFullConnection = - this.engineState === EngineState.New && primaryPC.connectionState === 'connected'; + this.pcState === PCState.New && primaryPC.connectionState === 'connected'; if (initialFullConnection) { - this.engineState = EngineState.Connected; + this.pcState = PCState.Connected; this.emit(EngineEvent.Connected, joinResponse); } } @@ -528,7 +525,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit }; this.client.onClose = () => { - console.log('signal closed, disconnect engine'); this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED); }; @@ -916,7 +912,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } if (recoverable) { - console.log('recoverable, disconnect first', e); this.handleDisconnect('reconnect', ReconnectReason.RR_UNKNOWN); } else { log.info( @@ -957,7 +952,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit await this.client.sendLeave(); } await this.cleanupPeerConnections(); - this.engineState = EngineState.Closed; + this.pcState = PCState.Closed; await this.cleanupClient(); let joinResponse: JoinResponse; @@ -976,7 +971,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } if (this.shouldFailNext) { - console.warn('should fail'); this.shouldFailNext = false; throw new Error('simulated failure'); } @@ -1033,7 +1027,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit throw new SignalReconnectError(message); } this.emit(EngineEvent.SignalResumed); - console.log('signal resumed'); if (this.shouldFailNext) { this.shouldFailNext = false; @@ -1044,13 +1037,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit // only restart publisher if it's needed if (this.needsPublisher) { - console.warn('needs publisher'); await this.publisher.createAndSendOffer({ iceRestart: true }); - } else { - console.warn('does not need publisher'); } - console.log('waiting for pc reconnect', this.needsPublisher); await this.waitForPCReconnected(); this.client.setReconnected(); @@ -1065,11 +1054,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } async waitForPCInitialConnection(timeout?: number, abortController?: AbortController) { - if (this.engineState === EngineState.Connected) { - console.log('already connected!!!!!'); + if (this.pcState === PCState.Connected) { return; } - if (this.engineState !== EngineState.New) { + if (this.pcState !== PCState.New) { throw new UnexpectedConnectionState( 'Expected peer connection to be new on initial connection', ); @@ -1106,11 +1094,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit private async waitForPCReconnected() { const startTime = Date.now(); let now = startTime; - this.engineState = EngineState.Reconnecting; + this.pcState = PCState.Reconnecting; log.debug('waiting for peer connection to reconnect'); while (now - startTime < this.peerConnectionTimeout) { - console.log(this.publisher?.pc); if (this.primaryPC === undefined) { console.warn('primary missing, connection hosed'); // we can abort early, connection is hosed @@ -1123,7 +1110,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.primaryPC?.connectionState === 'connected' && (!this.needsPublisher || this.publisher?.pc.connectionState === 'connected') ) { - this.engineState = EngineState.Connected; + this.pcState = PCState.Connected; return; } await sleep(100); @@ -1136,7 +1123,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit waitForRestarted = () => { return new Promise((resolve, reject) => { - if (this.engineState === EngineState.Connected) { + if (this.pcState === PCState.Connected) { resolve(); } const onRestarted = () => { @@ -1232,46 +1219,32 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit /* @internal */ verifyTransport(): boolean { - console.log( - 'verifying transport', - this.needsPublisher, - this.primaryPC?.connectionState, - this.publisher?.pc.connectionState, - ); // primary connection if (!this.primaryPC) { - log.warn('no primary PC'); return false; } if ( this.primaryPC.connectionState === 'closed' || this.primaryPC.connectionState === 'failed' ) { - log.warn('primary pc connectionState issue', { - state: this.primaryPC.connectionState, - subPrimary: this.subscriberPrimary, - }); return false; } // also verify publisher connection if it's needed or different if (this.needsPublisher && this.subscriberPrimary) { if (!this.publisher) { - log.warn('publisher not present'); return false; } if ( this.publisher.pc.connectionState === 'closed' || this.publisher.pc.connectionState === 'failed' ) { - log.warn('publisher connection state issue', { state: this.publisher.pc.connectionState }); return false; } } // ensure signal is connected if (!this.client.ws || this.client.ws.readyState === WebSocket.CLOSED) { - log.warn('signal not connected'); return false; } return true; @@ -1302,7 +1275,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit const negotiationTimeout = setTimeout(() => { reject('negotiation timed out'); - console.log('negotiation timeout'); this.handleDisconnect('negotiation', ReconnectReason.RR_SIGNAL_DISCONNECTED); }, this.peerConnectionTimeout); @@ -1335,7 +1307,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit if (e instanceof NegotiationError) { this.fullReconnectOnNext = true; } - console.log('publisher negotiation error'); this.handleDisconnect('negotiation', ReconnectReason.RR_UNKNOWN); }); }); From b82e89fa3542d1c4870833ea0f18eea11238f2e0 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 14 Sep 2023 16:30:26 +0200 Subject: [PATCH 4/6] more cleanup --- src/room/RTCEngine.ts | 14 +++++++------- src/room/Room.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/room/RTCEngine.ts b/src/room/RTCEngine.ts index 21c5534f5d..df39d3fd1a 100644 --- a/src/room/RTCEngine.ts +++ b/src/room/RTCEngine.ts @@ -120,7 +120,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit // true if publisher connection has already been established. // this is helpful to know if we need to restart ICE on the publisher connection - private needsPublisher: boolean = false; + private hasPublished: boolean = false; // keep join info around for reconnect, this could be a region url private url?: string; @@ -207,7 +207,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } // create offer - if (!this.subscriberPrimary || this.needsPublisher) { + if (!this.subscriberPrimary || this.hasPublished) { this.negotiate(); } @@ -419,7 +419,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit log.debug(`primary PC state changed ${primaryPC.connectionState}`); if (primaryPC.connectionState === 'connected') { const initialFullConnection = - (this.pcState === PCState.New && !this.needsPublisher) || + (this.pcState === PCState.New && !this.hasPublished) || this.publisher?.pc.connectionState === 'connected'; if (initialFullConnection) { this.pcState = PCState.Connected; @@ -1036,7 +1036,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.subscriber.restartingIce = true; // only restart publisher if it's needed - if (this.needsPublisher) { + if (this.hasPublished) { await this.publisher.createAndSendOffer({ iceRestart: true }); } @@ -1108,7 +1108,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit // manually now - startTime > minReconnectWait && this.primaryPC?.connectionState === 'connected' && - (!this.needsPublisher || this.publisher?.pc.connectionState === 'connected') + (!this.hasPublished || this.publisher?.pc.connectionState === 'connected') ) { this.pcState = PCState.Connected; return; @@ -1231,7 +1231,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit } // also verify publisher connection if it's needed or different - if (this.needsPublisher && this.subscriberPrimary) { + if (this.hasPublished && this.subscriberPrimary) { if (!this.publisher) { return false; } @@ -1259,7 +1259,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit return; } - this.needsPublisher = true; + this.hasPublished = true; const handleClosed = () => { log.debug('engine disconnected while negotiation was ongoing'); diff --git a/src/room/Room.ts b/src/room/Room.ts index b7e96b293a..df6eaa27c4 100644 --- a/src/room/Room.ts +++ b/src/room/Room.ts @@ -1619,7 +1619,7 @@ class Room extends (EventEmitter as new () => TypedEmitter) console.log('registering connection reconcile', { stackError }); let consecutiveFailures = 0; - this.connectionReconcileInterval = setInterval(() => { + this.connectionReconcileInterval = CriticalTimers.setInterval(() => { if ( // ensure we didn't tear it down !this.engine || From b946b5565faac4a1f4708be2ff0ebe9f48483b3d Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 14 Sep 2023 16:31:28 +0200 Subject: [PATCH 5/6] remove logs --- src/room/Room.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/room/Room.ts b/src/room/Room.ts index df6eaa27c4..39af375ad2 100644 --- a/src/room/Room.ts +++ b/src/room/Room.ts @@ -294,7 +294,6 @@ class Room extends (EventEmitter as new () => TypedEmitter) .on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate) .on(EngineEvent.DataPacketReceived, this.handleDataPacket) .on(EngineEvent.Resuming, () => { - console.log("we're resuming"); this.clearConnectionReconcile(); if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) { this.emit(RoomEvent.Reconnecting); @@ -1609,15 +1608,7 @@ class Room extends (EventEmitter as new () => TypedEmitter) } private registerConnectionReconcile() { - let stackError: string | undefined; - try { - throw new Error(); - } catch (e) { - stackError = (e as Error).stack; - } this.clearConnectionReconcile(); - console.log('registering connection reconcile', { stackError }); - let consecutiveFailures = 0; this.connectionReconcileInterval = CriticalTimers.setInterval(() => { if ( @@ -1645,7 +1636,6 @@ class Room extends (EventEmitter as new () => TypedEmitter) private clearConnectionReconcile() { if (this.connectionReconcileInterval) { - console.log('clearing connection reconcile'); CriticalTimers.clearInterval(this.connectionReconcileInterval); } } From 67013ee7bc83780363ec22540b0237116d9bec28 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 14 Sep 2023 16:33:05 +0200 Subject: [PATCH 6/6] remove logs --- src/room/RTCEngine.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/room/RTCEngine.ts b/src/room/RTCEngine.ts index df39d3fd1a..89545267cb 100644 --- a/src/room/RTCEngine.ts +++ b/src/room/RTCEngine.ts @@ -447,10 +447,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit this.emit(EngineEvent.Connected, joinResponse); } } - log.warn(`secondary PC state changed ${secondaryPC.connectionState}`); + log.debug(`secondary PC state changed ${secondaryPC.connectionState}`); // also reconnect if secondary peerconnection fails if (secondaryPC.connectionState === 'failed') { - log.warn('issuing reconnect for secondary PC failed'); this.handleDisconnect( 'secondary peerconnection', subscriberPrimary @@ -1099,7 +1098,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit log.debug('waiting for peer connection to reconnect'); while (now - startTime < this.peerConnectionTimeout) { if (this.primaryPC === undefined) { - console.warn('primary missing, connection hosed'); // we can abort early, connection is hosed break; } else if (