@wazo/sdk 0.37.15 → 0.37.19
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/dist/wazo-sdk.js +3 -3
- package/esm/__tests__/api-client.test.js +9 -5
- package/esm/__tests__/web-rtc-client.test.js +117 -23
- package/esm/api/agentd.js +1 -1
- package/esm/api/amid.js +1 -1
- package/esm/api/application.js +1 -1
- package/esm/api/auth.js +1 -1
- package/esm/api/call-logd.js +3 -3
- package/esm/api/calld.js +1 -1
- package/esm/api/chatd.js +1 -1
- package/esm/api/confd.js +7 -3
- package/esm/api/ctid-ng.js +1 -1
- package/esm/api/dird.js +1 -1
- package/esm/api/webhookd.js +1 -1
- package/esm/api-client.js +9 -5
- package/esm/checker/Checker.js +117 -23
- package/esm/checker/checks/aor.js +9 -5
- package/esm/checker/checks/api.js +9 -5
- package/esm/checker/checks/index.js +117 -23
- package/esm/checker/checks/wazo-websocket.js +1 -1
- package/esm/checker/checks/webrtc-transport.js +117 -23
- package/esm/checker/checks/webrtc.js +117 -23
- package/esm/domain/AdHocAPIConference.js +9 -5
- package/esm/domain/CallLog.js +2 -2
- package/esm/domain/Features.js +9 -5
- package/esm/domain/Meeting.js +6 -2
- package/esm/domain/Phone/CTIPhone.js +9 -5
- package/esm/domain/Phone/WebRTCPhone.js +9 -2
- package/esm/domain/Recording.js +1 -1
- package/esm/domain/__tests__/CallLog.test.js +2 -2
- package/esm/index.js +125 -23
- package/esm/lib/WazoSessionDescriptionHandler.js +1 -1
- package/esm/service/CallApi.js +9 -5
- package/esm/service/IssueReporter.js +1 -1
- package/esm/service/__tests__/IssueReporter.test.js +1 -1
- package/esm/service/getApiClient.js +9 -5
- package/esm/simple/Auth.js +125 -23
- package/esm/simple/Configuration.js +125 -23
- package/esm/simple/Directory.js +9 -5
- package/esm/simple/Phone.js +125 -23
- package/esm/simple/Websocket.js +1 -1
- package/esm/simple/index.js +125 -23
- package/esm/simple/room/LocalParticipant.js +125 -23
- package/esm/simple/room/Participant.js +125 -23
- package/esm/simple/room/RemoteParticipant.js +125 -23
- package/esm/simple/room/Room.js +125 -23
- package/esm/simple/room/SipRoom.js +125 -23
- package/esm/simple/room/Stream.js +125 -23
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -23
- package/esm/simple/utils.js +125 -23
- package/esm/utils/__tests__/api-requester.test.js +1 -1
- package/esm/utils/api-requester.js +1 -1
- package/esm/web-rtc-client.js +117 -23
- package/esm/websocket-client.js +1 -1
- package/lib/__tests__/api-client.test.js +9 -5
- package/lib/__tests__/web-rtc-client.test.js +117 -23
- package/lib/api/agentd.js +1 -1
- package/lib/api/amid.js +1 -1
- package/lib/api/application.js +1 -1
- package/lib/api/auth.js +1 -1
- package/lib/api/call-logd.js +3 -3
- package/lib/api/calld.js +1 -1
- package/lib/api/chatd.js +1 -1
- package/lib/api/confd.js +7 -3
- package/lib/api/ctid-ng.js +1 -1
- package/lib/api/dird.js +1 -1
- package/lib/api/webhookd.js +1 -1
- package/lib/api-client.js +9 -5
- package/lib/checker/Checker.js +117 -23
- package/lib/checker/checks/aor.js +9 -5
- package/lib/checker/checks/api.js +9 -5
- package/lib/checker/checks/index.js +117 -23
- package/lib/checker/checks/wazo-websocket.js +1 -1
- package/lib/checker/checks/webrtc-transport.js +117 -23
- package/lib/checker/checks/webrtc.js +117 -23
- package/lib/domain/AdHocAPIConference.js +9 -5
- package/lib/domain/CallLog.js +2 -2
- package/lib/domain/Features.js +9 -5
- package/lib/domain/Meeting.js +6 -2
- package/lib/domain/Phone/CTIPhone.js +9 -5
- package/lib/domain/Phone/WebRTCPhone.js +9 -1
- package/lib/domain/Recording.js +1 -1
- package/lib/domain/__tests__/CallLog.test.js +2 -2
- package/lib/index.js +125 -23
- package/lib/lib/WazoSessionDescriptionHandler.js +1 -1
- package/lib/service/CallApi.js +9 -5
- package/lib/service/IssueReporter.js +1 -1
- package/lib/service/__tests__/IssueReporter.test.js +1 -1
- package/lib/service/getApiClient.js +9 -5
- package/lib/simple/Auth.js +125 -23
- package/lib/simple/Configuration.js +125 -23
- package/lib/simple/Directory.js +9 -5
- package/lib/simple/Phone.js +125 -23
- package/lib/simple/Websocket.js +1 -1
- package/lib/simple/index.js +125 -23
- package/lib/simple/room/LocalParticipant.js +125 -23
- package/lib/simple/room/Participant.js +125 -23
- package/lib/simple/room/RemoteParticipant.js +125 -23
- package/lib/simple/room/Room.js +125 -23
- package/lib/simple/room/SipRoom.js +125 -23
- package/lib/simple/room/Stream.js +125 -23
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -23
- package/lib/simple/utils.js +125 -23
- package/lib/utils/__tests__/api-requester.test.js +1 -1
- package/lib/utils/api-requester.js +1 -1
- package/lib/web-rtc-client.js +117 -23
- package/lib/websocket-client.js +1 -1
- package/package.json +1 -1
- package/src/domain/CallLog.js +1 -1
- package/src/domain/Meeting.js +6 -2
- package/src/domain/Phone/WebRTCPhone.js +7 -0
- package/src/domain/Recording.js +1 -1
- package/src/service/IssueReporter.js +1 -1
- package/src/web-rtc-client.js +108 -18
|
@@ -390,7 +390,7 @@ class IssueReporter {
|
|
|
390
390
|
payload._retry = retry + 1;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
this._sendDebugToGrafana(
|
|
393
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
394
394
|
}, 5000 + retry * 1000);
|
|
395
395
|
});
|
|
396
396
|
}
|
|
@@ -2593,7 +2593,8 @@ class ExternalApp {
|
|
|
2593
2593
|
|
|
2594
2594
|
|
|
2595
2595
|
|
|
2596
|
-
|
|
2596
|
+
|
|
2597
|
+
|
|
2597
2598
|
|
|
2598
2599
|
|
|
2599
2600
|
class Meeting {
|
|
@@ -2605,6 +2606,7 @@ class Meeting {
|
|
|
2605
2606
|
|
|
2606
2607
|
|
|
2607
2608
|
|
|
2609
|
+
|
|
2608
2610
|
|
|
2609
2611
|
|
|
2610
2612
|
static parse(plain ) {
|
|
@@ -2616,6 +2618,7 @@ class Meeting {
|
|
|
2616
2618
|
port: plain.port,
|
|
2617
2619
|
uuid: plain.uuid,
|
|
2618
2620
|
number: plain.number,
|
|
2621
|
+
persistent: plain.persistent,
|
|
2619
2622
|
});
|
|
2620
2623
|
}
|
|
2621
2624
|
|
|
@@ -2623,7 +2626,7 @@ class Meeting {
|
|
|
2623
2626
|
return newFrom(meeting, Meeting);
|
|
2624
2627
|
}
|
|
2625
2628
|
|
|
2626
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2629
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2627
2630
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2628
2631
|
this.uri = uri;
|
|
2629
2632
|
this.name = name;
|
|
@@ -2631,6 +2634,7 @@ class Meeting {
|
|
|
2631
2634
|
this.port = port;
|
|
2632
2635
|
this.uuid = uuid;
|
|
2633
2636
|
this.number = number;
|
|
2637
|
+
this.persistent = persistent;
|
|
2634
2638
|
|
|
2635
2639
|
// Useful to compare instead of instanceof with minified code
|
|
2636
2640
|
this.type = 'Meeting';
|
|
@@ -3194,7 +3198,7 @@ class Recording {
|
|
|
3194
3198
|
|
|
3195
3199
|
|
|
3196
3200
|
|
|
3197
|
-
static parseMany(recordings
|
|
3201
|
+
static parseMany(recordings = []) {
|
|
3198
3202
|
return recordings.map(item => Recording.parse(item));
|
|
3199
3203
|
}
|
|
3200
3204
|
|
|
@@ -3320,7 +3324,7 @@ class CallLog {
|
|
|
3320
3324
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3321
3325
|
start: moment__default['default'](plain.start).toDate(),
|
|
3322
3326
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3323
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3327
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3324
3328
|
});
|
|
3325
3329
|
}
|
|
3326
3330
|
|
package/lib/simple/Auth.js
CHANGED
|
@@ -1898,7 +1898,7 @@ class IssueReporter {
|
|
|
1898
1898
|
payload._retry = retry + 1;
|
|
1899
1899
|
}
|
|
1900
1900
|
|
|
1901
|
-
this._sendDebugToGrafana(
|
|
1901
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
1902
1902
|
}, 5000 + retry * 1000);
|
|
1903
1903
|
});
|
|
1904
1904
|
}
|
|
@@ -2616,7 +2616,8 @@ class ExternalApp {
|
|
|
2616
2616
|
|
|
2617
2617
|
|
|
2618
2618
|
|
|
2619
|
-
|
|
2619
|
+
|
|
2620
|
+
|
|
2620
2621
|
|
|
2621
2622
|
|
|
2622
2623
|
class Meeting {
|
|
@@ -2628,6 +2629,7 @@ class Meeting {
|
|
|
2628
2629
|
|
|
2629
2630
|
|
|
2630
2631
|
|
|
2632
|
+
|
|
2631
2633
|
|
|
2632
2634
|
|
|
2633
2635
|
static parse(plain ) {
|
|
@@ -2639,6 +2641,7 @@ class Meeting {
|
|
|
2639
2641
|
port: plain.port,
|
|
2640
2642
|
uuid: plain.uuid,
|
|
2641
2643
|
number: plain.number,
|
|
2644
|
+
persistent: plain.persistent,
|
|
2642
2645
|
});
|
|
2643
2646
|
}
|
|
2644
2647
|
|
|
@@ -2646,7 +2649,7 @@ class Meeting {
|
|
|
2646
2649
|
return newFrom(meeting, Meeting);
|
|
2647
2650
|
}
|
|
2648
2651
|
|
|
2649
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2652
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2650
2653
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2651
2654
|
this.uri = uri;
|
|
2652
2655
|
this.name = name;
|
|
@@ -2654,6 +2657,7 @@ class Meeting {
|
|
|
2654
2657
|
this.port = port;
|
|
2655
2658
|
this.uuid = uuid;
|
|
2656
2659
|
this.number = number;
|
|
2660
|
+
this.persistent = persistent;
|
|
2657
2661
|
|
|
2658
2662
|
// Useful to compare instead of instanceof with minified code
|
|
2659
2663
|
this.type = 'Meeting';
|
|
@@ -3588,7 +3592,7 @@ class Recording {
|
|
|
3588
3592
|
|
|
3589
3593
|
|
|
3590
3594
|
|
|
3591
|
-
static parseMany(recordings
|
|
3595
|
+
static parseMany(recordings = []) {
|
|
3592
3596
|
return recordings.map(item => Recording.parse(item));
|
|
3593
3597
|
}
|
|
3594
3598
|
|
|
@@ -3714,7 +3718,7 @@ class CallLog {
|
|
|
3714
3718
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3715
3719
|
start: moment__default['default'](plain.start).toDate(),
|
|
3716
3720
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3717
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3721
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3718
3722
|
});
|
|
3719
3723
|
}
|
|
3720
3724
|
|
|
@@ -6295,6 +6299,7 @@ const ON_REINVITE$1 = 'reinvite';
|
|
|
6295
6299
|
const ON_ERROR = 'onError';
|
|
6296
6300
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
6297
6301
|
const ON_NETWORK_STATS$1 = 'onNetworkStats';
|
|
6302
|
+
const ON_DISCONNECTED$1 = 'onDisconnected';
|
|
6298
6303
|
|
|
6299
6304
|
const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
6300
6305
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
@@ -6371,6 +6376,7 @@ class WebRTCClient extends Emitter {
|
|
|
6371
6376
|
|
|
6372
6377
|
|
|
6373
6378
|
|
|
6379
|
+
|
|
6374
6380
|
|
|
6375
6381
|
static isAPrivateIp(ip ) {
|
|
6376
6382
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -6436,6 +6442,7 @@ class WebRTCClient extends Emitter {
|
|
|
6436
6442
|
this.ON_ERROR = ON_ERROR;
|
|
6437
6443
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
6438
6444
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
|
|
6445
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED$1;
|
|
6439
6446
|
}
|
|
6440
6447
|
|
|
6441
6448
|
configureMedia(media ) {
|
|
@@ -7037,7 +7044,7 @@ class WebRTCClient extends Emitter {
|
|
|
7037
7044
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
7038
7045
|
const transceivers = pc.getTransceivers();
|
|
7039
7046
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
7040
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
7047
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
7041
7048
|
|
|
7042
7049
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
7043
7050
|
} else {
|
|
@@ -7283,10 +7290,13 @@ class WebRTCClient extends Emitter {
|
|
|
7283
7290
|
return null;
|
|
7284
7291
|
}
|
|
7285
7292
|
|
|
7286
|
-
// let's update the local value
|
|
7287
|
-
if (this.audio
|
|
7288
|
-
|
|
7289
|
-
|
|
7293
|
+
// let's update the local audio value
|
|
7294
|
+
if (this.audio) {
|
|
7295
|
+
this.audio = {
|
|
7296
|
+
deviceId: {
|
|
7297
|
+
exact: id,
|
|
7298
|
+
},
|
|
7299
|
+
};
|
|
7290
7300
|
}
|
|
7291
7301
|
|
|
7292
7302
|
if (session) {
|
|
@@ -7299,6 +7309,9 @@ class WebRTCClient extends Emitter {
|
|
|
7299
7309
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
7300
7310
|
|
|
7301
7311
|
if (sender) {
|
|
7312
|
+
if (sender.track) {
|
|
7313
|
+
audioTrack.enabled = sender.track.enabled;
|
|
7314
|
+
}
|
|
7302
7315
|
sender.replaceTrack(audioTrack);
|
|
7303
7316
|
}
|
|
7304
7317
|
|
|
@@ -7323,7 +7336,7 @@ class WebRTCClient extends Emitter {
|
|
|
7323
7336
|
return null;
|
|
7324
7337
|
}
|
|
7325
7338
|
|
|
7326
|
-
// let's update the local value
|
|
7339
|
+
// let's update the local video value
|
|
7327
7340
|
if (this.video) {
|
|
7328
7341
|
this.video = {
|
|
7329
7342
|
deviceId: {
|
|
@@ -7358,12 +7371,21 @@ class WebRTCClient extends Emitter {
|
|
|
7358
7371
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
7359
7372
|
const videoTrack = stream.getVideoTracks()[0];
|
|
7360
7373
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
7374
|
+
let wasTrackEnabled = false;
|
|
7361
7375
|
if (!sender) {
|
|
7362
7376
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
7363
7377
|
}
|
|
7364
7378
|
|
|
7365
7379
|
if (sender) {
|
|
7366
|
-
|
|
7380
|
+
// No video track means video not enabled
|
|
7381
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
7382
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
7383
|
+
|
|
7384
|
+
if (!wasTrackEnabled) {
|
|
7385
|
+
videoTrack.stop();
|
|
7386
|
+
}
|
|
7387
|
+
|
|
7388
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
7367
7389
|
}
|
|
7368
7390
|
|
|
7369
7391
|
// let's update the local stream
|
|
@@ -8047,6 +8069,7 @@ class WebRTCClient extends Emitter {
|
|
|
8047
8069
|
|
|
8048
8070
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
8049
8071
|
|
|
8072
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
8050
8073
|
const onTrack = (event ) => {
|
|
8051
8074
|
const isAudioOnly = this._isAudioOnly(session);
|
|
8052
8075
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -8066,6 +8089,12 @@ class WebRTCClient extends Emitter {
|
|
|
8066
8089
|
|
|
8067
8090
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
8068
8091
|
|
|
8092
|
+
pc.oniceconnectionstatechange = () => {
|
|
8093
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
8094
|
+
this.eventEmitter.emit(ON_DISCONNECTED$1);
|
|
8095
|
+
}
|
|
8096
|
+
};
|
|
8097
|
+
|
|
8069
8098
|
if (withEvent) {
|
|
8070
8099
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
8071
8100
|
}
|
|
@@ -8261,24 +8290,89 @@ class WebRTCClient extends Emitter {
|
|
|
8261
8290
|
const session = this.getSipSession(sessionId);
|
|
8262
8291
|
|
|
8263
8292
|
const stats = session ? await this.getStats(session) : null;
|
|
8264
|
-
if (!stats) {
|
|
8293
|
+
if (!stats || !(sessionId in this.sessionNetworkStats)) {
|
|
8265
8294
|
return;
|
|
8266
8295
|
}
|
|
8267
8296
|
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8297
|
+
const networkStats = {
|
|
8298
|
+
audioBytesSent: 0,
|
|
8299
|
+
videoBytesSent: 0,
|
|
8300
|
+
videoBytesReceived: 0,
|
|
8301
|
+
audioBytesReceived: 0,
|
|
8302
|
+
};
|
|
8303
|
+
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
8304
|
+
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
8305
|
+
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
8306
|
+
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
8307
|
+
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
8308
|
+
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
8309
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
8310
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
8311
|
+
let audioBytesSent = 0;
|
|
8312
|
+
let audioBytesReceived = 0;
|
|
8313
|
+
let videoBytesSent = 0;
|
|
8314
|
+
let videoBytesReceived = 0;
|
|
8315
|
+
let transportSent = 0;
|
|
8316
|
+
let transportReceived = 0;
|
|
8317
|
+
let packetsLost = 0;
|
|
8276
8318
|
|
|
8277
|
-
|
|
8278
|
-
|
|
8319
|
+
stats.forEach(report => {
|
|
8320
|
+
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
8321
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8322
|
+
}
|
|
8323
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
8324
|
+
audioBytesSent += report.bytesSent;
|
|
8325
|
+
}
|
|
8326
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8327
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8328
|
+
}
|
|
8329
|
+
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
8330
|
+
packetsLost += report.packetsLost;
|
|
8331
|
+
networkStats.packetsReceived = report.packetsReceived;
|
|
8332
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8333
|
+
}
|
|
8334
|
+
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
8335
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8336
|
+
}
|
|
8337
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8338
|
+
if ('framesPerSecond' in report) {
|
|
8339
|
+
networkStats.framesPerSecond = report.framesPerSecond;
|
|
8340
|
+
}
|
|
8341
|
+
if ('framerateMean' in report) {
|
|
8342
|
+
// framerateMean is only available in FF
|
|
8343
|
+
networkStats.framesPerSecond = Math.round(report.framerateMean);
|
|
8279
8344
|
}
|
|
8280
8345
|
}
|
|
8346
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
8347
|
+
packetsLost += report.packetsLost;
|
|
8348
|
+
networkStats.roundTripTime = report.roundTripTime;
|
|
8349
|
+
networkStats.jitter = report.jitter;
|
|
8350
|
+
}
|
|
8351
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
8352
|
+
packetsLost += report.packetsLost;
|
|
8353
|
+
}
|
|
8354
|
+
if (report.type === 'transport') {
|
|
8355
|
+
transportSent += report.bytesSent;
|
|
8356
|
+
transportReceived += report.bytesReceived;
|
|
8357
|
+
}
|
|
8281
8358
|
});
|
|
8359
|
+
|
|
8360
|
+
networkStats.packetsLost = packetsLost;
|
|
8361
|
+
networkStats.audioBytesSent = audioBytesSent;
|
|
8362
|
+
networkStats.audioBytesReceived = audioBytesReceived;
|
|
8363
|
+
networkStats.videoBytesSent = videoBytesSent;
|
|
8364
|
+
networkStats.videoBytesReceived = videoBytesReceived;
|
|
8365
|
+
networkStats.transportSent = transportSent;
|
|
8366
|
+
networkStats.transportReceived = transportReceived;
|
|
8367
|
+
|
|
8368
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
8369
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
8370
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
8371
|
+
|
|
8372
|
+
networkStats.bandwidth = bandwidth;
|
|
8373
|
+
|
|
8374
|
+
this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
8375
|
+
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
8282
8376
|
}
|
|
8283
8377
|
|
|
8284
8378
|
}
|
|
@@ -8324,6 +8418,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
|
8324
8418
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
8325
8419
|
const ON_CHAT = 'phone/ON_CHAT';
|
|
8326
8420
|
const ON_SIGNAL = 'phone/ON_SIGNAL';
|
|
8421
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
8327
8422
|
|
|
8328
8423
|
const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
8329
8424
|
const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
@@ -8363,6 +8458,7 @@ const events = [
|
|
|
8363
8458
|
ON_CHAT,
|
|
8364
8459
|
ON_SIGNAL,
|
|
8365
8460
|
ON_NETWORK_STATS,
|
|
8461
|
+
ON_DISCONNECTED,
|
|
8366
8462
|
];
|
|
8367
8463
|
|
|
8368
8464
|
const logger$8 = IssueReporter$1.loggerFor('webrtc-phone');
|
|
@@ -9715,6 +9811,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9715
9811
|
this.eventEmitter.emit(ON_UNREGISTERED);
|
|
9716
9812
|
});
|
|
9717
9813
|
|
|
9814
|
+
this.client.on(this.client.ON_DISCONNECTED, () => {
|
|
9815
|
+
logger$8.info('WebRTC disconnected');
|
|
9816
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
9817
|
+
});
|
|
9818
|
+
|
|
9718
9819
|
this.client.on(this.client.REGISTERED, () => {
|
|
9719
9820
|
logger$8.info('WebRTC registered', {
|
|
9720
9821
|
shouldSendReinvite: this.shouldSendReinvite,
|
|
@@ -9971,6 +10072,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
|
|
|
9971
10072
|
ON_NETWORK_STATS: ON_NETWORK_STATS,
|
|
9972
10073
|
ON_CHAT: ON_CHAT,
|
|
9973
10074
|
ON_SIGNAL: ON_SIGNAL,
|
|
10075
|
+
ON_DISCONNECTED: ON_DISCONNECTED,
|
|
9974
10076
|
MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
|
|
9975
10077
|
MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
|
|
9976
10078
|
events: events,
|
|
@@ -1896,7 +1896,7 @@ class IssueReporter {
|
|
|
1896
1896
|
payload._retry = retry + 1;
|
|
1897
1897
|
}
|
|
1898
1898
|
|
|
1899
|
-
this._sendDebugToGrafana(
|
|
1899
|
+
this._sendDebugToGrafana(payload, retry + 1);
|
|
1900
1900
|
}, 5000 + retry * 1000);
|
|
1901
1901
|
});
|
|
1902
1902
|
}
|
|
@@ -2614,7 +2614,8 @@ class ExternalApp {
|
|
|
2614
2614
|
|
|
2615
2615
|
|
|
2616
2616
|
|
|
2617
|
-
|
|
2617
|
+
|
|
2618
|
+
|
|
2618
2619
|
|
|
2619
2620
|
|
|
2620
2621
|
class Meeting {
|
|
@@ -2626,6 +2627,7 @@ class Meeting {
|
|
|
2626
2627
|
|
|
2627
2628
|
|
|
2628
2629
|
|
|
2630
|
+
|
|
2629
2631
|
|
|
2630
2632
|
|
|
2631
2633
|
static parse(plain ) {
|
|
@@ -2637,6 +2639,7 @@ class Meeting {
|
|
|
2637
2639
|
port: plain.port,
|
|
2638
2640
|
uuid: plain.uuid,
|
|
2639
2641
|
number: plain.number,
|
|
2642
|
+
persistent: plain.persistent,
|
|
2640
2643
|
});
|
|
2641
2644
|
}
|
|
2642
2645
|
|
|
@@ -2644,7 +2647,7 @@ class Meeting {
|
|
|
2644
2647
|
return newFrom(meeting, Meeting);
|
|
2645
2648
|
}
|
|
2646
2649
|
|
|
2647
|
-
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
|
|
2650
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
|
|
2648
2651
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2649
2652
|
this.uri = uri;
|
|
2650
2653
|
this.name = name;
|
|
@@ -2652,6 +2655,7 @@ class Meeting {
|
|
|
2652
2655
|
this.port = port;
|
|
2653
2656
|
this.uuid = uuid;
|
|
2654
2657
|
this.number = number;
|
|
2658
|
+
this.persistent = persistent;
|
|
2655
2659
|
|
|
2656
2660
|
// Useful to compare instead of instanceof with minified code
|
|
2657
2661
|
this.type = 'Meeting';
|
|
@@ -3586,7 +3590,7 @@ class Recording {
|
|
|
3586
3590
|
|
|
3587
3591
|
|
|
3588
3592
|
|
|
3589
|
-
static parseMany(recordings
|
|
3593
|
+
static parseMany(recordings = []) {
|
|
3590
3594
|
return recordings.map(item => Recording.parse(item));
|
|
3591
3595
|
}
|
|
3592
3596
|
|
|
@@ -3712,7 +3716,7 @@ class CallLog {
|
|
|
3712
3716
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3713
3717
|
start: moment__default['default'](plain.start).toDate(),
|
|
3714
3718
|
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3715
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3719
|
+
recordings: Recording.parseMany(plain.recordings || []),
|
|
3716
3720
|
});
|
|
3717
3721
|
}
|
|
3718
3722
|
|
|
@@ -6293,6 +6297,7 @@ const ON_REINVITE$1 = 'reinvite';
|
|
|
6293
6297
|
const ON_ERROR = 'onError';
|
|
6294
6298
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
6295
6299
|
const ON_NETWORK_STATS$1 = 'onNetworkStats';
|
|
6300
|
+
const ON_DISCONNECTED$1 = 'onDisconnected';
|
|
6296
6301
|
|
|
6297
6302
|
const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
6298
6303
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
@@ -6369,6 +6374,7 @@ class WebRTCClient extends Emitter {
|
|
|
6369
6374
|
|
|
6370
6375
|
|
|
6371
6376
|
|
|
6377
|
+
|
|
6372
6378
|
|
|
6373
6379
|
static isAPrivateIp(ip ) {
|
|
6374
6380
|
const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
|
|
@@ -6434,6 +6440,7 @@ class WebRTCClient extends Emitter {
|
|
|
6434
6440
|
this.ON_ERROR = ON_ERROR;
|
|
6435
6441
|
this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
|
|
6436
6442
|
this.ON_NETWORK_STATS = ON_NETWORK_STATS$1;
|
|
6443
|
+
this.ON_DISCONNECTED = ON_DISCONNECTED$1;
|
|
6437
6444
|
}
|
|
6438
6445
|
|
|
6439
6446
|
configureMedia(media ) {
|
|
@@ -7035,7 +7042,7 @@ class WebRTCClient extends Emitter {
|
|
|
7035
7042
|
// We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
|
|
7036
7043
|
const transceivers = pc.getTransceivers();
|
|
7037
7044
|
const transceiverIdx = lastIndexOf(transceivers, transceiver =>
|
|
7038
|
-
transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
|
|
7045
|
+
transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
|
|
7039
7046
|
|
|
7040
7047
|
videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
|
|
7041
7048
|
} else {
|
|
@@ -7281,10 +7288,13 @@ class WebRTCClient extends Emitter {
|
|
|
7281
7288
|
return null;
|
|
7282
7289
|
}
|
|
7283
7290
|
|
|
7284
|
-
// let's update the local value
|
|
7285
|
-
if (this.audio
|
|
7286
|
-
|
|
7287
|
-
|
|
7291
|
+
// let's update the local audio value
|
|
7292
|
+
if (this.audio) {
|
|
7293
|
+
this.audio = {
|
|
7294
|
+
deviceId: {
|
|
7295
|
+
exact: id,
|
|
7296
|
+
},
|
|
7297
|
+
};
|
|
7288
7298
|
}
|
|
7289
7299
|
|
|
7290
7300
|
if (session) {
|
|
@@ -7297,6 +7307,9 @@ class WebRTCClient extends Emitter {
|
|
|
7297
7307
|
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
7298
7308
|
|
|
7299
7309
|
if (sender) {
|
|
7310
|
+
if (sender.track) {
|
|
7311
|
+
audioTrack.enabled = sender.track.enabled;
|
|
7312
|
+
}
|
|
7300
7313
|
sender.replaceTrack(audioTrack);
|
|
7301
7314
|
}
|
|
7302
7315
|
|
|
@@ -7321,7 +7334,7 @@ class WebRTCClient extends Emitter {
|
|
|
7321
7334
|
return null;
|
|
7322
7335
|
}
|
|
7323
7336
|
|
|
7324
|
-
// let's update the local value
|
|
7337
|
+
// let's update the local video value
|
|
7325
7338
|
if (this.video) {
|
|
7326
7339
|
this.video = {
|
|
7327
7340
|
deviceId: {
|
|
@@ -7356,12 +7369,21 @@ class WebRTCClient extends Emitter {
|
|
|
7356
7369
|
return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
|
|
7357
7370
|
const videoTrack = stream.getVideoTracks()[0];
|
|
7358
7371
|
let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
|
|
7372
|
+
let wasTrackEnabled = false;
|
|
7359
7373
|
if (!sender) {
|
|
7360
7374
|
sender = pc && pc.getSenders().find(s => !s.track);
|
|
7361
7375
|
}
|
|
7362
7376
|
|
|
7363
7377
|
if (sender) {
|
|
7364
|
-
|
|
7378
|
+
// No video track means video not enabled
|
|
7379
|
+
wasTrackEnabled = sender.track ? sender.track.enabled : false;
|
|
7380
|
+
videoTrack.enabled = wasTrackEnabled;
|
|
7381
|
+
|
|
7382
|
+
if (!wasTrackEnabled) {
|
|
7383
|
+
videoTrack.stop();
|
|
7384
|
+
}
|
|
7385
|
+
|
|
7386
|
+
sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
|
|
7365
7387
|
}
|
|
7366
7388
|
|
|
7367
7389
|
// let's update the local stream
|
|
@@ -8045,6 +8067,7 @@ class WebRTCClient extends Emitter {
|
|
|
8045
8067
|
|
|
8046
8068
|
this.updateRemoteStream(this.getSipSessionId(session));
|
|
8047
8069
|
|
|
8070
|
+
const pc = session.sessionDescriptionHandler.peerConnection;
|
|
8048
8071
|
const onTrack = (event ) => {
|
|
8049
8072
|
const isAudioOnly = this._isAudioOnly(session);
|
|
8050
8073
|
const { kind, label, readyState, id, muted } = event.track;
|
|
@@ -8064,6 +8087,12 @@ class WebRTCClient extends Emitter {
|
|
|
8064
8087
|
|
|
8065
8088
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
8066
8089
|
|
|
8090
|
+
pc.oniceconnectionstatechange = () => {
|
|
8091
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
8092
|
+
this.eventEmitter.emit(ON_DISCONNECTED$1);
|
|
8093
|
+
}
|
|
8094
|
+
};
|
|
8095
|
+
|
|
8067
8096
|
if (withEvent) {
|
|
8068
8097
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
8069
8098
|
}
|
|
@@ -8259,24 +8288,89 @@ class WebRTCClient extends Emitter {
|
|
|
8259
8288
|
const session = this.getSipSession(sessionId);
|
|
8260
8289
|
|
|
8261
8290
|
const stats = session ? await this.getStats(session) : null;
|
|
8262
|
-
if (!stats) {
|
|
8291
|
+
if (!stats || !(sessionId in this.sessionNetworkStats)) {
|
|
8263
8292
|
return;
|
|
8264
8293
|
}
|
|
8265
8294
|
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8295
|
+
const networkStats = {
|
|
8296
|
+
audioBytesSent: 0,
|
|
8297
|
+
videoBytesSent: 0,
|
|
8298
|
+
videoBytesReceived: 0,
|
|
8299
|
+
audioBytesReceived: 0,
|
|
8300
|
+
};
|
|
8301
|
+
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
8302
|
+
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
8303
|
+
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
8304
|
+
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
8305
|
+
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
8306
|
+
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
8307
|
+
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
8308
|
+
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
8309
|
+
let audioBytesSent = 0;
|
|
8310
|
+
let audioBytesReceived = 0;
|
|
8311
|
+
let videoBytesSent = 0;
|
|
8312
|
+
let videoBytesReceived = 0;
|
|
8313
|
+
let transportSent = 0;
|
|
8314
|
+
let transportReceived = 0;
|
|
8315
|
+
let packetsLost = 0;
|
|
8274
8316
|
|
|
8275
|
-
|
|
8276
|
-
|
|
8317
|
+
stats.forEach(report => {
|
|
8318
|
+
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
8319
|
+
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8320
|
+
}
|
|
8321
|
+
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
8322
|
+
audioBytesSent += report.bytesSent;
|
|
8323
|
+
}
|
|
8324
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8325
|
+
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8326
|
+
}
|
|
8327
|
+
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
8328
|
+
packetsLost += report.packetsLost;
|
|
8329
|
+
networkStats.packetsReceived = report.packetsReceived;
|
|
8330
|
+
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8331
|
+
}
|
|
8332
|
+
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
8333
|
+
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8334
|
+
}
|
|
8335
|
+
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8336
|
+
if ('framesPerSecond' in report) {
|
|
8337
|
+
networkStats.framesPerSecond = report.framesPerSecond;
|
|
8338
|
+
}
|
|
8339
|
+
if ('framerateMean' in report) {
|
|
8340
|
+
// framerateMean is only available in FF
|
|
8341
|
+
networkStats.framesPerSecond = Math.round(report.framerateMean);
|
|
8277
8342
|
}
|
|
8278
8343
|
}
|
|
8344
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
8345
|
+
packetsLost += report.packetsLost;
|
|
8346
|
+
networkStats.roundTripTime = report.roundTripTime;
|
|
8347
|
+
networkStats.jitter = report.jitter;
|
|
8348
|
+
}
|
|
8349
|
+
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
8350
|
+
packetsLost += report.packetsLost;
|
|
8351
|
+
}
|
|
8352
|
+
if (report.type === 'transport') {
|
|
8353
|
+
transportSent += report.bytesSent;
|
|
8354
|
+
transportReceived += report.bytesReceived;
|
|
8355
|
+
}
|
|
8279
8356
|
});
|
|
8357
|
+
|
|
8358
|
+
networkStats.packetsLost = packetsLost;
|
|
8359
|
+
networkStats.audioBytesSent = audioBytesSent;
|
|
8360
|
+
networkStats.audioBytesReceived = audioBytesReceived;
|
|
8361
|
+
networkStats.videoBytesSent = videoBytesSent;
|
|
8362
|
+
networkStats.videoBytesReceived = videoBytesReceived;
|
|
8363
|
+
networkStats.transportSent = transportSent;
|
|
8364
|
+
networkStats.transportReceived = transportReceived;
|
|
8365
|
+
|
|
8366
|
+
const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
|
|
8367
|
+
+ (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
|
|
8368
|
+
+ (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
|
|
8369
|
+
|
|
8370
|
+
networkStats.bandwidth = bandwidth;
|
|
8371
|
+
|
|
8372
|
+
this.eventEmitter.emit(ON_NETWORK_STATS$1, session, networkStats, this.sessionNetworkStats[sessionId]);
|
|
8373
|
+
this.sessionNetworkStats[sessionId].push(networkStats);
|
|
8280
8374
|
}
|
|
8281
8375
|
|
|
8282
8376
|
}
|
|
@@ -8322,6 +8416,7 @@ const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
|
8322
8416
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
8323
8417
|
const ON_CHAT = 'phone/ON_CHAT';
|
|
8324
8418
|
const ON_SIGNAL = 'phone/ON_SIGNAL';
|
|
8419
|
+
const ON_DISCONNECTED = 'onDisconnected';
|
|
8325
8420
|
|
|
8326
8421
|
const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
8327
8422
|
const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
@@ -8361,6 +8456,7 @@ const events = [
|
|
|
8361
8456
|
ON_CHAT,
|
|
8362
8457
|
ON_SIGNAL,
|
|
8363
8458
|
ON_NETWORK_STATS,
|
|
8459
|
+
ON_DISCONNECTED,
|
|
8364
8460
|
];
|
|
8365
8461
|
|
|
8366
8462
|
const logger$8 = IssueReporter$1.loggerFor('webrtc-phone');
|
|
@@ -9713,6 +9809,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9713
9809
|
this.eventEmitter.emit(ON_UNREGISTERED);
|
|
9714
9810
|
});
|
|
9715
9811
|
|
|
9812
|
+
this.client.on(this.client.ON_DISCONNECTED, () => {
|
|
9813
|
+
logger$8.info('WebRTC disconnected');
|
|
9814
|
+
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
9815
|
+
});
|
|
9816
|
+
|
|
9716
9817
|
this.client.on(this.client.REGISTERED, () => {
|
|
9717
9818
|
logger$8.info('WebRTC registered', {
|
|
9718
9819
|
shouldSendReinvite: this.shouldSendReinvite,
|
|
@@ -9969,6 +10070,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
|
|
|
9969
10070
|
ON_NETWORK_STATS: ON_NETWORK_STATS,
|
|
9970
10071
|
ON_CHAT: ON_CHAT,
|
|
9971
10072
|
ON_SIGNAL: ON_SIGNAL,
|
|
10073
|
+
ON_DISCONNECTED: ON_DISCONNECTED,
|
|
9972
10074
|
MESSAGE_TYPE_CHAT: MESSAGE_TYPE_CHAT,
|
|
9973
10075
|
MESSAGE_TYPE_SIGNAL: MESSAGE_TYPE_SIGNAL,
|
|
9974
10076
|
events: events,
|