@observertc/observer-js 1.0.1-c3edea3.0 → 1.0.1-cda37f7.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 +43 -7
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +129 -13
- package/lib/ObservedCallEventMonitor.d.ts +104 -0
- package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
- package/lib/ObservedCallEventMonitor.js +314 -0
- 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 +392 -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 +6 -1
- package/lib/ObservedIceCandidatePair.d.ts.map +1 -1
- package/lib/ObservedIceCandidatePair.js +45 -1
- 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 +29 -2
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +181 -29
- 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 +43 -22
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +126 -40
- package/lib/ObserverEventMonitor.d.ts +130 -0
- package/lib/ObserverEventMonitor.d.ts.map +1 -0
- package/lib/ObserverEventMonitor.js +404 -0
- 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 +6 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +9 -1
- package/lib/schema/ClientEventTypes.d.ts +160 -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/schema/ClientSample.d.ts +1 -1
- package/lib/schema/ClientSample.d.ts.map +1 -1
- 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 +15 -0
- package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAllCallObserverUpdater.js +50 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts +15 -0
- package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAllClientCallUpdater.js +53 -0
- package/lib/updaters/OnAnyCallObserverUpdater.d.ts +12 -0
- package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAnyCallObserverUpdater.js +37 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts +12 -0
- package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
- package/lib/updaters/OnAnyClientCallUpdater.js +36 -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/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
- package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
- package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
- package/package.json +1 -1
- package/src/ObservedCall.ts +210 -16
- package/src/ObservedCallEventMonitor.ts +392 -0
- package/src/ObservedCallSummary.ts +22 -0
- package/src/ObservedClient.ts +490 -79
- package/src/ObservedClientEventMonitor.ts +301 -0
- package/src/ObservedClientSummary.ts +24 -0
- package/src/ObservedDataChannel.ts +32 -0
- package/src/ObservedIceCandidatePair.ts +44 -2
- package/src/ObservedIceTransport.ts +29 -0
- package/src/ObservedInboundTrack.ts +3 -0
- package/src/ObservedOutboundTrack.ts +3 -0
- package/src/ObservedPeerConnection.ts +210 -46
- package/src/ObservedTURN.ts +86 -0
- package/src/ObservedTurnServer.ts +72 -0
- package/src/Observer.ts +179 -64
- package/src/ObserverEventMonitor.ts +518 -0
- package/src/ObserverSummary.ts +15 -0
- package/src/common/utils.ts +12 -2
- package/src/index.ts +6 -0
- package/src/schema/ClientEventTypes.ts +176 -0
- package/src/schema/{metaTypes.ts → ClientMetaTypes.ts} +1 -1
- package/src/schema/ClientSample.ts +1 -1
- package/src/updaters/ObserverUpdater.ts +5 -0
- package/src/updaters/OnAllCallObserverUpdater.ts +59 -0
- package/src/updaters/OnAllClientCallUpdater.ts +61 -0
- package/src/updaters/OnAnyCallObserverUpdater.ts +41 -0
- package/src/updaters/OnAnyClientCallUpdater.ts +39 -0
- package/src/updaters/OnIntervalUpdater.ts +19 -0
- package/src/updaters/Updater.ts +5 -0
- package/src/utils/MediasoupRemoteTrackResolver.ts +155 -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
package/src/ObservedClient.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
|
3
3
|
import { createLogger } from './common/logger';
|
|
4
4
|
// eslint-disable-next-line camelcase
|
|
5
5
|
import { ClientEvent, ClientMetaData, ClientSample, PeerConnectionSample, ClientIssue, ExtensionStat } from './schema/ClientSample';
|
|
6
|
-
import * as MetaData from './schema/
|
|
7
|
-
import {
|
|
6
|
+
import * as MetaData from './schema/ClientMetaTypes';
|
|
7
|
+
import { ClientEventTypes } from './schema/ClientEventTypes';
|
|
8
8
|
import { ObservedCall } from './ObservedCall';
|
|
9
|
-
import {
|
|
9
|
+
import { ClientMetaTypes } from './schema/ClientMetaTypes';
|
|
10
10
|
import { parseJsonAs } from './common/utils';
|
|
11
11
|
import { CalculatedScore } from './scores/CalculatedScore';
|
|
12
12
|
import { Detectors } from './detectors/Detectors';
|
|
@@ -27,12 +27,15 @@ export type ObservedClientEvents = {
|
|
|
27
27
|
];
|
|
28
28
|
close: [];
|
|
29
29
|
joined: [];
|
|
30
|
+
issue: [ClientIssue];
|
|
31
|
+
metaData: [ClientMetaData];
|
|
30
32
|
rejoined: [timestamp: number];
|
|
31
33
|
left: [];
|
|
32
34
|
usingturn: [boolean];
|
|
33
35
|
usermediaerror: [string];
|
|
36
|
+
extensionStats: [ExtensionStat];
|
|
37
|
+
clientEvent: [ClientEvent];
|
|
34
38
|
|
|
35
|
-
// do we need this?
|
|
36
39
|
newpeerconnection: [ObservedPeerConnection];
|
|
37
40
|
};
|
|
38
41
|
|
|
@@ -53,7 +56,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
53
56
|
value: undefined,
|
|
54
57
|
};
|
|
55
58
|
|
|
56
|
-
public appData
|
|
59
|
+
public appData: AppData;
|
|
57
60
|
public attachments?: Record<string, unknown>;
|
|
58
61
|
|
|
59
62
|
public updated = Date.now();
|
|
@@ -62,6 +65,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
62
65
|
|
|
63
66
|
public joinedAt?: number;
|
|
64
67
|
public leftAt?: number;
|
|
68
|
+
public closedAt?: number;
|
|
65
69
|
// the timestamp of the CLIENT_JOINED event
|
|
66
70
|
public operationSystem?: MetaData.OperationSystem;
|
|
67
71
|
public engine?: MetaData.Engine;
|
|
@@ -70,47 +74,85 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
70
74
|
public mediaConstraints: string[] = [];
|
|
71
75
|
|
|
72
76
|
public usingTURN = false;
|
|
77
|
+
public usingTCP = false;
|
|
73
78
|
public availableOutgoingBitrate = 0;
|
|
74
79
|
public availableIncomingBitrate = 0;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
public
|
|
98
|
-
public
|
|
99
|
-
public
|
|
100
|
-
public
|
|
101
|
-
public
|
|
80
|
+
|
|
81
|
+
public totalInboundPacketsLost = 0;
|
|
82
|
+
public totalInboundPacketsReceived = 0;
|
|
83
|
+
public totalOutboundPacketsSent = 0;
|
|
84
|
+
public totalDataChannelBytesSent = 0;
|
|
85
|
+
public totalDataChannelBytesReceived = 0;
|
|
86
|
+
public totalDataChannelMessagesSent = 0;
|
|
87
|
+
public totalDataChannelMessagesReceived = 0;
|
|
88
|
+
public totalReceivedAudioBytes = 0;
|
|
89
|
+
public totalReceivedVideoBytes = 0;
|
|
90
|
+
public totalSentAudioBytes = 0;
|
|
91
|
+
public totalSentVideoBytes = 0;
|
|
92
|
+
public totalSentBytes = 0;
|
|
93
|
+
public totalReceivedBytes = 0;
|
|
94
|
+
|
|
95
|
+
public deltaReceivedAudioBytes = 0;
|
|
96
|
+
public deltaReceivedVideoBytes = 0;
|
|
97
|
+
public deltaSentAudioBytes = 0;
|
|
98
|
+
public deltaSentVideoBytes = 0;
|
|
99
|
+
public deltaDataChannelBytesSent = 0;
|
|
100
|
+
public deltaDataChannelBytesReceived = 0;
|
|
101
|
+
public deltaDataChannelMessagesSent = 0;
|
|
102
|
+
public deltaDataChannelMessagesReceived = 0;
|
|
103
|
+
public deltaInboundPacketsLost = 0;
|
|
104
|
+
public deltaInboundPacketsReceived = 0;
|
|
105
|
+
public deltaOutboundPacketsSent = 0;
|
|
106
|
+
public deltaTransportSentBytes = 0;
|
|
107
|
+
public deltaTransportReceivedBytes = 0;
|
|
108
|
+
public deltaRttLt50Measurements = 0;
|
|
109
|
+
public deltaRttLt150Measurements = 0;
|
|
110
|
+
public deltaRttLt300Measurements = 0;
|
|
111
|
+
public deltaRttGtOrEq300Measurements = 0;
|
|
112
|
+
|
|
113
|
+
public currentMaxRttInMs?: number;
|
|
114
|
+
public currentMinRttInMs?: number;
|
|
115
|
+
public currentAvgRttInMs?: number;
|
|
116
|
+
|
|
117
|
+
public sendingAudioBitrate = 0;
|
|
118
|
+
public sendingVideoBitrate = 0;
|
|
119
|
+
public receivingAudioBitrate = 0;
|
|
120
|
+
public receivingVideoBitrate = 0;
|
|
121
|
+
|
|
122
|
+
public numberOfInboundRtpStreams = 0;
|
|
123
|
+
public numberOfInbundTracks = 0;
|
|
124
|
+
public numberOfOutboundRtpStreams = 0;
|
|
125
|
+
public numberOfOutboundTracks = 0;
|
|
126
|
+
public numberOfDataChannels = 0;
|
|
127
|
+
|
|
128
|
+
public totalRttLt50Measurements = 0;
|
|
129
|
+
public totalRttLt150Measurements = 0;
|
|
130
|
+
public totalRttLt300Measurements = 0;
|
|
131
|
+
public totalRttGtOrEq300Measurements = 0;
|
|
132
|
+
public deltaNumberOfIssues = 0;
|
|
133
|
+
|
|
134
|
+
public totalScoreSum = 0;
|
|
135
|
+
public numberOfScoreMeasurements = 0;
|
|
136
|
+
public totalNumberOfIssues = 0;
|
|
102
137
|
|
|
103
138
|
public readonly mediaDevices: MetaData.MediaDeviceInfo[] = [];
|
|
104
139
|
public issues: ClientIssue[] = [];
|
|
105
140
|
|
|
141
|
+
private _injections: Pick<ClientSample, 'clientEvents' | 'clientIssues' | 'extensionStats' | 'attachments' | 'clientMetaItems'> = {};
|
|
142
|
+
|
|
106
143
|
public constructor(settings: ObservedClientSettings<AppData>, public readonly call: ObservedCall) {
|
|
107
144
|
super();
|
|
108
145
|
this.setMaxListeners(Infinity);
|
|
109
146
|
|
|
110
147
|
this.clientId = settings.clientId;
|
|
111
|
-
this.appData = settings.appData;
|
|
148
|
+
this.appData = settings.appData ?? {} as AppData;
|
|
149
|
+
|
|
112
150
|
this.detectors = new Detectors();
|
|
113
151
|
}
|
|
152
|
+
|
|
153
|
+
public get numberOfPeerConnections() {
|
|
154
|
+
return this.observedPeerConnections.size;
|
|
155
|
+
}
|
|
114
156
|
|
|
115
157
|
public get score() {
|
|
116
158
|
return this.calculatedScore.value;
|
|
@@ -122,6 +164,8 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
122
164
|
|
|
123
165
|
Array.from(this.observedPeerConnections.values()).forEach((peerConnection) => peerConnection.close());
|
|
124
166
|
|
|
167
|
+
this.closedAt = Date.now();
|
|
168
|
+
|
|
125
169
|
this.emit('close');
|
|
126
170
|
}
|
|
127
171
|
|
|
@@ -129,16 +173,157 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
129
173
|
if (this.closed) throw new Error(`Client ${this.clientId} is closed`);
|
|
130
174
|
|
|
131
175
|
const now = Date.now();
|
|
176
|
+
const elapsedInMs = now - this.updated;
|
|
177
|
+
const elapsedInSeconds = elapsedInMs / 1000;
|
|
178
|
+
let sumOfRtts = 0;
|
|
179
|
+
let numberOfRttMeasurements = 0;
|
|
180
|
+
|
|
181
|
+
++this.acceptedSamples;
|
|
182
|
+
|
|
183
|
+
this.availableIncomingBitrate = 0;
|
|
184
|
+
this.availableOutgoingBitrate = 0;
|
|
185
|
+
this.deltaDataChannelBytesReceived = 0;
|
|
186
|
+
this.deltaDataChannelBytesSent = 0;
|
|
187
|
+
this.deltaDataChannelMessagesReceived = 0;
|
|
188
|
+
this.deltaDataChannelMessagesSent = 0;
|
|
189
|
+
this.deltaInboundPacketsLost = 0;
|
|
190
|
+
this.deltaInboundPacketsReceived = 0;
|
|
191
|
+
this.deltaOutboundPacketsSent = 0;
|
|
192
|
+
this.deltaReceivedAudioBytes = 0;
|
|
193
|
+
this.deltaReceivedVideoBytes = 0;
|
|
194
|
+
this.deltaSentAudioBytes = 0;
|
|
195
|
+
this.deltaSentVideoBytes = 0;
|
|
196
|
+
this.deltaTransportReceivedBytes = 0;
|
|
197
|
+
this.deltaTransportSentBytes = 0;
|
|
198
|
+
this.deltaRttLt50Measurements = 0;
|
|
199
|
+
this.deltaRttLt150Measurements = 0;
|
|
200
|
+
this.deltaRttLt300Measurements = 0;
|
|
201
|
+
this.deltaRttGtOrEq300Measurements = 0;
|
|
202
|
+
this.deltaNumberOfIssues = 0;
|
|
203
|
+
|
|
204
|
+
this.numberOfDataChannels = 0;
|
|
205
|
+
this.numberOfInboundRtpStreams = 0;
|
|
206
|
+
this.numberOfInbundTracks = 0;
|
|
207
|
+
this.numberOfOutboundRtpStreams = 0;
|
|
208
|
+
this.numberOfOutboundTracks = 0;
|
|
209
|
+
this.usingTURN = false;
|
|
210
|
+
this.usingTCP = false;
|
|
211
|
+
this.currentMinRttInMs = undefined;
|
|
212
|
+
this.currentMaxRttInMs = undefined;
|
|
213
|
+
|
|
214
|
+
this._mergeInjections(sample);
|
|
215
|
+
|
|
216
|
+
const clientEventsPostBuffer: ClientEvent[] = [];
|
|
217
|
+
|
|
218
|
+
for (const clientEvent of sample.clientEvents ?? []) {
|
|
219
|
+
this._processClientEvent(clientEvent, clientEventsPostBuffer);
|
|
220
|
+
|
|
221
|
+
this.call.observer.emit('client-event', this, clientEvent);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
for (const metaData of sample.clientMetaItems ?? []) {
|
|
225
|
+
this.addMetadata(metaData);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
for (const issue of sample.clientIssues ?? []) {
|
|
229
|
+
this.addIssue(issue);
|
|
230
|
+
|
|
231
|
+
++this.deltaNumberOfIssues;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
for (const extensionStat of sample.extensionStats ?? []) {
|
|
235
|
+
this.addExtensionStats(extensionStat);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
for (const pcSample of sample.peerConnections ?? []) {
|
|
239
|
+
const observedPeerConnection = this._updatePeerConnection(pcSample);
|
|
240
|
+
|
|
241
|
+
if (!observedPeerConnection) continue;
|
|
242
|
+
|
|
243
|
+
this.deltaDataChannelBytesReceived += observedPeerConnection.deltaDataChannelBytesReceived;
|
|
244
|
+
this.deltaDataChannelBytesSent += observedPeerConnection.deltaDataChannelBytesSent;
|
|
245
|
+
this.deltaDataChannelMessagesReceived += observedPeerConnection.deltaDataChannelMessagesReceived;
|
|
246
|
+
this.deltaDataChannelMessagesSent += observedPeerConnection.deltaDataChannelMessagesSent;
|
|
247
|
+
this.deltaInboundPacketsLost += observedPeerConnection.deltaInboundPacketsLost;
|
|
248
|
+
this.deltaInboundPacketsReceived += observedPeerConnection.deltaInboundPacketsReceived;
|
|
249
|
+
this.deltaOutboundPacketsSent += observedPeerConnection.deltaOutboundPacketsSent;
|
|
250
|
+
this.deltaReceivedAudioBytes += observedPeerConnection.deltaReceivedAudioBytes;
|
|
251
|
+
this.deltaReceivedVideoBytes += observedPeerConnection.deltaReceivedVideoBytes;
|
|
252
|
+
this.deltaSentAudioBytes += observedPeerConnection.deltaSentAudioBytes;
|
|
253
|
+
this.deltaSentVideoBytes += observedPeerConnection.deltaSentVideoBytes;
|
|
254
|
+
this.deltaTransportReceivedBytes += observedPeerConnection.deltaTransportReceivedBytes;
|
|
255
|
+
this.deltaTransportSentBytes += observedPeerConnection.deltaTransportSentBytes;
|
|
256
|
+
|
|
257
|
+
this.availableIncomingBitrate += observedPeerConnection.availableIncomingBitrate;
|
|
258
|
+
this.availableOutgoingBitrate += observedPeerConnection.availableOutgoingBitrate;
|
|
259
|
+
|
|
260
|
+
this.numberOfDataChannels += observedPeerConnection.observedDataChannels.size;
|
|
261
|
+
this.numberOfInbundTracks += observedPeerConnection.observedInboundTracks.size;
|
|
262
|
+
this.numberOfOutboundRtpStreams += observedPeerConnection.observedOutboundRtps.size;
|
|
263
|
+
this.numberOfOutboundTracks += observedPeerConnection.observedOutboundTracks.size;
|
|
264
|
+
this.numberOfInboundRtpStreams += observedPeerConnection.observedInboundRtps.size;
|
|
265
|
+
|
|
266
|
+
if (observedPeerConnection.usingTURN) {
|
|
267
|
+
this.usingTURN = true;
|
|
268
|
+
}
|
|
269
|
+
if (observedPeerConnection.usingTCP) {
|
|
270
|
+
this.usingTCP = true;
|
|
271
|
+
}
|
|
132
272
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
273
|
+
if (observedPeerConnection.currentRttInMs) {
|
|
274
|
+
if (this.currentMinRttInMs === undefined || observedPeerConnection.currentRttInMs < this.currentMinRttInMs) {
|
|
275
|
+
this.currentMinRttInMs = observedPeerConnection.currentRttInMs;
|
|
276
|
+
}
|
|
277
|
+
if (this.currentMaxRttInMs === undefined || observedPeerConnection.currentRttInMs > this.currentMaxRttInMs) {
|
|
278
|
+
this.currentMaxRttInMs = observedPeerConnection.currentRttInMs;
|
|
279
|
+
}
|
|
280
|
+
if (observedPeerConnection.currentRttInMs < 50) {
|
|
281
|
+
this.deltaRttLt50Measurements += 1;
|
|
282
|
+
} else if (observedPeerConnection.currentRttInMs < 150) {
|
|
283
|
+
this.deltaRttLt150Measurements += 1;
|
|
284
|
+
} else if (observedPeerConnection.currentRttInMs < 300) {
|
|
285
|
+
this.deltaRttLt300Measurements += 1;
|
|
286
|
+
} else if (300 <= observedPeerConnection.currentRttInMs) {
|
|
287
|
+
this.deltaRttGtOrEq300Measurements += 1;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
sumOfRtts += observedPeerConnection.currentRttInMs;
|
|
291
|
+
++numberOfRttMeasurements;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
for (const clientEvent of clientEventsPostBuffer) {
|
|
296
|
+
this._processClientEvent(clientEvent);
|
|
297
|
+
}
|
|
138
298
|
|
|
139
299
|
// emit new attachments?
|
|
140
300
|
this.attachments = sample.attachments;
|
|
141
301
|
|
|
302
|
+
this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
303
|
+
this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
304
|
+
this.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
|
|
305
|
+
this.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
|
|
306
|
+
this.totalInboundPacketsLost += this.deltaInboundPacketsLost;
|
|
307
|
+
this.totalInboundPacketsReceived += this.deltaInboundPacketsReceived;
|
|
308
|
+
this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
|
|
309
|
+
this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
|
|
310
|
+
this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
|
|
311
|
+
this.totalSentAudioBytes += this.deltaSentAudioBytes;
|
|
312
|
+
this.totalSentVideoBytes += this.deltaSentVideoBytes;
|
|
313
|
+
this.totalReceivedBytes += this.deltaTransportReceivedBytes;
|
|
314
|
+
this.totalSentBytes += this.deltaTransportSentBytes;
|
|
315
|
+
this.totalRttLt50Measurements += this.deltaRttLt50Measurements;
|
|
316
|
+
this.totalRttLt150Measurements += this.deltaRttLt150Measurements;
|
|
317
|
+
this.totalRttLt300Measurements += this.deltaRttLt300Measurements;
|
|
318
|
+
this.totalRttGtOrEq300Measurements += this.deltaRttGtOrEq300Measurements;
|
|
319
|
+
this.totalNumberOfIssues += this.deltaNumberOfIssues;
|
|
320
|
+
|
|
321
|
+
this.receivingAudioBitrate = (this.deltaReceivedAudioBytes * 8) / (elapsedInSeconds);
|
|
322
|
+
this.receivingVideoBitrate = (this.totalReceivedVideoBytes * 8) / (elapsedInSeconds);
|
|
323
|
+
this.sendingAudioBitrate = (this.deltaSentAudioBytes * 8) / (elapsedInSeconds);
|
|
324
|
+
this.sendingVideoBitrate = (this.deltaSentVideoBytes * 8) / (elapsedInSeconds);
|
|
325
|
+
this.currentAvgRttInMs = 0 < numberOfRttMeasurements ? sumOfRtts / numberOfRttMeasurements : undefined;
|
|
326
|
+
|
|
142
327
|
this.calculatedScore.value = sample.score;
|
|
143
328
|
this.detectors.update();
|
|
144
329
|
|
|
@@ -148,19 +333,19 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
148
333
|
elapsedTimeInMs: now - this.updated,
|
|
149
334
|
});
|
|
150
335
|
this.updated = now;
|
|
336
|
+
|
|
337
|
+
// if result changed after update
|
|
338
|
+
if (this.calculatedScore.value) {
|
|
339
|
+
this.totalScoreSum += this.calculatedScore.value;
|
|
340
|
+
++this.numberOfScoreMeasurements;
|
|
341
|
+
}
|
|
151
342
|
}
|
|
152
343
|
|
|
153
|
-
private _processClientEvent(event: ClientEvent) {
|
|
344
|
+
private _processClientEvent(event: ClientEvent, postBuffer?: ClientEvent[]) {
|
|
345
|
+
// eslint-disable-next-line no-console
|
|
346
|
+
// console.warn('ClientEvent', event);
|
|
154
347
|
switch (event.type) {
|
|
155
|
-
case
|
|
156
|
-
// update call timestamp if it's the first time
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
case ClientEventType.CALL_ENDED: {
|
|
160
|
-
// update call timestamp if it's the first time
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
case ClientEventType.CLIENT_JOINED: {
|
|
348
|
+
case ClientEventTypes.CLIENT_JOINED: {
|
|
164
349
|
if (event.timestamp) {
|
|
165
350
|
if (!this.joinedAt) {
|
|
166
351
|
this.joinedAt = event.timestamp;
|
|
@@ -174,76 +359,209 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
174
359
|
}
|
|
175
360
|
break;
|
|
176
361
|
}
|
|
177
|
-
case
|
|
362
|
+
case ClientEventTypes.CLIENT_LEFT: {
|
|
178
363
|
if (event.timestamp) {
|
|
179
364
|
if (!this.leftAt) {
|
|
180
365
|
this.leftAt = event.timestamp;
|
|
181
366
|
this.emit('left');
|
|
367
|
+
} else {
|
|
368
|
+
logger.warn(`Client ${this.clientId} leftAt timestamp was already set`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
case ClientEventTypes.PEER_CONNECTION_OPENED: {
|
|
374
|
+
const payload = parseJsonAs<Record<string, unknown>>(event.payload);
|
|
375
|
+
|
|
376
|
+
if (payload?.peerConnectionId && typeof payload.peerConnectionId === 'string') {
|
|
377
|
+
const observedPeerConnection = this.observedPeerConnections.get(payload.peerConnectionId);
|
|
378
|
+
|
|
379
|
+
if (observedPeerConnection) {
|
|
380
|
+
observedPeerConnection.openedAt = event.timestamp;
|
|
381
|
+
} else if (postBuffer) {
|
|
382
|
+
postBuffer.push(event);
|
|
383
|
+
} else {
|
|
384
|
+
logger.warn('Received PEER_CONNECTION_OPENED event without a corresponding observedPeerConnection', event);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
}
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
case ClientEventTypes.PEER_CONNECTION_CLOSED: {
|
|
391
|
+
const payload = parseJsonAs<Record<string, unknown>>(event.payload);
|
|
392
|
+
|
|
393
|
+
if (payload?.peerConnectionId && typeof payload.peerConnectionId === 'string') {
|
|
394
|
+
const observedPeerConnection = this.observedPeerConnections.get(payload.peerConnectionId);
|
|
395
|
+
|
|
396
|
+
if (observedPeerConnection) {
|
|
397
|
+
observedPeerConnection.closedAt = event.timestamp;
|
|
398
|
+
} else if (postBuffer) {
|
|
399
|
+
postBuffer.push(event);
|
|
400
|
+
} else {
|
|
401
|
+
logger.warn('Received PEER_CONNECTION_CLOSED event without a corresponding observedPeerConnection', event);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
case ClientEventTypes.MEDIA_TRACK_ADDED: {
|
|
407
|
+
const payload = parseJsonAs<Record<string, unknown>>(event.payload);
|
|
408
|
+
|
|
409
|
+
if (payload?.peerConnectionId && typeof payload.peerConnectionId === 'string' && payload?.trackId && typeof payload.trackId === 'string') {
|
|
410
|
+
const observedPeerConnection = this.observedPeerConnections.get(payload.peerConnectionId);
|
|
411
|
+
const observedTrack = observedPeerConnection?.observedInboundTracks.get(payload.trackId) ?? observedPeerConnection?.observedOutboundTracks.get(payload.trackId);
|
|
412
|
+
|
|
413
|
+
if (observedTrack) {
|
|
414
|
+
observedTrack.addedAt = event.timestamp;
|
|
415
|
+
} else if (postBuffer) {
|
|
416
|
+
postBuffer.push(event);
|
|
417
|
+
} else {
|
|
418
|
+
logger.warn('Received MEDIA_TRACK_ADDED event without a corresponding observedPeerConnection or observedTrack', event);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
case ClientEventTypes.MEDIA_TRACK_REMOVED: {
|
|
424
|
+
const payload = parseJsonAs<Record<string, unknown>>(event.payload);
|
|
425
|
+
|
|
426
|
+
if (payload?.peerConnectionId && typeof payload.peerConnectionId === 'string' && payload?.trackId && typeof payload.trackId === 'string') {
|
|
427
|
+
const observedPeerConnection = this.observedPeerConnections.get(payload.peerConnectionId);
|
|
428
|
+
const observedTrack = observedPeerConnection?.observedInboundTracks.get(payload.trackId) ?? observedPeerConnection?.observedOutboundTracks.get(payload.trackId);
|
|
429
|
+
|
|
430
|
+
if (observedTrack) {
|
|
431
|
+
observedTrack.removedAt = event.timestamp;
|
|
432
|
+
} else if (postBuffer) {
|
|
433
|
+
postBuffer.push(event);
|
|
434
|
+
} else {
|
|
435
|
+
logger.warn('Received MEDIA_TRACK_REMOVED event without a corresponding observedPeerConnection or observedTrack', event);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
case ClientEventTypes.DATA_CHANNEL_OPEN: {
|
|
441
|
+
const payload = parseJsonAs<Record<string, unknown>>(event.payload);
|
|
442
|
+
|
|
443
|
+
if (payload?.peerConnectionId && typeof payload.peerConnectionId === 'string' && payload?.dataChannelId && typeof payload.dataChannelId === 'string') {
|
|
444
|
+
const observedPeerConnection = this.observedPeerConnections.get(payload.peerConnectionId);
|
|
445
|
+
const observedDataChannel = observedPeerConnection?.observedDataChannels.get(payload.dataChannelId);
|
|
446
|
+
|
|
447
|
+
if (observedDataChannel) {
|
|
448
|
+
observedDataChannel.addedAt = event.timestamp;
|
|
449
|
+
} else if (postBuffer) {
|
|
450
|
+
postBuffer.push(event);
|
|
451
|
+
} else {
|
|
452
|
+
logger.warn('Received DATA_CHANNEL_OPENED event without a corresponding observedPeerConnection or observedDataChannel', event);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
case ClientEventTypes.DATA_CHANNEL_CLOSED: {
|
|
458
|
+
const payload = parseJsonAs<Record<string, unknown>>(event.payload);
|
|
459
|
+
|
|
460
|
+
if (payload?.peerConnectionId && typeof payload.peerConnectionId === 'string' && payload?.dataChannelId && typeof payload.dataChannelId === 'string') {
|
|
461
|
+
const observedPeerConnection = this.observedPeerConnections.get(payload.peerConnectionId);
|
|
462
|
+
const observedDataChannel = observedPeerConnection?.observedDataChannels.get(payload.dataChannelId);
|
|
463
|
+
|
|
464
|
+
if (observedDataChannel) {
|
|
465
|
+
observedDataChannel.removedAt = event.timestamp;
|
|
466
|
+
} else if (postBuffer) {
|
|
467
|
+
postBuffer.push(event);
|
|
468
|
+
} else {
|
|
469
|
+
logger.warn('Received DATA_CHANNEL_CLOSE event without a corresponding observedPeerConnection or observedDataChannel', event);
|
|
182
470
|
}
|
|
183
471
|
}
|
|
184
472
|
break;
|
|
185
473
|
}
|
|
186
474
|
}
|
|
475
|
+
this.emit('clientEvent', event);
|
|
476
|
+
}
|
|
187
477
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
478
|
+
public injectMetaData(metaData: ClientMetaData) {
|
|
479
|
+
if (this.closed) return;
|
|
480
|
+
|
|
481
|
+
if (!this._injections.clientMetaItems) this._injections.clientMetaItems = [];
|
|
482
|
+
|
|
483
|
+
this._injections.clientMetaItems.push(metaData);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
public injectEvent(event: ClientEvent) {
|
|
487
|
+
if (this.closed) return;
|
|
488
|
+
|
|
489
|
+
if (!this._injections.clientEvents) this._injections.clientEvents = [];
|
|
490
|
+
|
|
491
|
+
this._injections.clientEvents.push(event);
|
|
193
492
|
}
|
|
194
493
|
|
|
195
|
-
public
|
|
494
|
+
public injectIssue(issue: ClientIssue) {
|
|
495
|
+
if (this.closed) return;
|
|
496
|
+
|
|
497
|
+
if (!this._injections.clientIssues) this._injections.clientIssues = [];
|
|
498
|
+
|
|
499
|
+
this._injections.clientIssues.push(issue);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
public injectExtensionStat(stat: ExtensionStat) {
|
|
503
|
+
if (this.closed) return;
|
|
504
|
+
|
|
505
|
+
if (!this._injections.extensionStats) this._injections.extensionStats = [];
|
|
506
|
+
|
|
507
|
+
this._injections.extensionStats.push(stat);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
public injectAttachment(key: string, value: unknown) {
|
|
511
|
+
if (this.closed) return;
|
|
512
|
+
|
|
513
|
+
if (!this._injections.attachments) this._injections.attachments = {};
|
|
514
|
+
|
|
515
|
+
this._injections.attachments[key] = value;
|
|
516
|
+
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
public addMetadata(metadata: ClientMetaData) {
|
|
520
|
+
if (this.closed) return;
|
|
521
|
+
|
|
196
522
|
switch (metadata.type) {
|
|
197
|
-
case
|
|
523
|
+
case ClientMetaTypes.BROWSER: {
|
|
198
524
|
this.browser = parseJsonAs(metadata.payload);
|
|
199
525
|
break;
|
|
200
526
|
}
|
|
201
|
-
case
|
|
527
|
+
case ClientMetaTypes.ENGINE: {
|
|
202
528
|
this.engine = parseJsonAs(metadata.payload);
|
|
203
529
|
break;
|
|
204
530
|
}
|
|
205
|
-
case
|
|
531
|
+
case ClientMetaTypes.PLATFORM: {
|
|
206
532
|
this.platform = parseJsonAs(metadata.payload);
|
|
207
533
|
break;
|
|
208
534
|
}
|
|
209
|
-
case
|
|
535
|
+
case ClientMetaTypes.OPERATION_SYSTEM: {
|
|
210
536
|
this.operationSystem = parseJsonAs(metadata.payload);
|
|
211
537
|
break;
|
|
212
538
|
}
|
|
213
539
|
}
|
|
214
540
|
|
|
215
|
-
this.call.observer.
|
|
216
|
-
call: this.call,
|
|
217
|
-
client: this,
|
|
218
|
-
data: metadata,
|
|
219
|
-
});
|
|
541
|
+
this.call.observer.emit('client-metadata', this, metadata);
|
|
220
542
|
}
|
|
221
543
|
|
|
222
|
-
public
|
|
223
|
-
this.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
});
|
|
544
|
+
public addIssue(issue: ClientIssue) {
|
|
545
|
+
if (this.closed) return;
|
|
546
|
+
|
|
547
|
+
this.emit('issue', issue);
|
|
548
|
+
this.call.observer.emit('client-issue', this, issue);
|
|
228
549
|
}
|
|
229
550
|
|
|
230
|
-
public
|
|
231
|
-
this.call.observer.
|
|
232
|
-
|
|
233
|
-
client: this,
|
|
234
|
-
data: stats,
|
|
235
|
-
});
|
|
551
|
+
public addExtensionStats(stats: ExtensionStat) {
|
|
552
|
+
this.call.observer.emit('client-extension-stats', this, stats);
|
|
553
|
+
this.emit('extensionStats', stats);
|
|
236
554
|
}
|
|
237
555
|
|
|
238
|
-
private _updatePeerConnection(sample: PeerConnectionSample) {
|
|
556
|
+
private _updatePeerConnection(sample: PeerConnectionSample): ObservedPeerConnection | undefined {
|
|
239
557
|
let observedPeerConnection = this.observedPeerConnections.get(sample.peerConnectionId);
|
|
240
558
|
|
|
241
559
|
if (!observedPeerConnection) {
|
|
242
560
|
if (!sample.peerConnectionId) {
|
|
243
|
-
return logger.warn(
|
|
561
|
+
return (logger.warn(
|
|
244
562
|
`ObservedClient received an invalid PeerConnectionSample (missing peerConnectionId field). ClientId: ${this.clientId}, CallId: ${this.call.callId}`,
|
|
245
563
|
sample
|
|
246
|
-
);
|
|
564
|
+
), void 0);
|
|
247
565
|
}
|
|
248
566
|
|
|
249
567
|
observedPeerConnection = new ObservedPeerConnection(sample.peerConnectionId, this);
|
|
@@ -252,8 +570,101 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
252
570
|
this.observedPeerConnections.delete(sample.peerConnectionId);
|
|
253
571
|
});
|
|
254
572
|
this.observedPeerConnections.set(sample.peerConnectionId, observedPeerConnection);
|
|
573
|
+
|
|
574
|
+
this.emit('newpeerconnection', observedPeerConnection);
|
|
255
575
|
}
|
|
256
576
|
|
|
257
577
|
observedPeerConnection.accept(sample);
|
|
578
|
+
|
|
579
|
+
return observedPeerConnection;
|
|
258
580
|
}
|
|
581
|
+
|
|
582
|
+
private _mergeInjections(sample: ClientSample): ClientSample {
|
|
583
|
+
if (this.closed) return sample;
|
|
584
|
+
|
|
585
|
+
if (this._injections.clientEvents) {
|
|
586
|
+
if (!sample.clientEvents) sample.clientEvents = [];
|
|
587
|
+
sample.clientEvents.push(...this._injections.clientEvents);
|
|
588
|
+
|
|
589
|
+
this._injections.clientEvents = undefined;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (this._injections.clientIssues) {
|
|
593
|
+
if (!sample.clientIssues) sample.clientIssues = [];
|
|
594
|
+
sample.clientIssues.push(...this._injections.clientIssues);
|
|
595
|
+
|
|
596
|
+
this._injections.clientIssues = undefined;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (this._injections.extensionStats) {
|
|
600
|
+
if (!sample.extensionStats) sample.extensionStats = [];
|
|
601
|
+
sample.extensionStats.push(...this._injections.extensionStats);
|
|
602
|
+
|
|
603
|
+
this._injections.extensionStats = undefined;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (this._injections.attachments) {
|
|
607
|
+
if (!sample.attachments) sample.attachments = {};
|
|
608
|
+
Object.assign(sample.attachments, this._injections.attachments);
|
|
609
|
+
|
|
610
|
+
this._injections.attachments = undefined;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (this._injections.clientMetaItems) {
|
|
614
|
+
if (!sample.clientMetaItems) sample.clientMetaItems = [];
|
|
615
|
+
sample.clientMetaItems.push(...this._injections.clientMetaItems);
|
|
616
|
+
|
|
617
|
+
this._injections.clientMetaItems = undefined;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return sample;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// public resetSummaryMetrics() {
|
|
624
|
+
// this.totalDataChannelBytesReceived = 0;
|
|
625
|
+
// this.totalDataChannelBytesSent = 0;
|
|
626
|
+
// this.totalDataChannelMessagesReceived = 0;
|
|
627
|
+
// this.totalDataChannelMessagesSent = 0;
|
|
628
|
+
// this.totalInboundPacketsLost = 0;
|
|
629
|
+
// this.totalInboundPacketsReceived = 0;
|
|
630
|
+
// this.totalOutboundPacketsSent = 0;
|
|
631
|
+
// this.totalReceivedAudioBytes = 0;
|
|
632
|
+
// this.totalReceivedVideoBytes = 0;
|
|
633
|
+
// this.totalSentAudioBytes = 0;
|
|
634
|
+
// this.totalSentVideoBytes = 0;
|
|
635
|
+
// this.totalSentBytes = 0;
|
|
636
|
+
// this.totalReceivedBytes = 0;
|
|
637
|
+
|
|
638
|
+
// this.totalNumberOfIssues = 0;
|
|
639
|
+
|
|
640
|
+
// this.totalScoreSum = 0;
|
|
641
|
+
// this.numberOfScoreMeasurements = 0;
|
|
642
|
+
// }
|
|
643
|
+
|
|
644
|
+
// public createSummary(): ObservedClientSummary {
|
|
645
|
+
// return {
|
|
646
|
+
// totalRttLt50Measurements: this.totalRttLt50Measurements,
|
|
647
|
+
// totalRttLt150Measurements: this.totalRttLt150Measurements,
|
|
648
|
+
// totalRttLt300Measurements: this.totalRttLt300Measurements,
|
|
649
|
+
// totalRttGtOrEq300Measurements: this.totalRttGtOrEq300Measurements,
|
|
650
|
+
// totalDataChannelBytesReceived: this.totalDataChannelBytesReceived,
|
|
651
|
+
// totalDataChannelBytesSent: this.totalDataChannelBytesSent,
|
|
652
|
+
// totalDataChannelMessagesReceived: this.totalDataChannelMessagesReceived,
|
|
653
|
+
// totalDataChannelMessagesSent: this.totalDataChannelMessagesSent,
|
|
654
|
+
// totalInboundPacketsLost: this.totalInboundPacketsLost,
|
|
655
|
+
// totalInboundPacketsReceived: this.totalInboundPacketsReceived,
|
|
656
|
+
// totalOutboundPacketsSent: this.totalOutboundPacketsSent,
|
|
657
|
+
// totalReceivedAudioBytes: this.totalReceivedAudioBytes,
|
|
658
|
+
// totalReceivedVideoBytes: this.totalReceivedVideoBytes,
|
|
659
|
+
// totalSentAudioBytes: this.totalSentAudioBytes,
|
|
660
|
+
// totalSentVideoBytes: this.totalSentVideoBytes,
|
|
661
|
+
// totalSentBytes: this.totalSentBytes,
|
|
662
|
+
// totalReceivedBytes: this.totalReceivedBytes,
|
|
663
|
+
|
|
664
|
+
// numberOfIssues: this.totalNumberOfIssues,
|
|
665
|
+
|
|
666
|
+
// totalScoreSum: this.totalScoreSum,
|
|
667
|
+
// numberOfScoreMeasurements: this.numberOfScoreMeasurements,
|
|
668
|
+
// };
|
|
669
|
+
// }
|
|
259
670
|
}
|