@koi-design/callkit 2.3.0-beta.9 → 2.3.1-beta.2
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/index.d.ts +45 -2
- package/dist/index.global.js +445 -47
- package/dist/index.js +440 -42
- package/dist/index.mjs +440 -42
- package/package.json +2 -2
- package/dist/index.global.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -72,7 +72,7 @@ var Api = class {
|
|
|
72
72
|
const res = await this.post({
|
|
73
73
|
url: "/auth/agentUser/login",
|
|
74
74
|
method: "post",
|
|
75
|
-
data: params
|
|
75
|
+
data: { ...params, browserVersion: navigator.userAgent }
|
|
76
76
|
});
|
|
77
77
|
return res;
|
|
78
78
|
} finally {
|
|
@@ -535,7 +535,11 @@ var SocketReceiveEvent = {
|
|
|
535
535
|
ERROR: "ERROR",
|
|
536
536
|
SESSION_ERROR: "SESSION_ERROR",
|
|
537
537
|
WAITING_QUEUE: "WAITING_QUEUE",
|
|
538
|
-
CUSTOMER_MATCH_BLACK_PHONE: "CUSTOMER_MATCH_BLACK_PHONE"
|
|
538
|
+
CUSTOMER_MATCH_BLACK_PHONE: "CUSTOMER_MATCH_BLACK_PHONE",
|
|
539
|
+
/**
|
|
540
|
+
* Agent RTP loss
|
|
541
|
+
*/
|
|
542
|
+
AGENT_RTP_LOSS: "AGENT_RTP_LOSS"
|
|
539
543
|
};
|
|
540
544
|
var EncryptionMethod = {
|
|
541
545
|
NONE: "NONE",
|
|
@@ -580,7 +584,9 @@ var SIP_RECONNECT_CONFIG = {
|
|
|
580
584
|
delay: 1e3,
|
|
581
585
|
registererOptions: {
|
|
582
586
|
refreshFrequency: 90
|
|
583
|
-
}
|
|
587
|
+
},
|
|
588
|
+
enableMessageKeepalive: true,
|
|
589
|
+
messageKeepaliveInterval: 30
|
|
584
590
|
};
|
|
585
591
|
|
|
586
592
|
// core/call.ts
|
|
@@ -724,13 +730,13 @@ var Call = class {
|
|
|
724
730
|
// package.json
|
|
725
731
|
var package_default = {
|
|
726
732
|
name: "@koi-design/callkit",
|
|
727
|
-
version: "2.3.
|
|
733
|
+
version: "2.3.1-beta.2",
|
|
728
734
|
description: "callkit",
|
|
729
735
|
author: "koi",
|
|
730
736
|
license: "ISC",
|
|
731
737
|
scripts: {
|
|
732
738
|
build: "tsup",
|
|
733
|
-
start: "
|
|
739
|
+
start: "vite --host 0.0.0.0",
|
|
734
740
|
dev: "tsup --watch",
|
|
735
741
|
lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
|
|
736
742
|
release: "tsup && node scripts/pkg.js"
|
|
@@ -15565,7 +15571,15 @@ var Connect = class {
|
|
|
15565
15571
|
this.callKit = callKit;
|
|
15566
15572
|
}
|
|
15567
15573
|
get reconnectConfig() {
|
|
15568
|
-
|
|
15574
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
15575
|
+
const { enableMessageKeepalive } = userInfo;
|
|
15576
|
+
const { messageKeepaliveInterval } = userInfo;
|
|
15577
|
+
const defaultConfig = this.callKit.config.getReconnectConfig("sip");
|
|
15578
|
+
if (enableMessageKeepalive) {
|
|
15579
|
+
defaultConfig.enableMessageKeepalive = enableMessageKeepalive;
|
|
15580
|
+
defaultConfig.messageKeepaliveInterval = messageKeepaliveInterval;
|
|
15581
|
+
}
|
|
15582
|
+
return defaultConfig;
|
|
15569
15583
|
}
|
|
15570
15584
|
// current call id for invite data
|
|
15571
15585
|
currentCallId = null;
|
|
@@ -15689,6 +15703,7 @@ var Connect = class {
|
|
|
15689
15703
|
}
|
|
15690
15704
|
}
|
|
15691
15705
|
this.setConnectStatus(CallStatus.init);
|
|
15706
|
+
this.stopMessageKeepalive();
|
|
15692
15707
|
}
|
|
15693
15708
|
getAduioReference() {
|
|
15694
15709
|
const { audioRef } = this.callKit.config.getConfig();
|
|
@@ -15824,8 +15839,6 @@ var Connect = class {
|
|
|
15824
15839
|
});
|
|
15825
15840
|
return;
|
|
15826
15841
|
}
|
|
15827
|
-
const { userInfo } = this.callKit.config.getConfig();
|
|
15828
|
-
const { userPart, fsIp, fsPort } = userInfo;
|
|
15829
15842
|
const { registererOptions = {} } = this.reconnectConfig;
|
|
15830
15843
|
this.registerer = new Registerer(this.userAgent, registererOptions);
|
|
15831
15844
|
this.registerer.stateChange.addListener((state) => {
|
|
@@ -15843,6 +15856,7 @@ var Connect = class {
|
|
|
15843
15856
|
if (!this.isInCallRefering()) {
|
|
15844
15857
|
this.setConnectStatus(CallStatus.init);
|
|
15845
15858
|
}
|
|
15859
|
+
this.stopMessageKeepalive();
|
|
15846
15860
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15847
15861
|
registererState: state,
|
|
15848
15862
|
isRegistered: this.isRegistered()
|
|
@@ -15859,27 +15873,26 @@ var Connect = class {
|
|
|
15859
15873
|
});
|
|
15860
15874
|
this.setRegister(true);
|
|
15861
15875
|
if (this.isReConnected) {
|
|
15862
|
-
if (this.
|
|
15863
|
-
const selfUri = `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
|
|
15876
|
+
if (this.canReferInCallToSelf()) {
|
|
15864
15877
|
this.callKit.logger.info(
|
|
15865
15878
|
"Reconnected, referring active session to self",
|
|
15866
15879
|
{
|
|
15867
15880
|
caller: "Connect.setupRegisterer.registererStateChange",
|
|
15868
15881
|
type: "SIP",
|
|
15869
15882
|
content: {
|
|
15870
|
-
selfUri,
|
|
15883
|
+
selfUri: this.getSelfReferUri(),
|
|
15871
15884
|
sessionState: this.currentSession.state,
|
|
15872
15885
|
connectStatus: this.connectStatus
|
|
15873
15886
|
}
|
|
15874
15887
|
}
|
|
15875
15888
|
);
|
|
15876
|
-
this.
|
|
15889
|
+
this.referInCallToSelf().catch((err) => {
|
|
15877
15890
|
this.callKit.logger.error(err, {
|
|
15878
15891
|
caller: "Connect.setupRegisterer.registererStateChange",
|
|
15879
15892
|
type: "SIP",
|
|
15880
15893
|
content: {
|
|
15881
15894
|
errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
|
|
15882
|
-
selfUri
|
|
15895
|
+
selfUri: this.getSelfReferUri()
|
|
15883
15896
|
}
|
|
15884
15897
|
});
|
|
15885
15898
|
});
|
|
@@ -15900,6 +15913,7 @@ var Connect = class {
|
|
|
15900
15913
|
}
|
|
15901
15914
|
this.setIsReConnected(false);
|
|
15902
15915
|
}
|
|
15916
|
+
this.startMessageKeepalive();
|
|
15903
15917
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15904
15918
|
registererState: state,
|
|
15905
15919
|
isRegistered: this.isRegistered()
|
|
@@ -15919,6 +15933,7 @@ var Connect = class {
|
|
|
15919
15933
|
if (!this.isInCallRefering()) {
|
|
15920
15934
|
this.setConnectStatus(CallStatus.init);
|
|
15921
15935
|
}
|
|
15936
|
+
this.stopMessageKeepalive();
|
|
15922
15937
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15923
15938
|
registererState: state,
|
|
15924
15939
|
isRegistered: this.isRegistered(),
|
|
@@ -15939,6 +15954,7 @@ var Connect = class {
|
|
|
15939
15954
|
if (!this.isInCallRefering()) {
|
|
15940
15955
|
this.setConnectStatus(CallStatus.init);
|
|
15941
15956
|
}
|
|
15957
|
+
this.stopMessageKeepalive();
|
|
15942
15958
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15943
15959
|
registererState: state,
|
|
15944
15960
|
isRegistered: this.isRegistered(),
|
|
@@ -15985,7 +16001,7 @@ var Connect = class {
|
|
|
15985
16001
|
this.mediaStream = await navigator.mediaDevices.getUserMedia(constrains);
|
|
15986
16002
|
return this.mediaStream;
|
|
15987
16003
|
};
|
|
15988
|
-
const { userPart, fsIp, fsPort, iceInfo, wsUrl } = userInfo;
|
|
16004
|
+
const { userPart, fsIp, fsPort, fsPassword, iceInfo, wsUrl } = userInfo;
|
|
15989
16005
|
const connectConfig = {
|
|
15990
16006
|
uri: UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`),
|
|
15991
16007
|
displayName: userPart,
|
|
@@ -15994,6 +16010,8 @@ var Connect = class {
|
|
|
15994
16010
|
traceSip: true
|
|
15995
16011
|
},
|
|
15996
16012
|
logLevel: "error",
|
|
16013
|
+
authorizationUsername: userPart,
|
|
16014
|
+
authorizationPassword: fsPassword,
|
|
15997
16015
|
allowLegacyNotifications: true,
|
|
15998
16016
|
contactName: userPart,
|
|
15999
16017
|
contactParams: { transport: "wss" },
|
|
@@ -16249,7 +16267,10 @@ var Connect = class {
|
|
|
16249
16267
|
}
|
|
16250
16268
|
});
|
|
16251
16269
|
this.setupRegisterer();
|
|
16252
|
-
|
|
16270
|
+
try {
|
|
16271
|
+
await this.registerer.register();
|
|
16272
|
+
this.startMessageKeepalive();
|
|
16273
|
+
} catch (err) {
|
|
16253
16274
|
this.callKit.reset();
|
|
16254
16275
|
this.callKit.logger.error(err?.message, {
|
|
16255
16276
|
caller: "Connect.register",
|
|
@@ -16258,9 +16279,10 @@ var Connect = class {
|
|
|
16258
16279
|
errCode: ErrorCode.WEBRTC_REGISTER_ERROR
|
|
16259
16280
|
}
|
|
16260
16281
|
});
|
|
16261
|
-
}
|
|
16282
|
+
}
|
|
16262
16283
|
},
|
|
16263
16284
|
onDisconnect: (error) => {
|
|
16285
|
+
this.stopMessageKeepalive();
|
|
16264
16286
|
if (error) {
|
|
16265
16287
|
this.callKit.logger.warn("SIP User Agent Disconnected with error", {
|
|
16266
16288
|
caller: "Connect.register",
|
|
@@ -16296,6 +16318,7 @@ var Connect = class {
|
|
|
16296
16318
|
}
|
|
16297
16319
|
reconnectTimer;
|
|
16298
16320
|
reconnectAttempts = 0;
|
|
16321
|
+
messageKeepaliveTimer;
|
|
16299
16322
|
startReconnectTimer() {
|
|
16300
16323
|
if (this._isError || this.isReConnected)
|
|
16301
16324
|
return;
|
|
@@ -16349,8 +16372,53 @@ var Connect = class {
|
|
|
16349
16372
|
}
|
|
16350
16373
|
}, this.reconnectConfig.delay);
|
|
16351
16374
|
}
|
|
16375
|
+
stopMessageKeepalive() {
|
|
16376
|
+
if (this.messageKeepaliveTimer) {
|
|
16377
|
+
clearInterval(this.messageKeepaliveTimer);
|
|
16378
|
+
this.messageKeepaliveTimer = void 0;
|
|
16379
|
+
}
|
|
16380
|
+
}
|
|
16381
|
+
startMessageKeepalive() {
|
|
16382
|
+
const { enableMessageKeepalive, messageKeepaliveInterval } = this.reconnectConfig;
|
|
16383
|
+
if (!enableMessageKeepalive)
|
|
16384
|
+
return;
|
|
16385
|
+
this.stopMessageKeepalive();
|
|
16386
|
+
this.messageKeepaliveTimer = setInterval(() => {
|
|
16387
|
+
this.sendKeepaliveMessage();
|
|
16388
|
+
}, messageKeepaliveInterval * 1e3);
|
|
16389
|
+
}
|
|
16390
|
+
async sendKeepaliveMessage() {
|
|
16391
|
+
try {
|
|
16392
|
+
if (!this.isRegistered() || !this.userAgent)
|
|
16393
|
+
return;
|
|
16394
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
16395
|
+
const { userPart, fsIp, fsPort } = userInfo || {};
|
|
16396
|
+
const target = UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`);
|
|
16397
|
+
if (!target)
|
|
16398
|
+
return;
|
|
16399
|
+
const messager = new Messager(this.userAgent, target, "");
|
|
16400
|
+
await messager.message();
|
|
16401
|
+
this.callKit.logger.info("MESSAGE keepalive ok", {
|
|
16402
|
+
caller: "Connect.sendKeepaliveMessage",
|
|
16403
|
+
type: "SIP",
|
|
16404
|
+
content: {}
|
|
16405
|
+
});
|
|
16406
|
+
} catch (err) {
|
|
16407
|
+
this.callKit.logger.error(err, {
|
|
16408
|
+
caller: "Connect.sendKeepaliveMessage",
|
|
16409
|
+
type: "SIP",
|
|
16410
|
+
content: {}
|
|
16411
|
+
});
|
|
16412
|
+
this.stopMessageKeepalive();
|
|
16413
|
+
this.callKit.trigger(KitEvent.SIP_CONNECT_EVENT, {
|
|
16414
|
+
event: "MESSAGE_KEEPALIVE_FAILED"
|
|
16415
|
+
});
|
|
16416
|
+
this.startReconnectTimer();
|
|
16417
|
+
}
|
|
16418
|
+
}
|
|
16352
16419
|
async stop() {
|
|
16353
16420
|
await this.userAgent.stop();
|
|
16421
|
+
this.stopMessageKeepalive();
|
|
16354
16422
|
}
|
|
16355
16423
|
async unregister() {
|
|
16356
16424
|
this.callKit.logger.info("connect unregister", {
|
|
@@ -16360,6 +16428,7 @@ var Connect = class {
|
|
|
16360
16428
|
isRegistered: this.isRegistered()
|
|
16361
16429
|
}
|
|
16362
16430
|
});
|
|
16431
|
+
this.stopMessageKeepalive();
|
|
16363
16432
|
if (!this.isRegistered() || !this.registerer) {
|
|
16364
16433
|
this.callKit.logger.warn("No registerer to unregister.", {
|
|
16365
16434
|
caller: "Connect.unregister",
|
|
@@ -16708,6 +16777,199 @@ var Connect = class {
|
|
|
16708
16777
|
}
|
|
16709
16778
|
this.currentSession.refer(target, extra?.sessionReferOptions);
|
|
16710
16779
|
}
|
|
16780
|
+
/**
|
|
16781
|
+
* Get the SIP URI for "refer to self" (same as reconnection refer logic).
|
|
16782
|
+
* Shared by referInCallToSelf and internal reconnection refer.
|
|
16783
|
+
*/
|
|
16784
|
+
getSelfReferUri() {
|
|
16785
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
16786
|
+
const { userPart, fsIp, fsPort } = userInfo;
|
|
16787
|
+
return `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
|
|
16788
|
+
}
|
|
16789
|
+
/**
|
|
16790
|
+
* Whether we can refer the current call to self (has active session in Established/Establishing and is calling).
|
|
16791
|
+
* Shared by reconnection logic and referInCallToSelf.
|
|
16792
|
+
*/
|
|
16793
|
+
canReferInCallToSelf() {
|
|
16794
|
+
return !!this.currentSession && (this.currentSession.state === SessionState2.Established || this.currentSession.state === SessionState2.Establishing) && this.isCalling();
|
|
16795
|
+
}
|
|
16796
|
+
/**
|
|
16797
|
+
* Refer the current call to self (e.g. Agent RTP loss recovery, post-reconnect recovery).
|
|
16798
|
+
* Socket and other callers can use this without constructing referTo.
|
|
16799
|
+
*/
|
|
16800
|
+
async referInCallToSelf(callUuid, extra) {
|
|
16801
|
+
if (callUuid && this.currentCallId !== callUuid) {
|
|
16802
|
+
this.callKit.logger.warn(
|
|
16803
|
+
"Cannot refer in call to self: callUuid mismatch",
|
|
16804
|
+
{
|
|
16805
|
+
caller: "Connect.referInCallToSelf",
|
|
16806
|
+
type: "SIP",
|
|
16807
|
+
content: {
|
|
16808
|
+
currentCallId: this.currentCallId,
|
|
16809
|
+
callUuid
|
|
16810
|
+
}
|
|
16811
|
+
}
|
|
16812
|
+
);
|
|
16813
|
+
return;
|
|
16814
|
+
}
|
|
16815
|
+
if (!this.canReferInCallToSelf()) {
|
|
16816
|
+
this.callKit.logger.warn(
|
|
16817
|
+
"Cannot refer in call to self: preconditions not met",
|
|
16818
|
+
{
|
|
16819
|
+
caller: "Connect.referInCallToSelf",
|
|
16820
|
+
type: "SIP",
|
|
16821
|
+
content: {
|
|
16822
|
+
hasCurrentSession: !!this.currentSession,
|
|
16823
|
+
sessionState: this.currentSession?.state,
|
|
16824
|
+
isCalling: this.isCalling()
|
|
16825
|
+
}
|
|
16826
|
+
}
|
|
16827
|
+
);
|
|
16828
|
+
return;
|
|
16829
|
+
}
|
|
16830
|
+
const selfUri = this.getSelfReferUri();
|
|
16831
|
+
return this.referInCall(selfUri, extra);
|
|
16832
|
+
}
|
|
16833
|
+
};
|
|
16834
|
+
|
|
16835
|
+
// core/heartbeat-worker.ts
|
|
16836
|
+
var workerCode = `
|
|
16837
|
+
let timer = null;
|
|
16838
|
+
let interval = 30000;
|
|
16839
|
+
|
|
16840
|
+
self.onmessage = function(e) {
|
|
16841
|
+
const { type, interval: newInterval } = e.data;
|
|
16842
|
+
|
|
16843
|
+
if (type === 'start') {
|
|
16844
|
+
if (timer) {
|
|
16845
|
+
clearInterval(timer);
|
|
16846
|
+
}
|
|
16847
|
+
interval = newInterval || interval;
|
|
16848
|
+
timer = setInterval(() => {
|
|
16849
|
+
self.postMessage({ type: 'tick' });
|
|
16850
|
+
}, interval);
|
|
16851
|
+
}
|
|
16852
|
+
|
|
16853
|
+
if (type === 'stop') {
|
|
16854
|
+
if (timer) {
|
|
16855
|
+
clearInterval(timer);
|
|
16856
|
+
timer = null;
|
|
16857
|
+
}
|
|
16858
|
+
}
|
|
16859
|
+
|
|
16860
|
+
if (type === 'updateInterval') {
|
|
16861
|
+
interval = newInterval;
|
|
16862
|
+
if (timer) {
|
|
16863
|
+
clearInterval(timer);
|
|
16864
|
+
timer = setInterval(() => {
|
|
16865
|
+
self.postMessage({ type: 'tick' });
|
|
16866
|
+
}, interval);
|
|
16867
|
+
}
|
|
16868
|
+
}
|
|
16869
|
+
};
|
|
16870
|
+
`;
|
|
16871
|
+
function createHeartbeatWorker() {
|
|
16872
|
+
try {
|
|
16873
|
+
const blob = new Blob([workerCode], { type: "application/javascript" });
|
|
16874
|
+
const workerUrl = URL.createObjectURL(blob);
|
|
16875
|
+
const worker = new Worker(workerUrl);
|
|
16876
|
+
URL.revokeObjectURL(workerUrl);
|
|
16877
|
+
return worker;
|
|
16878
|
+
} catch {
|
|
16879
|
+
return null;
|
|
16880
|
+
}
|
|
16881
|
+
}
|
|
16882
|
+
var HeartbeatManager = class {
|
|
16883
|
+
worker = null;
|
|
16884
|
+
fallbackTimer = null;
|
|
16885
|
+
interval = 3e4;
|
|
16886
|
+
onTick = null;
|
|
16887
|
+
isRunning = false;
|
|
16888
|
+
constructor() {
|
|
16889
|
+
this.worker = createHeartbeatWorker();
|
|
16890
|
+
if (this.worker) {
|
|
16891
|
+
this.worker.onmessage = (e) => {
|
|
16892
|
+
if (e.data.type === "tick" && this.onTick) {
|
|
16893
|
+
this.onTick();
|
|
16894
|
+
}
|
|
16895
|
+
};
|
|
16896
|
+
}
|
|
16897
|
+
}
|
|
16898
|
+
/**
|
|
16899
|
+
* Start the heartbeat
|
|
16900
|
+
* @param interval - Interval in milliseconds
|
|
16901
|
+
* @param onTick - Callback function to execute on each tick
|
|
16902
|
+
*/
|
|
16903
|
+
start(interval, onTick) {
|
|
16904
|
+
this.stop();
|
|
16905
|
+
this.interval = interval;
|
|
16906
|
+
this.onTick = onTick;
|
|
16907
|
+
this.isRunning = true;
|
|
16908
|
+
if (this.worker) {
|
|
16909
|
+
this.worker.postMessage({
|
|
16910
|
+
type: "start",
|
|
16911
|
+
interval
|
|
16912
|
+
});
|
|
16913
|
+
} else {
|
|
16914
|
+
this.fallbackTimer = setInterval(() => {
|
|
16915
|
+
if (this.onTick) {
|
|
16916
|
+
this.onTick();
|
|
16917
|
+
}
|
|
16918
|
+
}, interval);
|
|
16919
|
+
}
|
|
16920
|
+
}
|
|
16921
|
+
/**
|
|
16922
|
+
* Stop the heartbeat
|
|
16923
|
+
*/
|
|
16924
|
+
stop() {
|
|
16925
|
+
this.isRunning = false;
|
|
16926
|
+
this.onTick = null;
|
|
16927
|
+
if (this.worker) {
|
|
16928
|
+
this.worker.postMessage({ type: "stop" });
|
|
16929
|
+
}
|
|
16930
|
+
if (this.fallbackTimer) {
|
|
16931
|
+
clearInterval(this.fallbackTimer);
|
|
16932
|
+
this.fallbackTimer = null;
|
|
16933
|
+
}
|
|
16934
|
+
}
|
|
16935
|
+
/**
|
|
16936
|
+
* Update the heartbeat interval
|
|
16937
|
+
* @param interval - New interval in milliseconds
|
|
16938
|
+
*/
|
|
16939
|
+
updateInterval(interval) {
|
|
16940
|
+
this.interval = interval;
|
|
16941
|
+
if (!this.isRunning)
|
|
16942
|
+
return;
|
|
16943
|
+
if (this.worker) {
|
|
16944
|
+
this.worker.postMessage({
|
|
16945
|
+
type: "updateInterval",
|
|
16946
|
+
interval
|
|
16947
|
+
});
|
|
16948
|
+
} else if (this.fallbackTimer && this.onTick) {
|
|
16949
|
+
clearInterval(this.fallbackTimer);
|
|
16950
|
+
this.fallbackTimer = setInterval(() => {
|
|
16951
|
+
if (this.onTick) {
|
|
16952
|
+
this.onTick();
|
|
16953
|
+
}
|
|
16954
|
+
}, interval);
|
|
16955
|
+
}
|
|
16956
|
+
}
|
|
16957
|
+
/**
|
|
16958
|
+
* Destroy the heartbeat manager and release resources
|
|
16959
|
+
*/
|
|
16960
|
+
destroy() {
|
|
16961
|
+
this.stop();
|
|
16962
|
+
if (this.worker) {
|
|
16963
|
+
this.worker.terminate();
|
|
16964
|
+
this.worker = null;
|
|
16965
|
+
}
|
|
16966
|
+
}
|
|
16967
|
+
/**
|
|
16968
|
+
* Check if using Web Worker
|
|
16969
|
+
*/
|
|
16970
|
+
isUsingWorker() {
|
|
16971
|
+
return this.worker !== null;
|
|
16972
|
+
}
|
|
16711
16973
|
};
|
|
16712
16974
|
|
|
16713
16975
|
// core/socket.ts
|
|
@@ -16715,7 +16977,7 @@ var Socket = class {
|
|
|
16715
16977
|
callKit;
|
|
16716
16978
|
ws;
|
|
16717
16979
|
lastPingTime = void 0;
|
|
16718
|
-
|
|
16980
|
+
heartbeatManager;
|
|
16719
16981
|
/**
|
|
16720
16982
|
* @description reconnect timer
|
|
16721
16983
|
*/
|
|
@@ -16748,9 +17010,32 @@ var Socket = class {
|
|
|
16748
17010
|
}
|
|
16749
17011
|
constructor(callKit) {
|
|
16750
17012
|
this.callKit = callKit;
|
|
17013
|
+
this.heartbeatManager = new HeartbeatManager();
|
|
17014
|
+
}
|
|
17015
|
+
get isUserSetPingTryCount() {
|
|
17016
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
17017
|
+
const { pingTryCount } = userInfo;
|
|
17018
|
+
return Number.isInteger(pingTryCount) && pingTryCount > 0;
|
|
16751
17019
|
}
|
|
16752
17020
|
get reconnectConfig() {
|
|
16753
|
-
|
|
17021
|
+
const incallConfig = this.callKit.config.getReconnectConfig("incall");
|
|
17022
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
17023
|
+
const { pingTryCount, pingTryCountInterval } = userInfo;
|
|
17024
|
+
if (pingTryCount > 0) {
|
|
17025
|
+
return {
|
|
17026
|
+
...incallConfig,
|
|
17027
|
+
maxAttempts: pingTryCount,
|
|
17028
|
+
interval: pingTryCountInterval * 1e3
|
|
17029
|
+
};
|
|
17030
|
+
}
|
|
17031
|
+
return incallConfig;
|
|
17032
|
+
}
|
|
17033
|
+
get pingInterval() {
|
|
17034
|
+
const { keepaliveInterval } = this.callKit.config.getConfig().userInfo;
|
|
17035
|
+
if (Number.isInteger(keepaliveInterval) && keepaliveInterval > 0) {
|
|
17036
|
+
return keepaliveInterval * 1e3;
|
|
17037
|
+
}
|
|
17038
|
+
return this.reconnectConfig.pingInterval;
|
|
16754
17039
|
}
|
|
16755
17040
|
isConnected() {
|
|
16756
17041
|
return this.connectAuthState.isConnected;
|
|
@@ -16775,7 +17060,17 @@ var Socket = class {
|
|
|
16775
17060
|
this.setConnectAuthState("isConnected", false);
|
|
16776
17061
|
const { enabled } = this.reconnectConfig;
|
|
16777
17062
|
if (!this.callKit.config.isLogin() || !enabled) {
|
|
16778
|
-
this.callKit.
|
|
17063
|
+
if (this.callKit.connect.isCalling()) {
|
|
17064
|
+
this.callKit.logger.warn("Disconnect during call, delay reset", {
|
|
17065
|
+
caller: "Socket.handleDisconnect",
|
|
17066
|
+
type: "INCALL",
|
|
17067
|
+
content: {
|
|
17068
|
+
connectStatus: this.callKit.connect.connectStatus
|
|
17069
|
+
}
|
|
17070
|
+
});
|
|
17071
|
+
} else {
|
|
17072
|
+
this.callKit.reset();
|
|
17073
|
+
}
|
|
16779
17074
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
16780
17075
|
event: "INCALL_NOT_CONNECTED"
|
|
16781
17076
|
});
|
|
@@ -16933,6 +17228,28 @@ var Socket = class {
|
|
|
16933
17228
|
this.setConnectAuthState("startConfirm", true);
|
|
16934
17229
|
this.cleanReconnectState();
|
|
16935
17230
|
}
|
|
17231
|
+
if (data.event === SocketReceiveEvent.AGENT_RTP_LOSS) {
|
|
17232
|
+
this.callKit.logger.warn("Agent RTP loss", {
|
|
17233
|
+
caller: "Socket.onMessage",
|
|
17234
|
+
type: "INCALL",
|
|
17235
|
+
content: {
|
|
17236
|
+
data: {
|
|
17237
|
+
callUuid,
|
|
17238
|
+
...content
|
|
17239
|
+
},
|
|
17240
|
+
event: SocketReceiveEvent.AGENT_RTP_LOSS
|
|
17241
|
+
}
|
|
17242
|
+
});
|
|
17243
|
+
if (callUuid) {
|
|
17244
|
+
this.callKit.connect.referInCallToSelf(callUuid).catch((err) => {
|
|
17245
|
+
this.callKit.logger.error(err, {
|
|
17246
|
+
caller: "Socket.onMessage:AGENT_RTP_LOSS",
|
|
17247
|
+
type: "INCALL",
|
|
17248
|
+
content: { callUuid, event: SocketReceiveEvent.AGENT_RTP_LOSS }
|
|
17249
|
+
});
|
|
17250
|
+
});
|
|
17251
|
+
}
|
|
17252
|
+
}
|
|
16936
17253
|
if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {
|
|
16937
17254
|
this.callKit.trigger(KitEvent.CALL_RINGING, {
|
|
16938
17255
|
time: /* @__PURE__ */ new Date(),
|
|
@@ -16981,6 +17298,18 @@ var Socket = class {
|
|
|
16981
17298
|
this.send(SocketSendEvent.END, { agentId: userInfo.agentId, callUuid });
|
|
16982
17299
|
}
|
|
16983
17300
|
if (data.event === SocketReceiveEvent.ERROR) {
|
|
17301
|
+
if (this.callKit.connect.isCalling()) {
|
|
17302
|
+
this.callKit.logger.warn("socket onMessage error during call, ignore", {
|
|
17303
|
+
caller: "Socket.onMessage",
|
|
17304
|
+
type: "INCALL",
|
|
17305
|
+
content: {
|
|
17306
|
+
errCode: ErrorCode.SOCKET_CONNECT_ERROR,
|
|
17307
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
17308
|
+
data: content
|
|
17309
|
+
}
|
|
17310
|
+
});
|
|
17311
|
+
return;
|
|
17312
|
+
}
|
|
16984
17313
|
this.setConnectAuthState("isError", true);
|
|
16985
17314
|
this.callKit.reset();
|
|
16986
17315
|
this.callKit.logger.error(data.msg, {
|
|
@@ -16989,20 +17318,24 @@ var Socket = class {
|
|
|
16989
17318
|
content: {
|
|
16990
17319
|
errCode: ErrorCode.SOKET_SERVER_ERROR,
|
|
16991
17320
|
data: content,
|
|
16992
|
-
callUuid
|
|
17321
|
+
callUuid,
|
|
17322
|
+
delayReset: this.callKit.connect.isCalling()
|
|
16993
17323
|
}
|
|
16994
17324
|
});
|
|
16995
17325
|
}
|
|
16996
17326
|
if (data.event === SocketReceiveEvent.SESSION_ERROR) {
|
|
16997
17327
|
this.setConnectAuthState("isError", true);
|
|
16998
|
-
this.callKit.
|
|
17328
|
+
if (!this.callKit.connect.isCalling()) {
|
|
17329
|
+
this.callKit.reset();
|
|
17330
|
+
}
|
|
16999
17331
|
this.callKit.logger.error(data.msg, {
|
|
17000
17332
|
caller: `Socket.onMessage:${data.event}`,
|
|
17001
17333
|
type: "INCALL",
|
|
17002
17334
|
content: {
|
|
17003
17335
|
data: content,
|
|
17004
17336
|
event: SocketReceiveEvent.SESSION_ERROR,
|
|
17005
|
-
callUuid
|
|
17337
|
+
callUuid,
|
|
17338
|
+
delayReset: this.callKit.connect.isCalling()
|
|
17006
17339
|
}
|
|
17007
17340
|
});
|
|
17008
17341
|
}
|
|
@@ -17034,6 +17367,18 @@ var Socket = class {
|
|
|
17034
17367
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17035
17368
|
event: "INCALL_NOT_CONNECTED"
|
|
17036
17369
|
});
|
|
17370
|
+
if (this.callKit.connect.isCalling()) {
|
|
17371
|
+
this.callKit.logger.warn("socket send during call, ignore", {
|
|
17372
|
+
caller: "Socket.onMessage",
|
|
17373
|
+
type: "INCALL",
|
|
17374
|
+
content: {
|
|
17375
|
+
errCode: ErrorCode.SOCKET_CONNECT_ERROR,
|
|
17376
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
17377
|
+
data: message
|
|
17378
|
+
}
|
|
17379
|
+
});
|
|
17380
|
+
return;
|
|
17381
|
+
}
|
|
17037
17382
|
this.callKit.reset();
|
|
17038
17383
|
this.callKit.logger.error("socket not connected", {
|
|
17039
17384
|
caller: "Socket.send",
|
|
@@ -17086,8 +17431,8 @@ var Socket = class {
|
|
|
17086
17431
|
return;
|
|
17087
17432
|
this.send(SocketSendEvent.PING);
|
|
17088
17433
|
const now = Date.now();
|
|
17089
|
-
const {
|
|
17090
|
-
if (now - this.lastPingTime > pingInterval + pingTimeout) {
|
|
17434
|
+
const { pingTimeout } = this.reconnectConfig;
|
|
17435
|
+
if (now - this.lastPingTime > this.pingInterval + pingTimeout) {
|
|
17091
17436
|
this.callKit.logger.warn("Ping timeout not connected", {
|
|
17092
17437
|
caller: "Socket.ping",
|
|
17093
17438
|
type: "INCALL",
|
|
@@ -17099,26 +17444,48 @@ var Socket = class {
|
|
|
17099
17444
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17100
17445
|
event: "INCALL_PING_TIMEOUT"
|
|
17101
17446
|
});
|
|
17447
|
+
if (this.isUserSetPingTryCount) {
|
|
17448
|
+
this.handlePingTimeout();
|
|
17449
|
+
}
|
|
17102
17450
|
}
|
|
17103
17451
|
}
|
|
17452
|
+
handlePingTimeout() {
|
|
17453
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
17454
|
+
const { pingTryCount, pingTryCountInterval } = userInfo;
|
|
17455
|
+
this.callKit.logger.warn("Ping timeout, user set ping try count", {
|
|
17456
|
+
caller: "Socket.handlePingTimeout",
|
|
17457
|
+
type: "INCALL",
|
|
17458
|
+
content: {
|
|
17459
|
+
errCode: ErrorCode.SOCKET_PING_TIMEOUT,
|
|
17460
|
+
isUserSetPingTryCount: this.isUserSetPingTryCount,
|
|
17461
|
+
pingTryCount,
|
|
17462
|
+
pingTryCountInterval
|
|
17463
|
+
}
|
|
17464
|
+
});
|
|
17465
|
+
this.attemptReconnect();
|
|
17466
|
+
}
|
|
17104
17467
|
checkPing() {
|
|
17105
|
-
|
|
17106
|
-
clearInterval(this.pingTimer);
|
|
17107
|
-
}
|
|
17108
|
-
const { pingInterval } = this.reconnectConfig;
|
|
17109
|
-
this.pingTimer = setInterval(() => {
|
|
17468
|
+
this.heartbeatManager.start(this.pingInterval, () => {
|
|
17110
17469
|
this.ping();
|
|
17111
|
-
}
|
|
17470
|
+
});
|
|
17471
|
+
this.callKit.logger.info(
|
|
17472
|
+
`Heartbeat started with Worker: ${this.heartbeatManager.isUsingWorker()}`,
|
|
17473
|
+
{
|
|
17474
|
+
caller: "Socket.checkPing",
|
|
17475
|
+
type: "INCALL",
|
|
17476
|
+
content: {
|
|
17477
|
+
pingInterval: this.pingInterval,
|
|
17478
|
+
usingWorker: this.heartbeatManager.isUsingWorker()
|
|
17479
|
+
}
|
|
17480
|
+
}
|
|
17481
|
+
);
|
|
17112
17482
|
}
|
|
17113
17483
|
/**
|
|
17114
17484
|
* reset socket connection and all states
|
|
17115
17485
|
*/
|
|
17116
17486
|
async reset(config) {
|
|
17117
17487
|
const { force = false } = config || {};
|
|
17118
|
-
|
|
17119
|
-
clearInterval(this.pingTimer);
|
|
17120
|
-
this.pingTimer = void 0;
|
|
17121
|
-
}
|
|
17488
|
+
this.heartbeatManager.stop();
|
|
17122
17489
|
if (force) {
|
|
17123
17490
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17124
17491
|
event: "INCALL_RESET"
|
|
@@ -17129,6 +17496,12 @@ var Socket = class {
|
|
|
17129
17496
|
this.setConnectAuthState("startConfirm", false);
|
|
17130
17497
|
this.clearWebSocket();
|
|
17131
17498
|
}
|
|
17499
|
+
/**
|
|
17500
|
+
* Destroy the heartbeat manager
|
|
17501
|
+
*/
|
|
17502
|
+
destroyHeartbeat() {
|
|
17503
|
+
this.heartbeatManager.destroy();
|
|
17504
|
+
}
|
|
17132
17505
|
attemptReconnect() {
|
|
17133
17506
|
if (this.reconnectTimer) {
|
|
17134
17507
|
clearTimeout(this.reconnectTimer);
|
|
@@ -17136,19 +17509,40 @@ var Socket = class {
|
|
|
17136
17509
|
}
|
|
17137
17510
|
const { maxAttempts } = this.reconnectConfig;
|
|
17138
17511
|
if (this.reconnectAttempts >= maxAttempts) {
|
|
17512
|
+
if (this.callKit.connect.isCalling()) {
|
|
17513
|
+
this.callKit.logger.warn("reconnect during call, ignore", {
|
|
17514
|
+
caller: "Socket.attemptReconnect",
|
|
17515
|
+
type: "INCALL",
|
|
17516
|
+
content: {
|
|
17517
|
+
errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
|
|
17518
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
17519
|
+
reconnectAttempts: this.reconnectAttempts
|
|
17520
|
+
}
|
|
17521
|
+
});
|
|
17522
|
+
return;
|
|
17523
|
+
}
|
|
17524
|
+
if (this.isUserSetPingTryCount) {
|
|
17525
|
+
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17526
|
+
event: "INCALL_PING_TIMEOUT_RECONNECT_FAILED_MAX_ATTEMPTS"
|
|
17527
|
+
});
|
|
17528
|
+
}
|
|
17139
17529
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17140
17530
|
event: "INCALL_RECONNECT_ERROR"
|
|
17141
17531
|
});
|
|
17142
17532
|
this.setConnectAuthState("isError", true);
|
|
17143
17533
|
this.callKit.reset();
|
|
17144
|
-
this.callKit.logger.
|
|
17145
|
-
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
|
|
17149
|
-
|
|
17534
|
+
this.callKit.logger.warn(
|
|
17535
|
+
"Maximum reconnection attempts reached, trigger reset",
|
|
17536
|
+
{
|
|
17537
|
+
caller: "Socket.attemptReconnect",
|
|
17538
|
+
type: "INCALL",
|
|
17539
|
+
content: {
|
|
17540
|
+
errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
|
|
17541
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
17542
|
+
delayReset: this.callKit.connect.isCalling()
|
|
17543
|
+
}
|
|
17150
17544
|
}
|
|
17151
|
-
|
|
17545
|
+
);
|
|
17152
17546
|
return;
|
|
17153
17547
|
}
|
|
17154
17548
|
if (this.reconnectAttempts === 0) {
|
|
@@ -17254,6 +17648,7 @@ var CallKit = class {
|
|
|
17254
17648
|
content: {
|
|
17255
17649
|
username,
|
|
17256
17650
|
password,
|
|
17651
|
+
ua: navigator.userAgent,
|
|
17257
17652
|
encryptionMethod,
|
|
17258
17653
|
encryptionPassword
|
|
17259
17654
|
}
|
|
@@ -17273,6 +17668,7 @@ var CallKit = class {
|
|
|
17273
17668
|
});
|
|
17274
17669
|
if (user) {
|
|
17275
17670
|
this.config.setConfig("userInfo", {
|
|
17671
|
+
...user,
|
|
17276
17672
|
wsUrl: `wss://${user.wsUrl}`,
|
|
17277
17673
|
sessionId: user.sessionId,
|
|
17278
17674
|
username,
|
|
@@ -17287,6 +17683,9 @@ var CallKit = class {
|
|
|
17287
17683
|
iceInfo: user.iceInfo,
|
|
17288
17684
|
iceGatheringTimeout: user.iceGatheringTimeout,
|
|
17289
17685
|
logGather: user.logGather,
|
|
17686
|
+
keepaliveInterval: user.keepaliveInterval,
|
|
17687
|
+
pingTryCount: user?.pingTryCount,
|
|
17688
|
+
pingTryCountInterval: user?.pingTryCountInterval,
|
|
17290
17689
|
phoneType: user.phoneType,
|
|
17291
17690
|
// encryptionType is in extra
|
|
17292
17691
|
...extra
|
|
@@ -17565,4 +17964,3 @@ var CallKit = class {
|
|
|
17565
17964
|
0 && (module.exports = {
|
|
17566
17965
|
CallKit
|
|
17567
17966
|
});
|
|
17568
|
-
//# sourceMappingURL=index.js.map
|