@observertc/observer-js 1.0.1-c3edea3.0 → 1.0.1-ec27289.0
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/lib/ObservedCall.d.ts +41 -7
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +125 -13
- package/lib/ObservedCallSummary.d.ts +18 -0
- package/lib/ObservedCallSummary.d.ts.map +1 -0
- package/lib/ObservedClient.d.ts +70 -11
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +394 -72
- package/lib/ObservedClientEventMonitor.d.ts +89 -0
- package/lib/ObservedClientEventMonitor.d.ts.map +1 -0
- package/lib/ObservedClientEventMonitor.js +247 -0
- package/lib/ObservedClientSummary.d.ts +23 -0
- package/lib/ObservedClientSummary.d.ts.map +1 -0
- package/lib/ObservedClientSummary.js +2 -0
- package/lib/ObservedDataChannel.d.ts +6 -0
- package/lib/ObservedDataChannel.d.ts.map +1 -1
- package/lib/ObservedDataChannel.js +30 -0
- package/lib/ObservedIceCandidatePair.d.ts +4 -0
- package/lib/ObservedIceCandidatePair.d.ts.map +1 -1
- package/lib/ObservedIceCandidatePair.js +28 -0
- package/lib/ObservedIceTransport.d.ts +4 -0
- package/lib/ObservedIceTransport.d.ts.map +1 -1
- package/lib/ObservedIceTransport.js +28 -0
- package/lib/ObservedInboundTrack.d.ts +2 -0
- package/lib/ObservedInboundTrack.d.ts.map +1 -1
- package/lib/ObservedInboundTrack.js +2 -0
- package/lib/ObservedOutboundTrack.d.ts +2 -0
- package/lib/ObservedOutboundTrack.d.ts.map +1 -1
- package/lib/ObservedOutboundTrack.js +2 -0
- package/lib/ObservedPeerConnection.d.ts +14 -2
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +106 -14
- package/lib/ObservedTURN.d.ts +31 -0
- package/lib/ObservedTURN.d.ts.map +1 -0
- package/lib/ObservedTURN.js +58 -0
- package/lib/ObservedTurnServer.d.ts +25 -0
- package/lib/ObservedTurnServer.d.ts.map +1 -0
- package/lib/ObservedTurnServer.js +59 -0
- package/lib/Observer.d.ts +38 -21
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +114 -40
- package/lib/ObserverSummary.d.ts +13 -0
- package/lib/ObserverSummary.d.ts.map +1 -0
- package/lib/ObserverSummary.js +2 -0
- package/lib/common/utils.d.ts +2 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +11 -3
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -1
- package/lib/schema/ClientEventTypes.d.ts +100 -0
- package/lib/schema/ClientEventTypes.d.ts.map +1 -0
- package/lib/schema/ClientEventTypes.js +38 -0
- package/lib/schema/{metaTypes.d.ts → ClientMetaTypes.d.ts} +2 -2
- package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
- package/lib/schema/ClientMetaTypes.js +16 -0
- package/lib/updaters/CallUpdater.d.ts.map +1 -0
- package/lib/updaters/CallUpdater.js +2 -0
- package/lib/updaters/ObserverUpdater.d.ts +5 -0
- package/lib/updaters/ObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/ObserverUpdater.js +2 -0
- package/lib/updaters/OnAllCallObserverUpdater_.d.ts +13 -0
- package/lib/updaters/OnAllCallObserverUpdater_.d.ts.map +1 -0
- package/lib/updaters/OnAllCallObserverUpdater_.js +38 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts +13 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAllClientCallUpdater.js +37 -0
- package/lib/updaters/OnAnyCallObserverUpdater_.d.ts +11 -0
- package/lib/updaters/OnAnyCallObserverUpdater_.d.ts.map +1 -0
- package/lib/updaters/OnAnyCallObserverUpdater_.js +27 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts +11 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAnyClientCallUpdater.js +27 -0
- package/lib/updaters/OnIntervalUpdater.d.ts +10 -0
- package/lib/updaters/OnIntervalUpdater.d.ts.map +1 -0
- package/lib/updaters/OnIntervalUpdater.js +17 -0
- package/lib/updaters/Updater.d.ts +6 -0
- package/lib/updaters/Updater.d.ts.map +1 -0
- package/lib/updaters/Updater.js +2 -0
- package/package.json +1 -1
- package/src/ObservedCall.ts +205 -16
- package/src/ObservedCallSummary.ts +22 -0
- package/src/ObservedClient.ts +492 -78
- package/src/ObservedClientEventMonitor.ts +301 -0
- package/src/ObservedClientSummary.ts +24 -0
- package/src/ObservedDataChannel.ts +32 -0
- package/src/ObservedIceCandidatePair.ts +26 -0
- package/src/ObservedIceTransport.ts +29 -0
- package/src/ObservedInboundTrack.ts +3 -0
- package/src/ObservedOutboundTrack.ts +3 -0
- package/src/ObservedPeerConnection.ts +120 -16
- package/src/ObservedTURN.ts +86 -0
- package/src/ObservedTurnServer.ts +72 -0
- package/src/Observer.ts +164 -64
- package/src/ObserverSummary.ts +15 -0
- package/src/common/utils.ts +12 -2
- package/src/index.ts +5 -0
- package/src/schema/ClientEventTypes.ts +112 -0
- package/src/schema/{metaTypes.ts → ClientMetaTypes.ts} +1 -1
- package/src/updaters/ObserverUpdater.ts +5 -0
- package/src/updaters/OnAllCallObserverUpdater_.ts +46 -0
- package/src/updaters/OnAllClientCallUpdater.ts +46 -0
- package/src/updaters/OnAnyCallObserverUpdater_.ts +32 -0
- package/src/updaters/OnAnyClientCallUpdater.ts +32 -0
- package/src/updaters/OnIntervalUpdater.ts +19 -0
- package/src/updaters/Updater.ts +5 -0
- package/tsconfig.json +1 -1
- package/lib/schema/eventTypes.d.ts +0 -33
- package/lib/schema/eventTypes.d.ts.map +0 -1
- package/lib/schema/eventTypes.js +0 -38
- package/lib/schema/metaTypes.d.ts.map +0 -1
- package/lib/schema/metaTypes.js +0 -16
- package/lib/utils/CallUpdater.d.ts.map +0 -1
- package/lib/utils/OnAllClientCallUpdater.d.ts +0 -16
- package/lib/utils/OnAllClientCallUpdater.d.ts.map +0 -1
- package/lib/utils/OnAllClientCallUpdater.js +0 -58
- package/lib/utils/onAnyClientCallUpdater.d.ts +0 -14
- package/lib/utils/onAnyClientCallUpdater.d.ts.map +0 -1
- package/lib/utils/onAnyClientCallUpdater.js +0 -51
- package/src/schema/eventTypes.ts +0 -36
- package/src/utils/OnAllClientCallUpdater.ts +0 -68
- package/src/utils/onAnyClientCallUpdater.ts +0 -59
- /package/lib/{utils/CallUpdater.js → ObservedCallSummary.js} +0 -0
- /package/lib/{utils → updaters}/CallUpdater.d.ts +0 -0
- /package/src/{utils → updaters}/CallUpdater.ts +0 -0
|
@@ -19,6 +19,8 @@ import { ObservedRemoteOutboundRtp } from './ObservedRemoteOutboundRtp';
|
|
|
19
19
|
import { ObservedInboundTrack } from './ObservedInboundTrack';
|
|
20
20
|
import { ObservedOutboundTrack } from './ObservedOutboundTrack';
|
|
21
21
|
import { CalculatedScore } from './scores/CalculatedScore';
|
|
22
|
+
import { ObservedTurnServer } from './ObservedTurnServer';
|
|
23
|
+
import { getMedian } from './common/utils';
|
|
22
24
|
|
|
23
25
|
const logger = createLogger('ObservedPeerConnection');
|
|
24
26
|
|
|
@@ -70,7 +72,7 @@ export type ObservedPeerConnectionEvents = {
|
|
|
70
72
|
'removed-peer-connection-transport': [ObservedPeerConnectionTransport];
|
|
71
73
|
'removed-remote-inbound-rtp': [ObservedRemoteInboundRtp];
|
|
72
74
|
'removed-remote-outbound-rtp': [ObservedRemoteOutboundRtp];
|
|
73
|
-
|
|
75
|
+
'update': [],
|
|
74
76
|
close: [];
|
|
75
77
|
};
|
|
76
78
|
|
|
@@ -106,11 +108,15 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
106
108
|
public closedAt?: number;
|
|
107
109
|
public updated = Date.now();
|
|
108
110
|
|
|
111
|
+
public availableIncomingBitrate = 0;
|
|
112
|
+
public availableOutgoingBitrate = 0;
|
|
109
113
|
public totalInboundPacketsLost = 0;
|
|
110
114
|
public totalInboundPacketsReceived = 0;
|
|
111
115
|
public totalOutboundPacketsSent = 0;
|
|
112
116
|
public totalDataChannelBytesSent = 0;
|
|
113
117
|
public totalDataChannelBytesReceived = 0;
|
|
118
|
+
public totalDataChannelMessagesSent = 0;
|
|
119
|
+
public totalDataChannelMessagesReceived = 0;
|
|
114
120
|
|
|
115
121
|
public totalSentAudioBytes = 0;
|
|
116
122
|
public totalSentVideoBytes = 0;
|
|
@@ -126,6 +132,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
126
132
|
public deltaOutboundPacketsSent = 0;
|
|
127
133
|
public deltaDataChannelBytesSent = 0;
|
|
128
134
|
public deltaDataChannelBytesReceived = 0;
|
|
135
|
+
public deltaDataChannelMessagesSent = 0;
|
|
136
|
+
public deltaDataChannelMessagesReceived = 0;
|
|
129
137
|
public deltaInboundReceivedBytes = 0;
|
|
130
138
|
public deltaOutboundSentBytes = 0;
|
|
131
139
|
|
|
@@ -135,6 +143,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
135
143
|
public deltaReceivedVideoPackets = 0;
|
|
136
144
|
public deltaSentAudioBytes = 0;
|
|
137
145
|
public deltaSentVideoBytes = 0;
|
|
146
|
+
public deltaTransportSentBytes = 0;
|
|
147
|
+
public deltaTransportReceivedBytes = 0;
|
|
138
148
|
|
|
139
149
|
public receivingPacketsPerSecond = 0;
|
|
140
150
|
public sendingPacketsPerSecond = 0;
|
|
@@ -143,12 +153,13 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
143
153
|
public receivingAudioBitrate = 0;
|
|
144
154
|
public receivingVideoBitrate = 0;
|
|
145
155
|
|
|
146
|
-
public
|
|
147
|
-
public
|
|
156
|
+
public currentRttInMs?: number;
|
|
157
|
+
public currentJitter?: number;
|
|
148
158
|
|
|
149
159
|
public usingTCP = false;
|
|
150
160
|
public usingTURN = false;
|
|
151
161
|
|
|
162
|
+
public observedTurnServer?: ObservedTurnServer;
|
|
152
163
|
public readonly observedCertificates = new Map<string, ObservedCertificate>();
|
|
153
164
|
public readonly observedCodecs = new Map<string, ObservedCodec>();
|
|
154
165
|
public readonly observedDataChannels = new Map<string, ObservedDataChannel>();
|
|
@@ -239,6 +250,14 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
239
250
|
.filter((pair) => pair !== undefined) as ObservedIceCandidatePair[];
|
|
240
251
|
}
|
|
241
252
|
|
|
253
|
+
public get selectedIceCandiadtePairForTurn() {
|
|
254
|
+
return this.selectedIceCandidatePairs
|
|
255
|
+
.filter((pair) =>
|
|
256
|
+
pair.getLocalCandidate()?.candidateType === 'relay' &&
|
|
257
|
+
pair.getRemoteCandidate()?.url?.startsWith('turn:')
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
242
261
|
public close() {
|
|
243
262
|
if (this.closed) return;
|
|
244
263
|
this.closed = true;
|
|
@@ -259,6 +278,10 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
259
278
|
this.observedRemoteInboundRtps.clear();
|
|
260
279
|
this.observedRemoteOutboundRtps.clear();
|
|
261
280
|
|
|
281
|
+
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
282
|
+
|
|
283
|
+
if (!this.closedAt) this.closedAt = Date.now();
|
|
284
|
+
|
|
262
285
|
this.emit('close');
|
|
263
286
|
}
|
|
264
287
|
|
|
@@ -266,6 +289,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
266
289
|
if (this.closed) return;
|
|
267
290
|
this._visited = true;
|
|
268
291
|
|
|
292
|
+
this.availableIncomingBitrate = 0;
|
|
293
|
+
this.availableOutgoingBitrate = 0;
|
|
269
294
|
this.deltaInboundPacketsLost = 0;
|
|
270
295
|
this.deltaInboundPacketsReceived = 0;
|
|
271
296
|
this.deltaOutboundPacketsSent = 0;
|
|
@@ -279,6 +304,9 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
279
304
|
this.deltaReceivedVideoPackets = 0;
|
|
280
305
|
this.deltaSentAudioBytes = 0;
|
|
281
306
|
this.deltaSentVideoBytes = 0;
|
|
307
|
+
this.deltaTransportReceivedBytes = 0;
|
|
308
|
+
this.deltaTransportSentBytes = 0;
|
|
309
|
+
|
|
282
310
|
this.sendingAudioBitrate = 0;
|
|
283
311
|
this.sendingVideoBitrate = 0;
|
|
284
312
|
this.receivingAudioBitrate = 0;
|
|
@@ -287,6 +315,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
287
315
|
const now = Date.now();
|
|
288
316
|
const elapsedTimeInMs = now - this.updated;
|
|
289
317
|
const elapsedTimeInSec = elapsedTimeInMs / 1000;
|
|
318
|
+
const rttMeasurementsInSec: number[] = [];
|
|
319
|
+
const jitterMeasurements: number[] = [];
|
|
290
320
|
|
|
291
321
|
if (sample.certificates) {
|
|
292
322
|
for (const certificate of sample.certificates) {
|
|
@@ -300,7 +330,14 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
300
330
|
}
|
|
301
331
|
if (sample.dataChannels) {
|
|
302
332
|
for (const dataChannel of sample.dataChannels) {
|
|
303
|
-
this._updateDataChannelStats(dataChannel);
|
|
333
|
+
const observedDataChannel = this._updateDataChannelStats(dataChannel);
|
|
334
|
+
|
|
335
|
+
if (!observedDataChannel) continue;
|
|
336
|
+
|
|
337
|
+
this.deltaDataChannelBytesSent += observedDataChannel.deltaBytesSent;
|
|
338
|
+
this.deltaDataChannelBytesReceived += observedDataChannel.deltaBytesReceived;
|
|
339
|
+
this.deltaDataChannelMessagesSent += observedDataChannel.deltaMessagesSent;
|
|
340
|
+
this.deltaDataChannelMessagesReceived += observedDataChannel.deltaMessagesReceived;
|
|
304
341
|
}
|
|
305
342
|
}
|
|
306
343
|
if (sample.iceCandidates) {
|
|
@@ -310,12 +347,29 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
310
347
|
}
|
|
311
348
|
if (sample.iceCandidatePairs) {
|
|
312
349
|
for (const iceCandidatePair of sample.iceCandidatePairs) {
|
|
313
|
-
this._updateIceCandidatePairStats(iceCandidatePair);
|
|
350
|
+
const observedCandidatePair = this._updateIceCandidatePairStats(iceCandidatePair);
|
|
351
|
+
|
|
352
|
+
if (!observedCandidatePair) continue;
|
|
353
|
+
|
|
354
|
+
if (observedCandidatePair.currentRoundTripTime) {
|
|
355
|
+
rttMeasurementsInSec.push(observedCandidatePair.currentRoundTripTime);
|
|
356
|
+
}
|
|
357
|
+
if (observedCandidatePair.availableIncomingBitrate) {
|
|
358
|
+
this.availableIncomingBitrate += observedCandidatePair.availableIncomingBitrate;
|
|
359
|
+
}
|
|
360
|
+
if (observedCandidatePair.availableOutgoingBitrate) {
|
|
361
|
+
this.availableOutgoingBitrate += observedCandidatePair.availableOutgoingBitrate;
|
|
362
|
+
}
|
|
314
363
|
}
|
|
315
364
|
}
|
|
316
365
|
if (sample.iceTransports) {
|
|
317
366
|
for (const iceTransport of sample.iceTransports) {
|
|
318
|
-
this._updateIceTransportStats(iceTransport);
|
|
367
|
+
const observedIceTransport = this._updateIceTransportStats(iceTransport);
|
|
368
|
+
|
|
369
|
+
if (!observedIceTransport) return;
|
|
370
|
+
|
|
371
|
+
observedIceTransport.bytesReceived;
|
|
372
|
+
|
|
319
373
|
}
|
|
320
374
|
}
|
|
321
375
|
if (sample.inboundRtps) {
|
|
@@ -338,6 +392,10 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
338
392
|
this.deltaReceivedVideoPackets += observedInboundRtp.deltaReceivedPackets;
|
|
339
393
|
break;
|
|
340
394
|
}
|
|
395
|
+
|
|
396
|
+
if (observedInboundRtp.jitter) {
|
|
397
|
+
jitterMeasurements.push(observedInboundRtp.jitter);
|
|
398
|
+
}
|
|
341
399
|
}
|
|
342
400
|
}
|
|
343
401
|
if (sample.mediaPlayouts) {
|
|
@@ -374,12 +432,21 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
374
432
|
}
|
|
375
433
|
if (sample.peerConnectionTransports) {
|
|
376
434
|
for (const peerConnectionTransport of sample.peerConnectionTransports) {
|
|
377
|
-
this._updatePeerConnectionTransportStats(peerConnectionTransport);
|
|
435
|
+
const observedTransport = this._updatePeerConnectionTransportStats(peerConnectionTransport);
|
|
436
|
+
|
|
437
|
+
if (!observedTransport) continue;
|
|
438
|
+
|
|
378
439
|
}
|
|
379
440
|
}
|
|
380
441
|
if (sample.remoteInboundRtps) {
|
|
381
442
|
for (const remoteInboundRtp of sample.remoteInboundRtps) {
|
|
382
|
-
this._updateRemoteInboundRtpStats(remoteInboundRtp);
|
|
443
|
+
const observedRemoteInboundRtp = this._updateRemoteInboundRtpStats(remoteInboundRtp);
|
|
444
|
+
|
|
445
|
+
if (!observedRemoteInboundRtp) continue;
|
|
446
|
+
|
|
447
|
+
if (observedRemoteInboundRtp.roundTripTime) {
|
|
448
|
+
rttMeasurementsInSec.push(observedRemoteInboundRtp.roundTripTime);
|
|
449
|
+
}
|
|
383
450
|
}
|
|
384
451
|
}
|
|
385
452
|
if (sample.remoteOutboundRtps) {
|
|
@@ -408,6 +475,8 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
408
475
|
this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
|
|
409
476
|
this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
410
477
|
this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
478
|
+
this.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
|
|
479
|
+
this.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
|
|
411
480
|
this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
|
|
412
481
|
this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
|
|
413
482
|
this.totalSentAudioBytes += this.deltaSentAudioBytes;
|
|
@@ -419,20 +488,55 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
419
488
|
|
|
420
489
|
this.receivingPacketsPerSecond = this.deltaInboundPacketsReceived / elapsedTimeInSec;
|
|
421
490
|
this.sendingPacketsPerSecond = this.deltaOutboundPacketsSent / elapsedTimeInSec;
|
|
422
|
-
this.sendingAudioBitrate = this.deltaSentAudioBytes * 8 / elapsedTimeInSec;
|
|
423
|
-
this.sendingVideoBitrate = this.deltaSentVideoBytes * 8 / elapsedTimeInSec;
|
|
424
|
-
this.receivingAudioBitrate = this.deltaReceivedAudioBytes * 8 / elapsedTimeInSec;
|
|
425
|
-
this.receivingVideoBitrate = this.deltaReceivedVideoBytes * 8 / elapsedTimeInSec;
|
|
426
|
-
|
|
491
|
+
this.sendingAudioBitrate = (this.deltaSentAudioBytes * 8) / elapsedTimeInSec;
|
|
492
|
+
this.sendingVideoBitrate = (this.deltaSentVideoBytes * 8) / elapsedTimeInSec;
|
|
493
|
+
this.receivingAudioBitrate = (this.deltaReceivedAudioBytes * 8) / elapsedTimeInSec;
|
|
494
|
+
this.receivingVideoBitrate = (this.deltaReceivedVideoBytes * 8) / elapsedTimeInSec;
|
|
495
|
+
|
|
496
|
+
if (rttMeasurementsInSec.length > 0) {
|
|
497
|
+
this.currentRttInMs = getMedian(rttMeasurementsInSec, false) * 1000;
|
|
498
|
+
} else {
|
|
499
|
+
this.currentRttInMs = undefined;
|
|
500
|
+
}
|
|
501
|
+
if (jitterMeasurements.length > 0) {
|
|
502
|
+
this.currentJitter = getMedian(jitterMeasurements, false);
|
|
503
|
+
} else {
|
|
504
|
+
this.currentJitter = undefined;
|
|
505
|
+
}
|
|
506
|
+
const wasUsingTURN = this.usingTURN;
|
|
427
507
|
const selectedIceCandidatePairs = this.selectedIceCandidatePairs;
|
|
508
|
+
const selectedCandidatePairForTurn: ObservedIceCandidatePair[] = [];
|
|
428
509
|
|
|
429
|
-
this.usingTCP =
|
|
430
|
-
this.usingTURN =
|
|
431
|
-
selectedIceCandidatePairs.some((pair) => pair.getRemoteCandidate()?.url?.startsWith('turn:'));
|
|
510
|
+
this.usingTCP = false;
|
|
511
|
+
this.usingTURN = false;
|
|
432
512
|
|
|
513
|
+
for (const selectedCandidatePair of selectedIceCandidatePairs) {
|
|
514
|
+
if (selectedCandidatePair.getLocalCandidate()?.protocol === 'tcp') {
|
|
515
|
+
this.usingTCP = true;
|
|
516
|
+
}
|
|
517
|
+
if (selectedCandidatePair.getLocalCandidate()?.candidateType === 'relay' && selectedCandidatePair.getRemoteCandidate()?.url?.startsWith('turn:')) {
|
|
518
|
+
selectedCandidatePairForTurn.push(selectedCandidatePair);
|
|
519
|
+
this.usingTURN = true;
|
|
520
|
+
}
|
|
521
|
+
this.deltaTransportReceivedBytes += selectedCandidatePair.deltaBytesReceived;
|
|
522
|
+
this.deltaTransportSentBytes += selectedCandidatePair.deltaBytesSent;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (this.usingTURN) {
|
|
526
|
+
if (!this.observedTurnServer) {
|
|
527
|
+
this.observedTurnServer = this.client.call.observer.observedTURN.addPeerConnection(this);
|
|
528
|
+
}
|
|
529
|
+
this.observedTurnServer?.updateTurnUsage(...selectedCandidatePairForTurn);
|
|
530
|
+
} else if (wasUsingTURN) {
|
|
531
|
+
if (!this.usingTURN) {
|
|
532
|
+
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
433
535
|
this.calculatedScore.value = sample.score;
|
|
434
536
|
this.updated = now;
|
|
435
537
|
this._checkVisited();
|
|
538
|
+
|
|
539
|
+
this.emit('update');
|
|
436
540
|
}
|
|
437
541
|
|
|
438
542
|
private _checkVisited() {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { EventEmitter } from 'stream';
|
|
2
|
+
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
3
|
+
import { ObservedTurnServer } from './ObservedTurnServer';
|
|
4
|
+
import { createLogger } from './common/logger';
|
|
5
|
+
|
|
6
|
+
const logger = createLogger('ObservedTURN');
|
|
7
|
+
|
|
8
|
+
export type ObservedTURNEventMap = {
|
|
9
|
+
'update': [ObservedTURN];
|
|
10
|
+
'close': [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export declare interface ObservedTURN {
|
|
14
|
+
on<U extends keyof ObservedTURNEventMap>(event: U, listener: (...args: ObservedTURNEventMap[U]) => void): this;
|
|
15
|
+
off<U extends keyof ObservedTURNEventMap>(event: U, listener: (...args: ObservedTURNEventMap[U]) => void): this;
|
|
16
|
+
once<U extends keyof ObservedTURNEventMap>(event: U, listener: (...args: ObservedTURNEventMap[U]) => void): this;
|
|
17
|
+
emit<U extends keyof ObservedTURNEventMap>(event: U, ...args: ObservedTURNEventMap[U]): boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class ObservedTURN extends EventEmitter {
|
|
21
|
+
public totalBytesSent = 0;
|
|
22
|
+
public totalBytesReceived = 0;
|
|
23
|
+
public totalPacketsSent = 0;
|
|
24
|
+
public totalPacketsReceived = 0;
|
|
25
|
+
|
|
26
|
+
public packetsSentPerSecond = 0;
|
|
27
|
+
public packetsReceivedPerSecond = 0;
|
|
28
|
+
public outboundBitrate = 0;
|
|
29
|
+
public inboundBitrate = 0;
|
|
30
|
+
public numberOfClients = 0;
|
|
31
|
+
|
|
32
|
+
public readonly servers = new Map<string, ObservedTurnServer>();
|
|
33
|
+
|
|
34
|
+
public constructor(
|
|
35
|
+
) {
|
|
36
|
+
super();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public update() {
|
|
40
|
+
const clientIds = new Set<string>();
|
|
41
|
+
|
|
42
|
+
this.packetsReceivedPerSecond = 0;
|
|
43
|
+
this.packetsSentPerSecond = 0;
|
|
44
|
+
this.outboundBitrate = 0;
|
|
45
|
+
this.inboundBitrate = 0;
|
|
46
|
+
|
|
47
|
+
for (const server of this.servers.values()) {
|
|
48
|
+
server.update();
|
|
49
|
+
server.observedPeerConnections.forEach((pc) => clientIds.add(pc.client.clientId));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.numberOfClients = clientIds.size;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public addPeerConnection(peerConnection: ObservedPeerConnection) {
|
|
56
|
+
const turnPairs = peerConnection.selectedIceCandidatePairs.filter((pair) => pair.getLocalCandidate()?.candidateType === 'relay' && pair.getRemoteCandidate()?.url?.startsWith('turn:'));
|
|
57
|
+
|
|
58
|
+
if (turnPairs.length !== 1) {
|
|
59
|
+
return (logger.warn(`Expected exactly one TURN pair, but found for peerconnection ${peerConnection.peerConnectionId}`, turnPairs.length), undefined);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const candidatePair = turnPairs[0];
|
|
63
|
+
const rawUrl = candidatePair.getRemoteCandidate()?.url;
|
|
64
|
+
|
|
65
|
+
if (!rawUrl) {
|
|
66
|
+
return (logger.warn(`No remote candidate URL found for peerconnection ${peerConnection.peerConnectionId}`), undefined);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const turnUrl = new URL(rawUrl);
|
|
70
|
+
const turnServerUrl = `${turnUrl.protocol}//${turnUrl.hostname}:${turnUrl.port}`;
|
|
71
|
+
let turnServer = this.servers.get(turnServerUrl);
|
|
72
|
+
|
|
73
|
+
if (!turnServer) {
|
|
74
|
+
turnServer = new ObservedTurnServer(turnServerUrl, this);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return turnServer;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public removePeerConnection(peerConnection: ObservedPeerConnection) {
|
|
81
|
+
for (const turnServer of this.servers.values()) {
|
|
82
|
+
turnServer.observedPeerConnections.delete(peerConnection.peerConnectionId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ObservedIceCandidatePair } from './ObservedIceCandidatePair';
|
|
2
|
+
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
3
|
+
import { ObservedTURN } from './ObservedTURN';
|
|
4
|
+
|
|
5
|
+
export class ObservedTurnServer {
|
|
6
|
+
public totalBytesSent = 0;
|
|
7
|
+
public totalBytesReceived = 0;
|
|
8
|
+
public totalPacketsSent = 0;
|
|
9
|
+
public totalPacketsReceived = 0;
|
|
10
|
+
|
|
11
|
+
public packetsSentPerSecond = 0;
|
|
12
|
+
public packetsReceivedPerSecond = 0;
|
|
13
|
+
public outboundBitrate = 0;
|
|
14
|
+
public inboundBitrate = 0;
|
|
15
|
+
|
|
16
|
+
public deltaBytesSent = 0;
|
|
17
|
+
public deltaBytesReceived = 0;
|
|
18
|
+
public deltaPacketsSent = 0;
|
|
19
|
+
public deltaPacketsReceived = 0;
|
|
20
|
+
|
|
21
|
+
public readonly observedPeerConnections = new Map<string, ObservedPeerConnection>();
|
|
22
|
+
|
|
23
|
+
public updated = Date.now();
|
|
24
|
+
|
|
25
|
+
public constructor(
|
|
26
|
+
public readonly url: string,
|
|
27
|
+
public readonly observedTURN: ObservedTURN,
|
|
28
|
+
) {
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public updateTurnUsage(...selectedcandidatepairs: ObservedIceCandidatePair[]) {
|
|
33
|
+
for (const selectedcandidatepair of selectedcandidatepairs) {
|
|
34
|
+
this.deltaBytesReceived += selectedcandidatepair.deltaBytesReceived;
|
|
35
|
+
this.deltaBytesSent += selectedcandidatepair.deltaBytesSent;
|
|
36
|
+
this.deltaPacketsReceived += selectedcandidatepair.deltaPacketsReceived;
|
|
37
|
+
this.deltaPacketsSent += selectedcandidatepair.deltaPacketsSent;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public update() {
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
const deltaInS = (now - this.updated) / 1000;
|
|
44
|
+
|
|
45
|
+
this.packetsSentPerSecond = this.deltaPacketsSent / deltaInS;
|
|
46
|
+
this.packetsReceivedPerSecond = this.deltaPacketsReceived / deltaInS;
|
|
47
|
+
this.outboundBitrate = (this.deltaBytesReceived * 8) / deltaInS;
|
|
48
|
+
this.inboundBitrate = (this.deltaBytesSent * 8) / deltaInS;
|
|
49
|
+
|
|
50
|
+
this.totalBytesSent += this.deltaBytesSent;
|
|
51
|
+
this.totalBytesReceived += this.deltaBytesReceived;
|
|
52
|
+
this.totalPacketsSent += this.deltaPacketsSent;
|
|
53
|
+
this.totalPacketsReceived += this.deltaPacketsReceived;
|
|
54
|
+
|
|
55
|
+
this.observedTURN.totalBytesSent += this.deltaBytesSent;
|
|
56
|
+
this.observedTURN.totalBytesReceived += this.deltaBytesReceived;
|
|
57
|
+
this.observedTURN.totalPacketsSent += this.deltaPacketsSent;
|
|
58
|
+
this.observedTURN.totalPacketsReceived += this.deltaPacketsReceived;
|
|
59
|
+
|
|
60
|
+
this.observedTURN.inboundBitrate += this.inboundBitrate;
|
|
61
|
+
this.observedTURN.outboundBitrate += this.outboundBitrate;
|
|
62
|
+
this.observedTURN.packetsReceivedPerSecond += this.packetsReceivedPerSecond;
|
|
63
|
+
this.observedTURN.packetsSentPerSecond += this.packetsSentPerSecond;
|
|
64
|
+
|
|
65
|
+
this.deltaBytesSent = 0;
|
|
66
|
+
this.deltaBytesReceived = 0;
|
|
67
|
+
this.deltaPacketsSent = 0;
|
|
68
|
+
this.deltaPacketsReceived = 0;
|
|
69
|
+
|
|
70
|
+
this.updated = now;
|
|
71
|
+
}
|
|
72
|
+
}
|