@observertc/observer-js 1.0.1-57a1811.0 → 1.0.1-c3edea3.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 +0 -13
- package/lib/ObservedCall.d.ts.map +1 -1
- package/lib/ObservedCall.js +1 -37
- package/lib/ObservedClient.d.ts +7 -39
- package/lib/ObservedClient.d.ts.map +1 -1
- package/lib/ObservedClient.js +58 -110
- package/lib/ObservedDataChannel.d.ts +0 -4
- package/lib/ObservedDataChannel.d.ts.map +1 -1
- package/lib/ObservedDataChannel.js +0 -28
- package/lib/ObservedIceCandidatePair.d.ts +0 -4
- package/lib/ObservedIceCandidatePair.d.ts.map +1 -1
- package/lib/ObservedIceCandidatePair.js +0 -28
- package/lib/ObservedPeerConnection.d.ts +0 -10
- package/lib/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/ObservedPeerConnection.js +9 -79
- package/lib/Observer.d.ts +21 -27
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +40 -59
- package/lib/index.d.ts +0 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -5
- package/lib/schema/{ClientEventTypes.d.ts → eventTypes.d.ts} +2 -2
- package/lib/schema/eventTypes.d.ts.map +1 -0
- package/lib/schema/eventTypes.js +38 -0
- package/lib/schema/{ClientMetaTypes.d.ts → metaTypes.d.ts} +2 -2
- package/lib/schema/metaTypes.d.ts.map +1 -0
- package/lib/schema/metaTypes.js +16 -0
- package/package.json +1 -1
- package/src/ObservedCall.ts +1 -44
- package/src/ObservedClient.ts +60 -125
- package/src/ObservedDataChannel.ts +0 -29
- package/src/ObservedIceCandidatePair.ts +0 -26
- package/src/ObservedPeerConnection.ts +10 -90
- package/src/Observer.ts +68 -81
- package/src/index.ts +0 -4
- package/src/schema/{ClientEventTypes.ts → eventTypes.ts} +1 -1
- package/src/schema/{ClientMetaTypes.ts → metaTypes.ts} +1 -1
- package/lib/ObservedTURN.d.ts +0 -31
- package/lib/ObservedTURN.d.ts.map +0 -1
- package/lib/ObservedTURN.js +0 -58
- package/lib/ObservedTurnServer.d.ts +0 -25
- package/lib/ObservedTurnServer.d.ts.map +0 -1
- package/lib/ObservedTurnServer.js +0 -59
- package/lib/schema/ClientEventTypes.d.ts.map +0 -1
- package/lib/schema/ClientEventTypes.js +0 -38
- package/lib/schema/ClientMetaTypes.d.ts.map +0 -1
- package/lib/schema/ClientMetaTypes.js +0 -16
- package/src/ObservedTURN.ts +0 -86
- package/src/ObservedTurnServer.ts +0 -72
package/src/ObservedCall.ts
CHANGED
|
@@ -43,20 +43,6 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
43
43
|
public remoteTrackResolver?: RemoteTrackResolver;
|
|
44
44
|
public callUpdater?: CallUpdater;
|
|
45
45
|
|
|
46
|
-
public totalAudioBytesSent = 0;
|
|
47
|
-
public totalAudioBytesReceived = 0;
|
|
48
|
-
public totalVideoBytesSent = 0;
|
|
49
|
-
public totalVideoBytesReceived = 0;
|
|
50
|
-
public totalDataChannelBytesSent = 0;
|
|
51
|
-
public totalDataChannelBytesReceived = 0;
|
|
52
|
-
|
|
53
|
-
public numberOfPeerConnections = 0;
|
|
54
|
-
public numberOfInboundRtpStreams = 0;
|
|
55
|
-
public numberOfOutboundRtpStreams = 0;
|
|
56
|
-
public numberOfDataChannels = 0;
|
|
57
|
-
|
|
58
|
-
public maxNumberOfClients = 0;
|
|
59
|
-
|
|
60
46
|
public appData?: AppData;
|
|
61
47
|
public closed = false;
|
|
62
48
|
public started?: number;
|
|
@@ -90,10 +76,6 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
90
76
|
}
|
|
91
77
|
}
|
|
92
78
|
|
|
93
|
-
public get numberOfClients() {
|
|
94
|
-
return this.observedClients.size;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
79
|
public get score() {
|
|
98
80
|
return this.calculatedScore.value;
|
|
99
81
|
}
|
|
@@ -119,7 +101,7 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
119
101
|
|
|
120
102
|
const result = new ObservedClient<ClientAppData>(settings, this);
|
|
121
103
|
const wasEmpty = this.observedClients.size === 0;
|
|
122
|
-
const onUpdate = () => this.
|
|
104
|
+
const onUpdate = () => this.callUpdater?.onClientUpdate(result);
|
|
123
105
|
|
|
124
106
|
result.once('close', () => {
|
|
125
107
|
result.off('update', onUpdate);
|
|
@@ -132,7 +114,6 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
132
114
|
result.on('update', onUpdate);
|
|
133
115
|
|
|
134
116
|
this.observedClients.set(settings.clientId, result);
|
|
135
|
-
this.maxNumberOfClients = Math.max(this.maxNumberOfClients, this.observedClients.size);
|
|
136
117
|
|
|
137
118
|
this.emit('newclient', result);
|
|
138
119
|
|
|
@@ -144,33 +125,9 @@ export class ObservedCall<AppData extends Record<string, unknown> = Record<strin
|
|
|
144
125
|
}
|
|
145
126
|
|
|
146
127
|
public update() {
|
|
147
|
-
if (this.closed) return;
|
|
148
|
-
|
|
149
|
-
this.numberOfInboundRtpStreams = 0;
|
|
150
|
-
this.numberOfOutboundRtpStreams = 0;
|
|
151
|
-
this.numberOfPeerConnections = 0;
|
|
152
|
-
this.numberOfDataChannels = 0;
|
|
153
|
-
|
|
154
|
-
for (const client of this.observedClients.values()) {
|
|
155
|
-
this.numberOfInboundRtpStreams += client.numberOfInboundRtpStreams;
|
|
156
|
-
this.numberOfOutboundRtpStreams += client.numberOfOutboundRtpStreams;
|
|
157
|
-
this.numberOfPeerConnections += client.numberOfPeerConnections;
|
|
158
|
-
this.numberOfDataChannels += client.numberOfDataChannels;
|
|
159
|
-
}
|
|
160
128
|
this.detectors.update();
|
|
161
129
|
this.scoreCalculator.update();
|
|
162
130
|
|
|
163
131
|
this.emit('update');
|
|
164
132
|
}
|
|
165
|
-
|
|
166
|
-
private _onClientUpdate(client: ObservedClient) {
|
|
167
|
-
this.callUpdater?.onClientUpdate(client);
|
|
168
|
-
|
|
169
|
-
this.totalAudioBytesReceived = client.deltaReceivedAudioBytes;
|
|
170
|
-
this.totalAudioBytesSent = client.deltaSentAudioBytes;
|
|
171
|
-
this.totalVideoBytesReceived = client.deltaReceivedVideoBytes;
|
|
172
|
-
this.totalVideoBytesSent = client.deltaSentVideoBytes;
|
|
173
|
-
this.totalDataChannelBytesReceived = client.deltaDataChannelBytesReceived;
|
|
174
|
-
this.totalDataChannelBytesSent = client.deltaDataChannelBytesSent;
|
|
175
|
-
}
|
|
176
133
|
}
|
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/metaTypes';
|
|
7
|
+
import { ClientEventType } from './schema/eventTypes';
|
|
8
8
|
import { ObservedCall } from './ObservedCall';
|
|
9
|
-
import {
|
|
9
|
+
import { ClientMetaType } from './schema/metaTypes';
|
|
10
10
|
import { parseJsonAs } from './common/utils';
|
|
11
11
|
import { CalculatedScore } from './scores/CalculatedScore';
|
|
12
12
|
import { Detectors } from './detectors/Detectors';
|
|
@@ -27,8 +27,6 @@ export type ObservedClientEvents = {
|
|
|
27
27
|
];
|
|
28
28
|
close: [];
|
|
29
29
|
joined: [];
|
|
30
|
-
issue: [ClientIssue];
|
|
31
|
-
metaData: [ClientMetaData];
|
|
32
30
|
rejoined: [timestamp: number];
|
|
33
31
|
left: [];
|
|
34
32
|
usingturn: [boolean];
|
|
@@ -74,43 +72,33 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
74
72
|
public usingTURN = false;
|
|
75
73
|
public availableOutgoingBitrate = 0;
|
|
76
74
|
public availableIncomingBitrate = 0;
|
|
77
|
-
public totalInboundPacketsLost = 0;
|
|
78
|
-
public totalInboundPacketsReceived = 0;
|
|
79
|
-
public totalOutboundPacketsSent = 0;
|
|
80
|
-
public totalDataChannelBytesSent = 0;
|
|
81
|
-
public totalDataChannelBytesReceived = 0;
|
|
82
|
-
public
|
|
83
|
-
public
|
|
84
|
-
public
|
|
85
|
-
public
|
|
86
|
-
public
|
|
87
|
-
public
|
|
88
|
-
|
|
89
|
-
public
|
|
90
|
-
|
|
91
|
-
public
|
|
92
|
-
public
|
|
93
|
-
public
|
|
94
|
-
public
|
|
95
|
-
public
|
|
96
|
-
public
|
|
97
|
-
public
|
|
98
|
-
public deltaDataChannelMessagesReceived = 0;
|
|
99
|
-
public deltaInboundPacketsLost = 0;
|
|
100
|
-
public deltaInboundPacketsReceived = 0;
|
|
101
|
-
public deltaOutboundPacketsSent = 0;
|
|
75
|
+
// public totalInboundPacketsLost = 0;
|
|
76
|
+
// public totalInboundPacketsReceived = 0;
|
|
77
|
+
// public totalOutboundPacketsSent = 0;
|
|
78
|
+
// public totalDataChannelBytesSent = 0;
|
|
79
|
+
// public totalDataChannelBytesReceived = 0;
|
|
80
|
+
// public totalSentBytes = 0;
|
|
81
|
+
// public totalReceivedBytes = 0;
|
|
82
|
+
// public totalReceivedAudioBytes = 0;
|
|
83
|
+
// public totalReceivedVideoBytes = 0;
|
|
84
|
+
// public totalSentAudioBytes = 0;
|
|
85
|
+
// public totalSentVideoBytes = 0;
|
|
86
|
+
|
|
87
|
+
// public deltaReceivedAudioBytes = 0;
|
|
88
|
+
// public deltaReceivedVideoBytes = 0;
|
|
89
|
+
// public deltaSentAudioBytes = 0;
|
|
90
|
+
// public deltaSentVideoBytes = 0;
|
|
91
|
+
// public deltaDataChannelBytesSent = 0;
|
|
92
|
+
// public deltaDataChannelBytesReceived = 0;
|
|
93
|
+
// public deltaInboundPacketsLost = 0;
|
|
94
|
+
// public deltaInboundPacketsReceived = 0;
|
|
95
|
+
// public deltaOutboundPacketsSent = 0;
|
|
102
96
|
|
|
103
97
|
public avgRttInMs?: number;
|
|
104
|
-
public
|
|
105
|
-
public
|
|
106
|
-
public
|
|
107
|
-
public
|
|
108
|
-
|
|
109
|
-
public numberOfInboundRtpStreams = 0;
|
|
110
|
-
public numberOfInbundTracks = 0;
|
|
111
|
-
public numberOfOutboundRtpStreams = 0;
|
|
112
|
-
public numberOfOutboundTracks = 0;
|
|
113
|
-
public numberOfDataChannels = 0;
|
|
98
|
+
public outboundAudioBitrate?: number;
|
|
99
|
+
public outboundVideoBitrate?: number;
|
|
100
|
+
public inboundAudioBitrate?: number;
|
|
101
|
+
public inboundVideoBitrate?: number;
|
|
114
102
|
|
|
115
103
|
public readonly mediaDevices: MetaData.MediaDeviceInfo[] = [];
|
|
116
104
|
public issues: ClientIssue[] = [];
|
|
@@ -124,10 +112,6 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
124
112
|
this.detectors = new Detectors();
|
|
125
113
|
}
|
|
126
114
|
|
|
127
|
-
public get numberOfPeerConnections() {
|
|
128
|
-
return this.observedPeerConnections.size;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
115
|
public get score() {
|
|
132
116
|
return this.calculatedScore.value;
|
|
133
117
|
}
|
|
@@ -145,57 +129,16 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
145
129
|
if (this.closed) throw new Error(`Client ${this.clientId} is closed`);
|
|
146
130
|
|
|
147
131
|
const now = Date.now();
|
|
148
|
-
const elapsedInMs = now - this.updated;
|
|
149
|
-
const elapsedInSeconds = elapsedInMs / 1000;
|
|
150
|
-
|
|
151
|
-
++this.acceptedSamples;
|
|
152
|
-
|
|
153
|
-
this.availableIncomingBitrate = 0;
|
|
154
|
-
this.availableOutgoingBitrate = 0;
|
|
155
|
-
this.deltaDataChannelBytesReceived = 0;
|
|
156
|
-
this.deltaDataChannelBytesSent = 0;
|
|
157
|
-
this.deltaDataChannelMessagesReceived = 0;
|
|
158
|
-
this.deltaDataChannelMessagesSent = 0;
|
|
159
|
-
this.deltaInboundPacketsLost = 0;
|
|
160
|
-
this.deltaInboundPacketsReceived = 0;
|
|
161
|
-
this.deltaOutboundPacketsSent = 0;
|
|
162
|
-
this.deltaReceivedAudioBytes = 0;
|
|
163
|
-
this.deltaReceivedVideoBytes = 0;
|
|
164
|
-
this.deltaSentAudioBytes = 0;
|
|
165
|
-
this.deltaSentVideoBytes = 0;
|
|
166
|
-
|
|
167
|
-
this.numberOfDataChannels = 0;
|
|
168
|
-
this.numberOfInboundRtpStreams = 0;
|
|
169
|
-
this.numberOfInbundTracks = 0;
|
|
170
|
-
this.numberOfOutboundRtpStreams = 0;
|
|
171
|
-
this.numberOfOutboundTracks = 0;
|
|
172
132
|
|
|
173
133
|
sample.clientEvents?.forEach(this._processClientEvent.bind(this));
|
|
174
134
|
sample.clientMetaItems?.forEach(this.processMetadata.bind(this));
|
|
175
|
-
sample.clientIssues?.forEach(this.
|
|
135
|
+
sample.clientIssues?.forEach(this.processIssue.bind(this));
|
|
176
136
|
sample.peerConnections?.forEach(this._updatePeerConnection.bind(this));
|
|
177
|
-
sample.extensionStats?.forEach(this.
|
|
137
|
+
sample.extensionStats?.forEach(this.processExtensionStats.bind(this));
|
|
178
138
|
|
|
179
139
|
// emit new attachments?
|
|
180
140
|
this.attachments = sample.attachments;
|
|
181
141
|
|
|
182
|
-
this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
183
|
-
this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
184
|
-
this.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
|
|
185
|
-
this.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
|
|
186
|
-
this.totalInboundPacketsLost += this.deltaInboundPacketsLost;
|
|
187
|
-
this.totalInboundPacketsReceived += this.deltaInboundPacketsReceived;
|
|
188
|
-
this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
|
|
189
|
-
this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
|
|
190
|
-
this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
|
|
191
|
-
this.totalSentAudioBytes += this.deltaSentAudioBytes;
|
|
192
|
-
this.totalSentVideoBytes += this.deltaSentVideoBytes;
|
|
193
|
-
|
|
194
|
-
this.receivingAudioBitrate = (this.deltaReceivedAudioBytes * 8) / (elapsedInSeconds);
|
|
195
|
-
this.receivingVideoBitrate = (this.totalReceivedVideoBytes * 8) / (elapsedInSeconds);
|
|
196
|
-
this.sendingAudioBitrate = (this.deltaSentAudioBytes * 8) / (elapsedInSeconds);
|
|
197
|
-
this.sendingVideoBitrate = (this.deltaSentVideoBytes * 8) / (elapsedInSeconds);
|
|
198
|
-
|
|
199
142
|
this.calculatedScore.value = sample.score;
|
|
200
143
|
this.detectors.update();
|
|
201
144
|
|
|
@@ -209,15 +152,15 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
209
152
|
|
|
210
153
|
private _processClientEvent(event: ClientEvent) {
|
|
211
154
|
switch (event.type) {
|
|
212
|
-
case
|
|
155
|
+
case ClientEventType.CALL_STARTED: {
|
|
213
156
|
// update call timestamp if it's the first time
|
|
214
157
|
break;
|
|
215
158
|
}
|
|
216
|
-
case
|
|
159
|
+
case ClientEventType.CALL_ENDED: {
|
|
217
160
|
// update call timestamp if it's the first time
|
|
218
161
|
break;
|
|
219
162
|
}
|
|
220
|
-
case
|
|
163
|
+
case ClientEventType.CLIENT_JOINED: {
|
|
221
164
|
if (event.timestamp) {
|
|
222
165
|
if (!this.joinedAt) {
|
|
223
166
|
this.joinedAt = event.timestamp;
|
|
@@ -231,7 +174,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
231
174
|
}
|
|
232
175
|
break;
|
|
233
176
|
}
|
|
234
|
-
case
|
|
177
|
+
case ClientEventType.CLIENT_LEFT: {
|
|
235
178
|
if (event.timestamp) {
|
|
236
179
|
if (!this.leftAt) {
|
|
237
180
|
this.leftAt = event.timestamp;
|
|
@@ -242,39 +185,54 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
242
185
|
}
|
|
243
186
|
}
|
|
244
187
|
|
|
245
|
-
this.call.observer.
|
|
188
|
+
this.call.observer.processors.events.process({
|
|
189
|
+
call: this.call,
|
|
190
|
+
client: this,
|
|
191
|
+
data: event,
|
|
192
|
+
});
|
|
246
193
|
}
|
|
247
194
|
|
|
248
195
|
public processMetadata(metadata: ClientMetaData) {
|
|
249
196
|
switch (metadata.type) {
|
|
250
|
-
case
|
|
197
|
+
case ClientMetaType.BROWSER: {
|
|
251
198
|
this.browser = parseJsonAs(metadata.payload);
|
|
252
199
|
break;
|
|
253
200
|
}
|
|
254
|
-
case
|
|
201
|
+
case ClientMetaType.ENGINE: {
|
|
255
202
|
this.engine = parseJsonAs(metadata.payload);
|
|
256
203
|
break;
|
|
257
204
|
}
|
|
258
|
-
case
|
|
205
|
+
case ClientMetaType.PLATFORM: {
|
|
259
206
|
this.platform = parseJsonAs(metadata.payload);
|
|
260
207
|
break;
|
|
261
208
|
}
|
|
262
|
-
case
|
|
209
|
+
case ClientMetaType.OPERATION_SYSTEM: {
|
|
263
210
|
this.operationSystem = parseJsonAs(metadata.payload);
|
|
264
211
|
break;
|
|
265
212
|
}
|
|
266
213
|
}
|
|
267
214
|
|
|
268
|
-
this.call.observer.
|
|
215
|
+
this.call.observer.processors.metaData.process({
|
|
216
|
+
call: this.call,
|
|
217
|
+
client: this,
|
|
218
|
+
data: metadata,
|
|
219
|
+
});
|
|
269
220
|
}
|
|
270
221
|
|
|
271
|
-
public
|
|
272
|
-
this.
|
|
273
|
-
|
|
222
|
+
public processIssue(issue: ClientIssue) {
|
|
223
|
+
this.call.observer.processors.issues.process({
|
|
224
|
+
call: this.call,
|
|
225
|
+
client: this,
|
|
226
|
+
data: issue,
|
|
227
|
+
});
|
|
274
228
|
}
|
|
275
229
|
|
|
276
|
-
public
|
|
277
|
-
this.call.observer.
|
|
230
|
+
public processExtensionStats(stats: ExtensionStat) {
|
|
231
|
+
this.call.observer.processors.extensionStats.process({
|
|
232
|
+
call: this.call,
|
|
233
|
+
client: this,
|
|
234
|
+
data: stats,
|
|
235
|
+
});
|
|
278
236
|
}
|
|
279
237
|
|
|
280
238
|
private _updatePeerConnection(sample: PeerConnectionSample) {
|
|
@@ -294,31 +252,8 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
|
|
|
294
252
|
this.observedPeerConnections.delete(sample.peerConnectionId);
|
|
295
253
|
});
|
|
296
254
|
this.observedPeerConnections.set(sample.peerConnectionId, observedPeerConnection);
|
|
297
|
-
|
|
298
|
-
this.emit('newpeerconnection', observedPeerConnection);
|
|
299
255
|
}
|
|
300
256
|
|
|
301
257
|
observedPeerConnection.accept(sample);
|
|
302
|
-
|
|
303
|
-
this.deltaDataChannelBytesReceived += observedPeerConnection.deltaDataChannelBytesReceived;
|
|
304
|
-
this.deltaDataChannelBytesSent += observedPeerConnection.deltaDataChannelBytesSent;
|
|
305
|
-
this.deltaDataChannelMessagesReceived += observedPeerConnection.deltaDataChannelMessagesReceived;
|
|
306
|
-
this.deltaDataChannelMessagesSent += observedPeerConnection.deltaDataChannelMessagesSent;
|
|
307
|
-
this.deltaInboundPacketsLost += observedPeerConnection.deltaInboundPacketsLost;
|
|
308
|
-
this.deltaInboundPacketsReceived += observedPeerConnection.deltaInboundPacketsReceived;
|
|
309
|
-
this.deltaOutboundPacketsSent += observedPeerConnection.deltaOutboundPacketsSent;
|
|
310
|
-
this.deltaReceivedAudioBytes += observedPeerConnection.deltaReceivedAudioBytes;
|
|
311
|
-
this.deltaReceivedVideoBytes += observedPeerConnection.deltaReceivedVideoBytes;
|
|
312
|
-
this.deltaSentAudioBytes += observedPeerConnection.deltaSentAudioBytes;
|
|
313
|
-
this.deltaSentVideoBytes += observedPeerConnection.deltaSentVideoBytes;
|
|
314
|
-
|
|
315
|
-
this.availableIncomingBitrate += observedPeerConnection.availableIncomingBitrate;
|
|
316
|
-
this.availableOutgoingBitrate += observedPeerConnection.availableOutgoingBitrate;
|
|
317
|
-
|
|
318
|
-
this.numberOfDataChannels += observedPeerConnection.observedDataChannels.size;
|
|
319
|
-
this.numberOfInbundTracks += observedPeerConnection.observedInboundTracks.size;
|
|
320
|
-
this.numberOfOutboundRtpStreams += observedPeerConnection.observedOutboundRtps.size;
|
|
321
|
-
this.numberOfOutboundTracks += observedPeerConnection.observedOutboundTracks.size;
|
|
322
|
-
this.numberOfInboundRtpStreams += observedPeerConnection.observedInboundRtps.size;
|
|
323
258
|
}
|
|
324
259
|
}
|
|
@@ -16,11 +16,6 @@ export class ObservedDataChannel implements DataChannelStats {
|
|
|
16
16
|
bytesReceived?: number | undefined;
|
|
17
17
|
attachments?: Record<string, unknown> | undefined;
|
|
18
18
|
|
|
19
|
-
public deltaBytesSent = 0;
|
|
20
|
-
public deltaBytesReceived = 0;
|
|
21
|
-
public deltaMessagesSent = 0;
|
|
22
|
-
public deltaMessagesReceived = 0;
|
|
23
|
-
|
|
24
19
|
public appData?: Record<string, unknown>;
|
|
25
20
|
|
|
26
21
|
public constructor(
|
|
@@ -45,30 +40,6 @@ export class ObservedDataChannel implements DataChannelStats {
|
|
|
45
40
|
public update(stats: DataChannelStats) {
|
|
46
41
|
this._visited = true;
|
|
47
42
|
|
|
48
|
-
if (this.messagesSent && stats.messagesSent && stats.messagesSent >= this.messagesSent) {
|
|
49
|
-
this.deltaMessagesSent = stats.messagesSent - this.messagesSent;
|
|
50
|
-
} else {
|
|
51
|
-
this.deltaMessagesSent = 0;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (this.messagesReceived && stats.messagesReceived && stats.messagesReceived >= this.messagesReceived) {
|
|
55
|
-
this.deltaMessagesReceived = stats.messagesReceived - this.messagesReceived;
|
|
56
|
-
} else {
|
|
57
|
-
this.deltaMessagesReceived = 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (this.bytesSent && stats.bytesSent && stats.bytesSent >= this.bytesSent) {
|
|
61
|
-
this.deltaBytesSent = stats.bytesSent - this.bytesSent;
|
|
62
|
-
} else {
|
|
63
|
-
this.deltaBytesSent = 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (this.bytesReceived && stats.bytesReceived && stats.bytesReceived >= this.bytesReceived) {
|
|
67
|
-
this.deltaBytesReceived = stats.bytesReceived - this.bytesReceived;
|
|
68
|
-
} else {
|
|
69
|
-
this.deltaBytesReceived = 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
43
|
this.label = stats.label;
|
|
73
44
|
this.protocol = stats.protocol;
|
|
74
45
|
this.dataChannelIdentifier = stats.dataChannelIdentifier;
|
|
@@ -29,11 +29,6 @@ export class ObservedIceCandidatePair implements IceCandidatePairStats {
|
|
|
29
29
|
bytesDiscardedOnSend?: number | undefined;
|
|
30
30
|
attachments?: Record<string, unknown> | undefined;
|
|
31
31
|
|
|
32
|
-
public deltaBytesSent = 0;
|
|
33
|
-
public deltaBytesReceived = 0;
|
|
34
|
-
public deltaPacketsSent = 0;
|
|
35
|
-
public deltaPacketsReceived = 0;
|
|
36
|
-
|
|
37
32
|
public constructor(
|
|
38
33
|
public timestamp: number,
|
|
39
34
|
public id: string,
|
|
@@ -68,27 +63,6 @@ export class ObservedIceCandidatePair implements IceCandidatePairStats {
|
|
|
68
63
|
public update(stats: IceCandidatePairStats) {
|
|
69
64
|
this._visited = true;
|
|
70
65
|
|
|
71
|
-
if (this.packetsSent && stats.packetsSent && stats.packetsSent >= this.packetsSent) {
|
|
72
|
-
this.deltaPacketsSent = stats.packetsSent - this.packetsSent;
|
|
73
|
-
} else {
|
|
74
|
-
this.deltaPacketsSent = 0;
|
|
75
|
-
}
|
|
76
|
-
if (this.packetsReceived && stats.packetsReceived && stats.packetsReceived >= this.packetsReceived) {
|
|
77
|
-
this.deltaPacketsReceived = stats.packetsReceived - this.packetsReceived;
|
|
78
|
-
} else {
|
|
79
|
-
this.deltaPacketsReceived = 0;
|
|
80
|
-
}
|
|
81
|
-
if (this.bytesSent && stats.bytesSent && stats.bytesSent >= this.bytesSent) {
|
|
82
|
-
this.deltaBytesSent = stats.bytesSent - this.bytesSent;
|
|
83
|
-
} else {
|
|
84
|
-
this.deltaBytesSent = 0;
|
|
85
|
-
}
|
|
86
|
-
if (this.bytesReceived && stats.bytesReceived && stats.bytesReceived >= this.bytesReceived) {
|
|
87
|
-
this.deltaBytesReceived = stats.bytesReceived - this.bytesReceived;
|
|
88
|
-
} else {
|
|
89
|
-
this.deltaBytesReceived = 0;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
66
|
this.timestamp = stats.timestamp;
|
|
93
67
|
this.transportId = stats.transportId;
|
|
94
68
|
this.localCandidateId = stats.localCandidateId;
|
|
@@ -19,7 +19,6 @@ 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
22
|
|
|
24
23
|
const logger = createLogger('ObservedPeerConnection');
|
|
25
24
|
|
|
@@ -71,7 +70,7 @@ export type ObservedPeerConnectionEvents = {
|
|
|
71
70
|
'removed-peer-connection-transport': [ObservedPeerConnectionTransport];
|
|
72
71
|
'removed-remote-inbound-rtp': [ObservedRemoteInboundRtp];
|
|
73
72
|
'removed-remote-outbound-rtp': [ObservedRemoteOutboundRtp];
|
|
74
|
-
|
|
73
|
+
|
|
75
74
|
close: [];
|
|
76
75
|
};
|
|
77
76
|
|
|
@@ -107,15 +106,11 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
107
106
|
public closedAt?: number;
|
|
108
107
|
public updated = Date.now();
|
|
109
108
|
|
|
110
|
-
public availableIncomingBitrate = 0;
|
|
111
|
-
public availableOutgoingBitrate = 0;
|
|
112
109
|
public totalInboundPacketsLost = 0;
|
|
113
110
|
public totalInboundPacketsReceived = 0;
|
|
114
111
|
public totalOutboundPacketsSent = 0;
|
|
115
112
|
public totalDataChannelBytesSent = 0;
|
|
116
113
|
public totalDataChannelBytesReceived = 0;
|
|
117
|
-
public totalDataChannelMessagesSent = 0;
|
|
118
|
-
public totalDataChannelMessagesReceived = 0;
|
|
119
114
|
|
|
120
115
|
public totalSentAudioBytes = 0;
|
|
121
116
|
public totalSentVideoBytes = 0;
|
|
@@ -131,8 +126,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
131
126
|
public deltaOutboundPacketsSent = 0;
|
|
132
127
|
public deltaDataChannelBytesSent = 0;
|
|
133
128
|
public deltaDataChannelBytesReceived = 0;
|
|
134
|
-
public deltaDataChannelMessagesSent = 0;
|
|
135
|
-
public deltaDataChannelMessagesReceived = 0;
|
|
136
129
|
public deltaInboundReceivedBytes = 0;
|
|
137
130
|
public deltaOutboundSentBytes = 0;
|
|
138
131
|
|
|
@@ -156,7 +149,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
156
149
|
public usingTCP = false;
|
|
157
150
|
public usingTURN = false;
|
|
158
151
|
|
|
159
|
-
public observedTurnServer?: ObservedTurnServer;
|
|
160
152
|
public readonly observedCertificates = new Map<string, ObservedCertificate>();
|
|
161
153
|
public readonly observedCodecs = new Map<string, ObservedCodec>();
|
|
162
154
|
public readonly observedDataChannels = new Map<string, ObservedDataChannel>();
|
|
@@ -247,14 +239,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
247
239
|
.filter((pair) => pair !== undefined) as ObservedIceCandidatePair[];
|
|
248
240
|
}
|
|
249
241
|
|
|
250
|
-
public get selectedIceCandiadtePairForTurn() {
|
|
251
|
-
return this.selectedIceCandidatePairs
|
|
252
|
-
.filter((pair) =>
|
|
253
|
-
pair.getLocalCandidate()?.candidateType === 'relay' &&
|
|
254
|
-
pair.getRemoteCandidate()?.url?.startsWith('turn:')
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
242
|
public close() {
|
|
259
243
|
if (this.closed) return;
|
|
260
244
|
this.closed = true;
|
|
@@ -275,8 +259,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
275
259
|
this.observedRemoteInboundRtps.clear();
|
|
276
260
|
this.observedRemoteOutboundRtps.clear();
|
|
277
261
|
|
|
278
|
-
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
279
|
-
|
|
280
262
|
this.emit('close');
|
|
281
263
|
}
|
|
282
264
|
|
|
@@ -284,8 +266,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
284
266
|
if (this.closed) return;
|
|
285
267
|
this._visited = true;
|
|
286
268
|
|
|
287
|
-
this.availableIncomingBitrate = 0;
|
|
288
|
-
this.availableOutgoingBitrate = 0;
|
|
289
269
|
this.deltaInboundPacketsLost = 0;
|
|
290
270
|
this.deltaInboundPacketsReceived = 0;
|
|
291
271
|
this.deltaOutboundPacketsSent = 0;
|
|
@@ -307,8 +287,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
307
287
|
const now = Date.now();
|
|
308
288
|
const elapsedTimeInMs = now - this.updated;
|
|
309
289
|
const elapsedTimeInSec = elapsedTimeInMs / 1000;
|
|
310
|
-
const rttMeasurementsInSec: number[] = [];
|
|
311
|
-
const jitterMeasurements: number[] = [];
|
|
312
290
|
|
|
313
291
|
if (sample.certificates) {
|
|
314
292
|
for (const certificate of sample.certificates) {
|
|
@@ -322,14 +300,7 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
322
300
|
}
|
|
323
301
|
if (sample.dataChannels) {
|
|
324
302
|
for (const dataChannel of sample.dataChannels) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if (!observedDataChannel) continue;
|
|
328
|
-
|
|
329
|
-
this.deltaDataChannelBytesSent += observedDataChannel.deltaBytesSent;
|
|
330
|
-
this.deltaDataChannelBytesReceived += observedDataChannel.deltaBytesReceived;
|
|
331
|
-
this.deltaDataChannelMessagesSent += observedDataChannel.deltaMessagesSent;
|
|
332
|
-
this.deltaDataChannelMessagesReceived += observedDataChannel.deltaMessagesReceived;
|
|
303
|
+
this._updateDataChannelStats(dataChannel);
|
|
333
304
|
}
|
|
334
305
|
}
|
|
335
306
|
if (sample.iceCandidates) {
|
|
@@ -339,19 +310,7 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
339
310
|
}
|
|
340
311
|
if (sample.iceCandidatePairs) {
|
|
341
312
|
for (const iceCandidatePair of sample.iceCandidatePairs) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if (!observedCandidatePair) continue;
|
|
345
|
-
|
|
346
|
-
if (observedCandidatePair.currentRoundTripTime) {
|
|
347
|
-
rttMeasurementsInSec.push(observedCandidatePair.currentRoundTripTime);
|
|
348
|
-
}
|
|
349
|
-
if (observedCandidatePair.availableIncomingBitrate) {
|
|
350
|
-
this.availableIncomingBitrate += observedCandidatePair.availableIncomingBitrate;
|
|
351
|
-
}
|
|
352
|
-
if (observedCandidatePair.availableOutgoingBitrate) {
|
|
353
|
-
this.availableOutgoingBitrate += observedCandidatePair.availableOutgoingBitrate;
|
|
354
|
-
}
|
|
313
|
+
this._updateIceCandidatePairStats(iceCandidatePair);
|
|
355
314
|
}
|
|
356
315
|
}
|
|
357
316
|
if (sample.iceTransports) {
|
|
@@ -379,10 +338,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
379
338
|
this.deltaReceivedVideoPackets += observedInboundRtp.deltaReceivedPackets;
|
|
380
339
|
break;
|
|
381
340
|
}
|
|
382
|
-
|
|
383
|
-
if (observedInboundRtp.jitter) {
|
|
384
|
-
jitterMeasurements.push(observedInboundRtp.jitter);
|
|
385
|
-
}
|
|
386
341
|
}
|
|
387
342
|
}
|
|
388
343
|
if (sample.mediaPlayouts) {
|
|
@@ -424,13 +379,7 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
424
379
|
}
|
|
425
380
|
if (sample.remoteInboundRtps) {
|
|
426
381
|
for (const remoteInboundRtp of sample.remoteInboundRtps) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
if (!observedRemoteInboundRtp) continue;
|
|
430
|
-
|
|
431
|
-
if (observedRemoteInboundRtp.roundTripTime) {
|
|
432
|
-
rttMeasurementsInSec.push(observedRemoteInboundRtp.roundTripTime);
|
|
433
|
-
}
|
|
382
|
+
this._updateRemoteInboundRtpStats(remoteInboundRtp);
|
|
434
383
|
}
|
|
435
384
|
}
|
|
436
385
|
if (sample.remoteOutboundRtps) {
|
|
@@ -459,8 +408,6 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
459
408
|
this.totalOutboundPacketsSent += this.deltaOutboundPacketsSent;
|
|
460
409
|
this.totalDataChannelBytesSent += this.deltaDataChannelBytesSent;
|
|
461
410
|
this.totalDataChannelBytesReceived += this.deltaDataChannelBytesReceived;
|
|
462
|
-
this.totalDataChannelMessagesSent += this.deltaDataChannelMessagesSent;
|
|
463
|
-
this.totalDataChannelMessagesReceived += this.deltaDataChannelMessagesReceived;
|
|
464
411
|
this.totalReceivedAudioBytes += this.deltaReceivedAudioBytes;
|
|
465
412
|
this.totalReceivedVideoBytes += this.deltaReceivedVideoBytes;
|
|
466
413
|
this.totalSentAudioBytes += this.deltaSentAudioBytes;
|
|
@@ -472,47 +419,20 @@ export class ObservedPeerConnection extends EventEmitter {
|
|
|
472
419
|
|
|
473
420
|
this.receivingPacketsPerSecond = this.deltaInboundPacketsReceived / elapsedTimeInSec;
|
|
474
421
|
this.sendingPacketsPerSecond = this.deltaOutboundPacketsSent / elapsedTimeInSec;
|
|
475
|
-
this.sendingAudioBitrate =
|
|
476
|
-
this.sendingVideoBitrate =
|
|
477
|
-
this.receivingAudioBitrate =
|
|
478
|
-
this.receivingVideoBitrate =
|
|
479
|
-
|
|
480
|
-
if (rttMeasurementsInSec.length > 0) {
|
|
481
|
-
this.avgRttInMs = rttMeasurementsInSec.reduce((acc, val) => acc + val, 0) / rttMeasurementsInSec.length;
|
|
482
|
-
} else {
|
|
483
|
-
this.avgRttInMs = undefined;
|
|
484
|
-
}
|
|
485
|
-
if (jitterMeasurements.length > 0) {
|
|
486
|
-
this.avgJitter = jitterMeasurements.reduce((acc, val) => acc + val, 0) / jitterMeasurements.length;
|
|
487
|
-
} else {
|
|
488
|
-
this.avgJitter = undefined;
|
|
489
|
-
}
|
|
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;
|
|
490
426
|
|
|
491
427
|
const selectedIceCandidatePairs = this.selectedIceCandidatePairs;
|
|
492
|
-
const selectedCandidatePairForTurn = selectedIceCandidatePairs.filter((pair) =>
|
|
493
|
-
pair.getLocalCandidate()?.candidateType === 'relay' &&
|
|
494
|
-
pair.getRemoteCandidate()?.url?.startsWith('turn:')
|
|
495
|
-
);
|
|
496
|
-
const wasUsingTURN = this.usingTURN;
|
|
497
428
|
|
|
498
429
|
this.usingTCP = selectedIceCandidatePairs.some((pair) => pair.getLocalCandidate()?.protocol === 'tcp');
|
|
499
|
-
this.usingTURN =
|
|
430
|
+
this.usingTURN = selectedIceCandidatePairs.some((pair) => pair.getLocalCandidate()?.candidateType === 'relay') &&
|
|
431
|
+
selectedIceCandidatePairs.some((pair) => pair.getRemoteCandidate()?.url?.startsWith('turn:'));
|
|
500
432
|
|
|
501
|
-
if (this.usingTURN) {
|
|
502
|
-
if (!this.observedTurnServer) {
|
|
503
|
-
this.observedTurnServer = this.client.call.observer.observedTURN.addPeerConnection(this);
|
|
504
|
-
}
|
|
505
|
-
this.observedTurnServer?.updateTurnUsage(...selectedCandidatePairForTurn);
|
|
506
|
-
} else if (wasUsingTURN) {
|
|
507
|
-
if (!this.usingTURN) {
|
|
508
|
-
this.client.call.observer.observedTURN.removePeerConnection(this);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
433
|
this.calculatedScore.value = sample.score;
|
|
512
434
|
this.updated = now;
|
|
513
435
|
this._checkVisited();
|
|
514
|
-
|
|
515
|
-
this.emit('update');
|
|
516
436
|
}
|
|
517
437
|
|
|
518
438
|
private _checkVisited() {
|