@livedigital/client 3.41.0-test-rejoins.4 → 3.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,10 @@
1
1
  import type { ChannelStateShortPeer } from '../proto/generated/channel/channel_state_short';
2
- export interface LocalChannelStatePeerProducer {
3
- id: string;
4
- paused: boolean;
5
- stateChangedAt: number;
6
- }
7
2
  export interface LocalChannelStatePeerConsumer {
8
3
  id: string;
9
4
  paused: boolean;
10
5
  producerId: string;
11
6
  }
12
7
  export interface LocalChannelStatePeer extends ChannelStateShortPeer {
13
- producers: LocalChannelStatePeerProducer[];
14
8
  consumers?: LocalChannelStatePeerConsumer[];
15
9
  }
16
10
  export interface LocalChannelState {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@livedigital/client",
3
3
  "author": "vlprojects",
4
4
  "license": "MIT",
5
- "version": "3.41.0-test-rejoins.4",
5
+ "version": "3.41.1",
6
6
  "private": false,
7
7
  "bugs": {
8
8
  "url": "https://github.com/vlprojects/livedigital-sdk/issues"
@@ -51,7 +51,7 @@
51
51
  "hash-sum": "^2.0.0",
52
52
  "inversify": "^6.0.2",
53
53
  "load-script": "^2.0.0",
54
- "mediasoup-client": "3.11",
54
+ "mediasoup-client": "3.15.6",
55
55
  "message-batcher": "^0.0.2",
56
56
  "qs": "^6.11.0",
57
57
  "reflect-metadata": "^0.2.2",
@@ -2,7 +2,7 @@
2
2
 
3
3
  import type { LogLevel } from '../types/common';
4
4
 
5
- export const SIGNALING_API_VERSION = 7;
5
+ export const SIGNALING_API_VERSION = 6;
6
6
 
7
7
  export const LOG_LEVEL_ERROR: LogLevel = 3;
8
8
  export const LOG_LEVEL_WARN: LogLevel = 4;
@@ -361,7 +361,7 @@ class ChannelStateSynchronizer {
361
361
  const { paused } = clusterPeerProducer;
362
362
 
363
363
  if (localProducer.paused !== paused) {
364
- localProducer.setPaused(paused);
364
+ localProducer.paused = paused;
365
365
  const producerStateEvent = localProducer.paused ? PEER_EVENTS.publisherPaused : PEER_EVENTS.publisherResumed;
366
366
  localPeer.observer.safeEmit(producerStateEvent, {
367
367
  producerId: localProducer.id,
@@ -19,8 +19,6 @@ class PeerProducer {
19
19
 
20
20
  readonly trackTransformParams?: TrackTransformParams;
21
21
 
22
- #stateChangedAt: number;
23
-
24
22
  constructor(params: ProducerData) {
25
23
  const {
26
24
  id, kind, peerId, label, paused,
@@ -34,16 +32,6 @@ class PeerProducer {
34
32
  this.encodings = params.encodings;
35
33
  this.trackTransformParams = params.trackTransformParams;
36
34
  this.maxSpatialLayer = params.maxSpatialLayer;
37
- this.#stateChangedAt = Date.now();
38
- }
39
-
40
- setPaused(paused: boolean): void {
41
- this.paused = paused;
42
- this.#stateChangedAt = Date.now();
43
- }
44
-
45
- getStateChangedAt(): number {
46
- return this.#stateChangedAt;
47
35
  }
48
36
  }
49
37
 
@@ -1,22 +1,18 @@
1
- import { FIVE_SECONDS_IN_MS } from '../../../constants/common';
2
1
  import type {
3
2
  ChannelStateShort,
3
+ ChannelStateShortPeer,
4
+ ChannelStateShortProducer,
4
5
  } from '../../../proto/generated/channel/channel_state_short';
5
- import type {
6
- LocalChannelState,
7
- LocalChannelStatePeer,
8
- LocalChannelStatePeerConsumer,
9
- LocalChannelStatePeerProducer,
10
- } from '../../../types/channelStateSyncronizer';
6
+ import type { LocalChannelStatePeer, LocalChannelStatePeerConsumer } from '../../../types/channelStateSyncronizer';
11
7
  import ChannelStateConsistencyCheckResult from './ChannelStateConsistencyCheckResult';
12
8
 
13
9
  interface ChannelStateConsistencyCheckerParams {
14
- localState: LocalChannelState;
10
+ localState: ChannelStateShort;
15
11
  remoteState: ChannelStateShort;
16
12
  }
17
13
 
18
14
  class ChannelStateConsistencyChecker {
19
- private readonly localState: LocalChannelState;
15
+ private readonly localState: ChannelStateShort;
20
16
 
21
17
  private readonly remoteState: ChannelStateShort;
22
18
 
@@ -53,15 +49,19 @@ class ChannelStateConsistencyChecker {
53
49
  }
54
50
 
55
51
  remotePeer.producers.forEach((remoteProducer) => {
52
+ const localConsumer = this.findLocalConsumerByProducerId(localPeer, remoteProducer.id);
53
+
54
+ if (localConsumer && localConsumer.paused !== remoteProducer.paused) {
55
+ this.consumersWithInconsistentState.push(localConsumer.id);
56
+ }
57
+
56
58
  const localProducer = this.findLocalProducerById(localPeer, remoteProducer.id);
57
59
 
58
60
  if (!localProducer) {
59
61
  this.missingProducers.push(remoteProducer.id);
60
-
61
- return;
62
62
  }
63
63
 
64
- if (this.isLocalProducerStateChangedRecently(localProducer)) {
64
+ if (!localProducer) {
65
65
  return;
66
66
  }
67
67
 
@@ -69,19 +69,6 @@ class ChannelStateConsistencyChecker {
69
69
 
70
70
  if (isInconsistentState) {
71
71
  this.producersWithInconsistentState.push(remoteProducer.id);
72
-
73
- // don't check consumer state while producer state is inconsistent
74
- return;
75
- }
76
-
77
- const localConsumer = this.findLocalConsumerByProducerId(localPeer, remoteProducer.id);
78
-
79
- if (localConsumer && localConsumer.paused !== remoteProducer.paused) {
80
- this.consumersWithInconsistentState.push(localConsumer.id);
81
- }
82
-
83
- if (!localProducer) {
84
- this.missingProducers.push(remoteProducer.id);
85
72
  }
86
73
  });
87
74
  });
@@ -115,7 +102,7 @@ class ChannelStateConsistencyChecker {
115
102
  return this.peersWithInconsistentAppData;
116
103
  }
117
104
 
118
- private findLocalPeerById(id: string): LocalChannelStatePeer | undefined {
105
+ private findLocalPeerById(id: string): ChannelStateShortPeer | undefined {
119
106
  return this.localState.peers.find((item) => item.id === id);
120
107
  }
121
108
 
@@ -126,7 +113,7 @@ class ChannelStateConsistencyChecker {
126
113
  return peer.consumers?.find((item) => item.producerId === producerId);
127
114
  }
128
115
 
129
- private findLocalProducerById(peer: LocalChannelStatePeer, id: string): LocalChannelStatePeerProducer | undefined {
116
+ private findLocalProducerById(peer: ChannelStateShortPeer, id: string): ChannelStateShortProducer | undefined {
130
117
  return peer.producers.find((item) => item.id === id);
131
118
  }
132
119
 
@@ -137,10 +124,6 @@ class ChannelStateConsistencyChecker {
137
124
  this.producersWithInconsistentState = [];
138
125
  this.peersWithInconsistentAppData = [];
139
126
  }
140
-
141
- private isLocalProducerStateChangedRecently(producer: LocalChannelStatePeerProducer): boolean {
142
- return Date.now() - producer.stateChangedAt < FIVE_SECONDS_IN_MS;
143
- }
144
127
  }
145
128
 
146
129
  export default ChannelStateConsistencyChecker;
@@ -274,7 +274,6 @@ class ChannelStateSyncEventHandler {
274
274
  producers: peer.getProducers().map((producer) => ({
275
275
  id: producer.id,
276
276
  paused: producer.paused,
277
- stateChangedAt: producer.getStateChangedAt(),
278
277
  })),
279
278
  consumers: peer.getConsumersState(),
280
279
  })),
@@ -131,7 +131,7 @@ class MediaEventHandler {
131
131
  return;
132
132
  }
133
133
 
134
- producer.setPaused(true);
134
+ producer.paused = true;
135
135
  peer.observer.safeEmit(PEER_EVENTS.publisherPaused, {
136
136
  producerId: producer.id,
137
137
  kind: producer.kind,
@@ -152,7 +152,7 @@ class MediaEventHandler {
152
152
  return;
153
153
  }
154
154
 
155
- producer.setPaused(false);
155
+ producer.paused = false;
156
156
  peer.observer.safeEmit(PEER_EVENTS.publisherResumed, {
157
157
  producerId: producer.id,
158
158
  kind: producer.kind,
@@ -136,7 +136,7 @@ class Engine {
136
136
  this.network.createSendTransport(this.media.mediasoupDevice),
137
137
  this.network.createRecvTransport(this.media.mediasoupDevice),
138
138
  // @INFO: un-comment to enable signaling tcp transport connection
139
- this.network.createSignalingTransport(this.media.mediasoupDevice),
139
+ // this.network.createSignalingTransport(this.media.mediasoupDevice),
140
140
  ]);
141
141
 
142
142
  this.webRtcIssueDetector?.handleNewPeerConnection(sendTransport.handler._pc, sendTransport.id);
@@ -162,7 +162,7 @@ class Engine {
162
162
 
163
163
  // @INFO: un-comment to enable signaling tcp transport connection
164
164
  // @WARN: must be non-blocking, no await
165
- await this.network.createSignalingConsumer();
165
+ // this.network.createSignalingConsumer();
166
166
  } catch (error: unknown) {
167
167
  this.#logger.error('initialize()', { error });
168
168
 
@@ -887,8 +887,8 @@ class Engine {
887
887
  case: 'waitForReconnectOrTriggerRejoinEventIfAppropriate',
888
888
  });
889
889
 
890
- const CHECKS_INTERVAL = 10_000;
891
- const REQUIRED_SUCCESSFUL_CHECKS = 6;
890
+ const CHECKS_INTERVAL = 3_000;
891
+ const REQUIRED_SUCCESSFUL_CHECKS = 4;
892
892
  let continuousNumberOfLoadbalancerSuccessfulChecks = 0;
893
893
 
894
894
  const checkInterval = setInterval(async () => {
@@ -41,6 +41,11 @@ import LivedigitalSDKError from '../../errors/LivedigitalSDKError';
41
41
  import { ClientObserverEvents } from '../../types/engine';
42
42
  import DataChannelsManager from './DataChannelsManager';
43
43
 
44
+ interface IceIntervalTimeouts {
45
+ send?: ReturnType<typeof setInterval>;
46
+ recv?: ReturnType<typeof setInterval>;
47
+ }
48
+
44
49
  const TRANSPORT_RESTART_ICE_INTERVAL = 5_000;
45
50
  const TRANSPORT_DETAILS_DELAY = 1500;
46
51
 
@@ -58,7 +63,10 @@ class Network {
58
63
 
59
64
  private preferRelay?: boolean;
60
65
 
61
- readonly #iceIntervalTimeouts = new Map<string, ReturnType<typeof setInterval>>();
66
+ readonly #iceIntervalTimeouts: IceIntervalTimeouts = {
67
+ send: undefined,
68
+ recv: undefined,
69
+ };
62
70
 
63
71
  readonly #eventEmitter: EnhancedEventEmitter<NetworkObserverEvents>;
64
72
 
@@ -392,7 +400,7 @@ class Network {
392
400
  }
393
401
 
394
402
  this.signalingDataProducer = await transport.produceData({
395
- label: 'heart-beater',
403
+ label: 'signaling-data-channel',
396
404
  protocol: 'json',
397
405
  });
398
406
 
@@ -711,7 +719,8 @@ class Network {
711
719
  }
712
720
 
713
721
  private stopRestartIceAttempts(): void {
714
- Array.from(this.#iceIntervalTimeouts.values()).forEach((interval) => clearInterval(interval));
722
+ clearInterval(this.#iceIntervalTimeouts.send);
723
+ clearInterval(this.#iceIntervalTimeouts.recv);
715
724
  }
716
725
 
717
726
  private subscribeCommonTransportEvents(transport: Transport): void {
@@ -809,10 +818,10 @@ class Network {
809
818
  direction: transport.direction,
810
819
  });
811
820
 
812
- if (this.#iceIntervalTimeouts.has(transport.id)) {
821
+ if (this.#iceIntervalTimeouts[transport.direction]) {
813
822
  this.#logger.debug('Stop receiveTransport.restartIce() retries', { recvTransportId: transport.id });
814
- clearInterval(this.#iceIntervalTimeouts.get(transport.id));
815
- this.#iceIntervalTimeouts.delete(transport.id);
823
+ clearInterval(this.#iceIntervalTimeouts[transport.direction]);
824
+ this.#iceIntervalTimeouts[transport.direction] = undefined;
816
825
 
817
826
  if (state === 'connected') {
818
827
  this.#eventEmitter.safeEmit(NETWORK_OBSERVER_EVENTS.transportState, {
@@ -841,38 +850,29 @@ class Network {
841
850
  });
842
851
 
843
852
  if (['disconnected', 'failed'].includes(state)) {
844
- if (this.#iceIntervalTimeouts.has(transport.id)) {
853
+ if (this.#iceIntervalTimeouts[transport.direction]) {
845
854
  return;
846
855
  }
847
856
 
848
857
  if (state === 'failed') {
849
- this.#logger.debug(`${ transport.id } transport.restartIce()`, {
850
- transportId: transport.id,
851
- direction: transport.direction,
852
- });
858
+ this.#logger.debug(`${ transport.direction }Transport.restartIce()`, { recvTransportId: transport.id });
853
859
  this.restartIce(transport).catch((error: unknown) => {
854
860
  this.#logger.debug('Failed to execute restartIce', {
855
861
  error: serializeError(error),
856
- transportId: transport.id,
857
- direction: transport.direction,
858
862
  });
859
863
  });
860
864
  }
861
865
 
862
- this.#iceIntervalTimeouts.set(transport.id, setInterval(() => {
866
+ this.#iceIntervalTimeouts[transport.direction] = setInterval(() => {
863
867
  this.restartIce(transport).catch((error: unknown) => {
864
868
  this.#logger.debug('Failed to execute restartIce', {
865
869
  error: serializeError(error),
866
- transportId: transport.id,
867
- direction: transport.direction,
868
870
  });
869
871
  });
870
- this.#logger.debug(`${ transport.id } transport.restartIce() attempt`, {
872
+ this.#logger.debug(`${ transport.direction }Transport.restartIce() attempt`, {
871
873
  recvTransportId: transport.id,
872
- transportId: transport.id,
873
- direction: transport.direction,
874
874
  });
875
- }, TRANSPORT_RESTART_ICE_INTERVAL));
875
+ }, TRANSPORT_RESTART_ICE_INTERVAL);
876
876
  }
877
877
  });
878
878
 
@@ -1,11 +1,5 @@
1
1
  import type { ChannelStateShortPeer } from '../proto/generated/channel/channel_state_short';
2
2
 
3
- export interface LocalChannelStatePeerProducer {
4
- id: string;
5
- paused: boolean;
6
- stateChangedAt: number;
7
- }
8
-
9
3
  export interface LocalChannelStatePeerConsumer {
10
4
  id: string;
11
5
  paused: boolean;
@@ -13,7 +7,6 @@ export interface LocalChannelStatePeerConsumer {
13
7
  }
14
8
 
15
9
  export interface LocalChannelStatePeer extends ChannelStateShortPeer {
16
- producers: LocalChannelStatePeerProducer[];
17
10
  consumers?: LocalChannelStatePeerConsumer[];
18
11
  };
19
12