@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.
- package/README.md +1 -1
- package/dist/constants/common.d.ts +1 -1
- package/dist/constants/common.ts +1 -1
- package/dist/engine/PeerProducer.d.ts +0 -3
- package/dist/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.d.ts +1 -3
- package/dist/index.es.js +2 -2
- package/dist/index.js +2 -2
- package/dist/types/channelStateSyncronizer.d.ts +0 -6
- package/package.json +2 -2
- package/src/constants/common.ts +1 -1
- package/src/engine/ChannelStateSynchronizer/ChannelStateSynchronizer.ts +1 -1
- package/src/engine/PeerProducer.ts +0 -12
- package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.ts +14 -31
- package/src/engine/handlers/ChannelStateSyncEventHandler/index.ts +0 -1
- package/src/engine/handlers/MediaEventHandler.ts +2 -2
- package/src/engine/index.ts +4 -4
- package/src/engine/network/index.ts +20 -20
- package/src/types/channelStateSyncronizer.ts +0 -7
|
@@ -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.
|
|
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.
|
|
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",
|
package/src/constants/common.ts
CHANGED
|
@@ -361,7 +361,7 @@ class ChannelStateSynchronizer {
|
|
|
361
361
|
const { paused } = clusterPeerProducer;
|
|
362
362
|
|
|
363
363
|
if (localProducer.paused !== paused) {
|
|
364
|
-
localProducer.
|
|
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:
|
|
10
|
+
localState: ChannelStateShort;
|
|
15
11
|
remoteState: ChannelStateShort;
|
|
16
12
|
}
|
|
17
13
|
|
|
18
14
|
class ChannelStateConsistencyChecker {
|
|
19
|
-
private readonly localState:
|
|
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 (
|
|
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):
|
|
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:
|
|
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;
|
|
@@ -131,7 +131,7 @@ class MediaEventHandler {
|
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
producer.
|
|
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.
|
|
155
|
+
producer.paused = false;
|
|
156
156
|
peer.observer.safeEmit(PEER_EVENTS.publisherResumed, {
|
|
157
157
|
producerId: producer.id,
|
|
158
158
|
kind: producer.kind,
|
package/src/engine/index.ts
CHANGED
|
@@ -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
|
-
|
|
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 =
|
|
891
|
-
const REQUIRED_SUCCESSFUL_CHECKS =
|
|
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 =
|
|
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: '
|
|
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
|
-
|
|
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
|
|
821
|
+
if (this.#iceIntervalTimeouts[transport.direction]) {
|
|
813
822
|
this.#logger.debug('Stop receiveTransport.restartIce() retries', { recvTransportId: transport.id });
|
|
814
|
-
clearInterval(this.#iceIntervalTimeouts
|
|
815
|
-
this.#iceIntervalTimeouts
|
|
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
|
|
853
|
+
if (this.#iceIntervalTimeouts[transport.direction]) {
|
|
845
854
|
return;
|
|
846
855
|
}
|
|
847
856
|
|
|
848
857
|
if (state === 'failed') {
|
|
849
|
-
this.#logger.debug(`${ transport.
|
|
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
|
|
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.
|
|
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
|
|