From 15312ac659f5720d5ff53b51ba8030aea2bcf2bd Mon Sep 17 00:00:00 2001 From: Christoph Guttandin <chrisguttandin@media-codings.com> Date: Mon, 13 Nov 2023 22:20:47 +0100 Subject: [PATCH] fix: cancel endlessly gathering connections --- src/functions/create-backoff.ts | 8 ++++++++ src/operators/negotiate-data-channels.ts | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/functions/create-backoff.ts diff --git a/src/functions/create-backoff.ts b/src/functions/create-backoff.ts new file mode 100644 index 00000000..cd7fd478 --- /dev/null +++ b/src/functions/create-backoff.ts @@ -0,0 +1,8 @@ +export const createBackoff = (base: number) => + <const>[ + () => base ** 2, + () => { + // tslint:disable-next-line:no-parameter-reassignment + base += 1; + } + ]; diff --git a/src/operators/negotiate-data-channels.ts b/src/operators/negotiate-data-channels.ts index dc516517..89984c77 100644 --- a/src/operators/negotiate-data-channels.ts +++ b/src/operators/negotiate-data-channels.ts @@ -9,19 +9,23 @@ import { finalize, from, ignoreElements, + iif, interval, merge, mergeMap, of, retry, + switchMap, take, takeUntil, tap, throwError, + timer, zip } from 'rxjs'; import { inexorably } from 'rxjs-etc/operators'; import { on } from 'subscribable-things'; +import { createBackoff } from '../functions/create-backoff'; import { IErrorEvent, IPingEvent, IPongEvent, IUpdateEvent } from '../interfaces'; import { TDataChannelTuple, TIncomingNegotiationEvent, TOutgoingSignalingEvent, TSendPeerToPeerMessageFunction } from '../types'; import { echo } from './echo'; @@ -138,8 +142,24 @@ export const negotiateDataChannels = return () => unsubscribeFunctions.forEach((unsubscribeFunction) => unsubscribeFunction()); }; + const [getBackoff, incrementBackoff] = createBackoff(1); const subscribeToPeerConnection = () => { + const subscription = merge(on(peerConnection, 'icecandidate'), on(peerConnection, 'icegatheringstatechange')) + .pipe( + switchMap(() => + iif( + () => peerConnection.iceGatheringState === 'gathering', + defer(() => timer(10_000 * getBackoff())), + EMPTY + ) + ) + ) + .subscribe(() => { + incrementBackoff(); + errorSubject.next(new Error('RTCPeerConnection seems to be stuck at iceGatheringState "gathering".')); + }); const unsubscribeFunctions = [ + () => subscription.unsubscribe(), on( peerConnection, 'connectionstatechange'