@flashphoner/websdk 2.0.262 → 2.0.264
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/docTemplate/README.md +1 -1
- package/flashphoner-no-flash.js +101 -36
- package/flashphoner-no-flash.min.js +1 -1
- package/flashphoner-no-webrtc.js +101 -36
- package/flashphoner-no-webrtc.min.js +1 -1
- package/flashphoner-no-wsplayer.js +101 -36
- package/flashphoner-no-wsplayer.min.js +1 -1
- package/flashphoner-room-api-webrtc-only.js +101 -36
- package/flashphoner-room-api-webrtc-only.min.js +1 -1
- package/flashphoner-room-api.js +80 -31
- package/flashphoner-room-api.min.js +1 -1
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +101 -36
- package/flashphoner-temasys-flash-websocket.js +101 -36
- package/flashphoner-temasys-flash-websocket.min.js +1 -1
- package/flashphoner-webrtc-only.js +101 -36
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +101 -36
- package/flashphoner.min.js +1 -1
- package/package.json +1 -2
- package/src/stats-collector.js +80 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flashphoner/websdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.264",
|
|
4
4
|
"description": "Official Flashphoner WebCallServer WebSDK package",
|
|
5
5
|
"main": "./src/flashphoner-core.js",
|
|
6
6
|
"types": "./src/flashphoner-core.d.ts",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"chai": "^3.5.0",
|
|
21
21
|
"grunt": "^1.0.1",
|
|
22
22
|
"grunt-browserify": "^5.0.0",
|
|
23
|
-
"grunt-contrib": "^0.11.0",
|
|
24
23
|
"grunt-contrib-clean": "^1.0.0",
|
|
25
24
|
"grunt-contrib-concat": "^1.0.1",
|
|
26
25
|
"grunt-contrib-copy": "^1.0.0",
|
package/src/stats-collector.js
CHANGED
|
@@ -16,6 +16,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
16
16
|
metricsBatch: null,
|
|
17
17
|
timer: null,
|
|
18
18
|
batchCount: 0,
|
|
19
|
+
timerBusy: false,
|
|
19
20
|
start: async function() {
|
|
20
21
|
let error = "Can't collect WebRTC stats to send: ";
|
|
21
22
|
if (!statCollector.description.types) {
|
|
@@ -55,7 +56,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
55
56
|
update: async function(description) {
|
|
56
57
|
if (!description) {
|
|
57
58
|
if (statCollector.logger) {
|
|
58
|
-
statCollector.logger.error(LOG_PREFIX, "Can't update WebRTC metrics sending: no parameters passed");
|
|
59
|
+
statCollector.logger.error(LOG_PREFIX + "-" + statCollector.id, "Can't update WebRTC metrics sending: no parameters passed");
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -91,8 +92,12 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
91
92
|
break;
|
|
92
93
|
}
|
|
93
94
|
},
|
|
94
|
-
updateHeaders: async function() {
|
|
95
|
-
let
|
|
95
|
+
updateHeaders: async function(stats = null) {
|
|
96
|
+
let currentHeaders = "";
|
|
97
|
+
let headersChanged = false;
|
|
98
|
+
if (!stats) {
|
|
99
|
+
stats = await statCollector.mediaConnection.getWebRTCStats();
|
|
100
|
+
}
|
|
96
101
|
Object.keys(statCollector.description.types).forEach((type) => {
|
|
97
102
|
let typeDescriptor = statCollector.description.types[type];
|
|
98
103
|
let metricsString = "";
|
|
@@ -105,15 +110,15 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
105
110
|
}
|
|
106
111
|
if (stats[type]) {
|
|
107
112
|
stats[type].forEach((report) => {
|
|
108
|
-
statCollector.logger.debug(LOG_PREFIX, type + " report: " + JSON.stringify(report));
|
|
113
|
+
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, type + " report: " + JSON.stringify(report));
|
|
109
114
|
if (contentFilters) {
|
|
110
115
|
let filtersMatched = true;
|
|
111
116
|
for (const filter in contentFilters) {
|
|
112
|
-
statCollector.logger.debug(LOG_PREFIX, type + " filter by " + filter + ": " + JSON.stringify(contentFilters[filter]));
|
|
117
|
+
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, type + " filter by " + filter + ": " + JSON.stringify(contentFilters[filter]));
|
|
113
118
|
let filterMatched = false;
|
|
114
119
|
if (report[filter]) {
|
|
115
120
|
for (const value of contentFilters[filter]) {
|
|
116
|
-
statCollector.logger.debug(LOG_PREFIX, filter + ": " + value + " <> " + report[filter]);
|
|
121
|
+
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, filter + ": " + value + " <> " + report[filter]);
|
|
117
122
|
if (report[filter] === value) {
|
|
118
123
|
filterMatched = true;
|
|
119
124
|
break;
|
|
@@ -126,34 +131,44 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
126
131
|
}
|
|
127
132
|
}
|
|
128
133
|
if (filtersMatched) {
|
|
129
|
-
statCollector.addHeaders(report, metricsString);
|
|
134
|
+
currentHeaders = statCollector.addHeaders(currentHeaders, report, metricsString);
|
|
130
135
|
}
|
|
131
136
|
} else {
|
|
132
|
-
statCollector.addHeaders(report, metricsString);
|
|
137
|
+
currentHeaders = statCollector.addHeaders(currentHeaders, report, metricsString);
|
|
133
138
|
}
|
|
134
139
|
});
|
|
135
140
|
} else {
|
|
136
|
-
statCollector.logger.
|
|
141
|
+
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, "No report type found in RTC stats: '" + type + "'");
|
|
137
142
|
}
|
|
138
143
|
});
|
|
144
|
+
if (currentHeaders !== statCollector.headers) {
|
|
145
|
+
headersChanged = true;
|
|
146
|
+
let newMetrics = [];
|
|
147
|
+
currentHeaders.split(",").forEach((header) => {
|
|
148
|
+
if (statCollector.headers.indexOf(header) === -1) {
|
|
149
|
+
newMetrics.push(header);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
if (newMetrics.length) {
|
|
153
|
+
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "RTC metrics to be collected: " + newMetrics.toString());
|
|
154
|
+
}
|
|
155
|
+
statCollector.headers = currentHeaders;
|
|
156
|
+
}
|
|
157
|
+
return headersChanged;
|
|
139
158
|
},
|
|
140
|
-
addHeaders: function(report, metricsString) {
|
|
159
|
+
addHeaders: function(currentHeaders, report, metricsString) {
|
|
141
160
|
if (metricsString) {
|
|
142
161
|
let metrics = metricsString.split(",");
|
|
143
162
|
metrics.forEach((metric) => {
|
|
144
|
-
let metricFound = false;
|
|
145
163
|
for (const key of Object.keys(report)) {
|
|
146
164
|
if (metric === key) {
|
|
147
|
-
|
|
148
|
-
metricFound = true;
|
|
165
|
+
currentHeaders = util.addFieldToCsvString(currentHeaders, report.type + "." + report.id + "." + metric, ",");
|
|
149
166
|
break;
|
|
150
167
|
}
|
|
151
168
|
}
|
|
152
|
-
if (!metricFound) {
|
|
153
|
-
statCollector.logger.warn(LOG_PREFIX, "No metric found in RTC stats report '" + report.type + "': '" + metric + "'");
|
|
154
|
-
}
|
|
155
169
|
});
|
|
156
170
|
}
|
|
171
|
+
return currentHeaders;
|
|
157
172
|
},
|
|
158
173
|
updateCompression: async function() {
|
|
159
174
|
if (statCollector.description.compression) {
|
|
@@ -169,7 +184,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
169
184
|
await util.compress(compression, "test", false);
|
|
170
185
|
statCollector.compression = compression;
|
|
171
186
|
} catch (e) {
|
|
172
|
-
statCollector.logger.warn(LOG_PREFIX, "Can't compress metrics data using " + compression + ": " + e);
|
|
187
|
+
statCollector.logger.warn(LOG_PREFIX + "-" + statCollector.id, "Can't compress metrics data using " + compression + ": " + e);
|
|
173
188
|
statCollector.compression = "none";
|
|
174
189
|
}
|
|
175
190
|
},
|
|
@@ -182,7 +197,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
182
197
|
statCollector.send("webRTCMetricsClientDescription", data);
|
|
183
198
|
},
|
|
184
199
|
send: function(message, data) {
|
|
185
|
-
statCollector.logger.debug(LOG_PREFIX, data);
|
|
200
|
+
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, data);
|
|
186
201
|
if (statCollector.wsConnection.readyState === WebSocket.OPEN) {
|
|
187
202
|
statCollector.wsConnection.send(JSON.stringify({
|
|
188
203
|
message: message,
|
|
@@ -204,14 +219,16 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
204
219
|
}
|
|
205
220
|
},
|
|
206
221
|
collectMetrics: async function() {
|
|
207
|
-
if (statCollector.timer) {
|
|
222
|
+
if (statCollector.timer && !statCollector.timerBusy) {
|
|
223
|
+
// Unfortunately there are no real atomics in JS unless SharedArrayBuffer is used
|
|
224
|
+
// So we guard the timer callback with a dumb boolean
|
|
225
|
+
statCollector.timerBusy = true;
|
|
208
226
|
let stats = await statCollector.mediaConnection.getWebRTCStats();
|
|
209
227
|
|
|
210
|
-
|
|
211
|
-
statCollector.metricsBatch = [];
|
|
212
|
-
}
|
|
228
|
+
statCollector.startNewBatch();
|
|
213
229
|
|
|
214
230
|
let metrics = [];
|
|
231
|
+
let lostMetrics = [];
|
|
215
232
|
statCollector.headers.split(",").forEach((header) => {
|
|
216
233
|
let components = header.split(".");
|
|
217
234
|
let descriptor = {
|
|
@@ -219,7 +236,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
219
236
|
id: components[1],
|
|
220
237
|
name: components[2]
|
|
221
238
|
}
|
|
222
|
-
let value =
|
|
239
|
+
let value = null;
|
|
223
240
|
|
|
224
241
|
if (stats[descriptor.type]) {
|
|
225
242
|
for (const report of stats[descriptor.type]) {
|
|
@@ -229,13 +246,32 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
229
246
|
}
|
|
230
247
|
}
|
|
231
248
|
}
|
|
232
|
-
|
|
249
|
+
if (value === null) {
|
|
250
|
+
lostMetrics.push(descriptor);
|
|
251
|
+
} else {
|
|
252
|
+
metrics.push(value);
|
|
253
|
+
}
|
|
233
254
|
});
|
|
234
|
-
|
|
235
|
-
statCollector.
|
|
236
|
-
if (
|
|
255
|
+
// Metrics list may change if some metrics are added or some metrics are lost #WCS-4627
|
|
256
|
+
let headersUpdated = await statCollector.updateHeaders(stats);
|
|
257
|
+
if (lostMetrics.length) {
|
|
258
|
+
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "Missing metrics: " + JSON.stringify(lostMetrics));
|
|
259
|
+
// Send metrics already collected and start a new batch with current metrics array to send them later #WCS-4627
|
|
237
260
|
await statCollector.sendMetrics();
|
|
261
|
+
statCollector.startNewBatch(metrics);
|
|
262
|
+
} else {
|
|
263
|
+
statCollector.metricsBatch.push(metrics);
|
|
264
|
+
statCollector.batchCount--;
|
|
265
|
+
if (statCollector.batchCount === 0 || headersUpdated) {
|
|
266
|
+
await statCollector.sendMetrics();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Check if metrics list changed and send a new headers if needed #WCS-4619
|
|
270
|
+
if (headersUpdated) {
|
|
271
|
+
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "RTC metrics list has changed, sending a new metrics description");
|
|
272
|
+
statCollector.sendHeaders();
|
|
238
273
|
}
|
|
274
|
+
statCollector.timerBusy = false;
|
|
239
275
|
}
|
|
240
276
|
},
|
|
241
277
|
sendMetrics: async function() {
|
|
@@ -243,7 +279,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
243
279
|
let metricsToSend = [];
|
|
244
280
|
let metricsData;
|
|
245
281
|
|
|
246
|
-
for (let i = 0; i < statCollector.metricsBatch.length; i++) {
|
|
282
|
+
for (let i = 0; statCollector.metricsBatch && i < statCollector.metricsBatch.length; i++) {
|
|
247
283
|
let metricsString = "";
|
|
248
284
|
for (let j = 0; j < statCollector.metricsBatch[i].length; j++) {
|
|
249
285
|
let valueString = valueToString(statCollector.metricsBatch[i][j]);
|
|
@@ -267,7 +303,7 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
267
303
|
try {
|
|
268
304
|
metricsData = await util.compress(statCollector.compression, JSON.stringify(metricsToSend), true);
|
|
269
305
|
} catch(e) {
|
|
270
|
-
statCollector.logger.warn(LOG_PREFIX, "Can't send metrics data using" + statCollector.compression + ": " + e);
|
|
306
|
+
statCollector.logger.warn(LOG_PREFIX + "-" + statCollector.id, "Can't send metrics data using" + statCollector.compression + ": " + e);
|
|
271
307
|
metricsData = null;
|
|
272
308
|
}
|
|
273
309
|
} else {
|
|
@@ -280,8 +316,21 @@ const StreamStatsCollector = function(description, id, mediaConnection, wsConnec
|
|
|
280
316
|
};
|
|
281
317
|
statCollector.send("webRTCMetricsBatch", data);
|
|
282
318
|
}
|
|
283
|
-
statCollector.
|
|
284
|
-
|
|
319
|
+
statCollector.cleanBatch();
|
|
320
|
+
},
|
|
321
|
+
startNewBatch: function(metrics) {
|
|
322
|
+
if (!statCollector.metricsBatch) {
|
|
323
|
+
statCollector.metricsBatch = [];
|
|
324
|
+
if (metrics) {
|
|
325
|
+
statCollector.metricsBatch.push(metrics);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
cleanBatch: function() {
|
|
330
|
+
if (statCollector.metricsBatch) {
|
|
331
|
+
statCollector.metricsBatch = null;
|
|
332
|
+
statCollector.batchCount = statCollector.description.batchSize;
|
|
333
|
+
}
|
|
285
334
|
}
|
|
286
335
|
}
|
|
287
336
|
return statCollector;
|