@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.mjs
CHANGED
|
@@ -45,7 +45,7 @@ var Api = class {
|
|
|
45
45
|
const res = await this.post({
|
|
46
46
|
url: "/auth/agentUser/login",
|
|
47
47
|
method: "post",
|
|
48
|
-
data: params
|
|
48
|
+
data: { ...params, browserVersion: navigator.userAgent }
|
|
49
49
|
});
|
|
50
50
|
return res;
|
|
51
51
|
} finally {
|
|
@@ -508,7 +508,11 @@ var SocketReceiveEvent = {
|
|
|
508
508
|
ERROR: "ERROR",
|
|
509
509
|
SESSION_ERROR: "SESSION_ERROR",
|
|
510
510
|
WAITING_QUEUE: "WAITING_QUEUE",
|
|
511
|
-
CUSTOMER_MATCH_BLACK_PHONE: "CUSTOMER_MATCH_BLACK_PHONE"
|
|
511
|
+
CUSTOMER_MATCH_BLACK_PHONE: "CUSTOMER_MATCH_BLACK_PHONE",
|
|
512
|
+
/**
|
|
513
|
+
* Agent RTP loss
|
|
514
|
+
*/
|
|
515
|
+
AGENT_RTP_LOSS: "AGENT_RTP_LOSS"
|
|
512
516
|
};
|
|
513
517
|
var EncryptionMethod = {
|
|
514
518
|
NONE: "NONE",
|
|
@@ -553,7 +557,9 @@ var SIP_RECONNECT_CONFIG = {
|
|
|
553
557
|
delay: 1e3,
|
|
554
558
|
registererOptions: {
|
|
555
559
|
refreshFrequency: 90
|
|
556
|
-
}
|
|
560
|
+
},
|
|
561
|
+
enableMessageKeepalive: true,
|
|
562
|
+
messageKeepaliveInterval: 30
|
|
557
563
|
};
|
|
558
564
|
|
|
559
565
|
// core/call.ts
|
|
@@ -697,13 +703,13 @@ var Call = class {
|
|
|
697
703
|
// package.json
|
|
698
704
|
var package_default = {
|
|
699
705
|
name: "@koi-design/callkit",
|
|
700
|
-
version: "2.3.
|
|
706
|
+
version: "2.3.1-beta.2",
|
|
701
707
|
description: "callkit",
|
|
702
708
|
author: "koi",
|
|
703
709
|
license: "ISC",
|
|
704
710
|
scripts: {
|
|
705
711
|
build: "tsup",
|
|
706
|
-
start: "
|
|
712
|
+
start: "vite --host 0.0.0.0",
|
|
707
713
|
dev: "tsup --watch",
|
|
708
714
|
lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
|
|
709
715
|
release: "tsup && node scripts/pkg.js"
|
|
@@ -15538,7 +15544,15 @@ var Connect = class {
|
|
|
15538
15544
|
this.callKit = callKit;
|
|
15539
15545
|
}
|
|
15540
15546
|
get reconnectConfig() {
|
|
15541
|
-
|
|
15547
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
15548
|
+
const { enableMessageKeepalive } = userInfo;
|
|
15549
|
+
const { messageKeepaliveInterval } = userInfo;
|
|
15550
|
+
const defaultConfig = this.callKit.config.getReconnectConfig("sip");
|
|
15551
|
+
if (enableMessageKeepalive) {
|
|
15552
|
+
defaultConfig.enableMessageKeepalive = enableMessageKeepalive;
|
|
15553
|
+
defaultConfig.messageKeepaliveInterval = messageKeepaliveInterval;
|
|
15554
|
+
}
|
|
15555
|
+
return defaultConfig;
|
|
15542
15556
|
}
|
|
15543
15557
|
// current call id for invite data
|
|
15544
15558
|
currentCallId = null;
|
|
@@ -15662,6 +15676,7 @@ var Connect = class {
|
|
|
15662
15676
|
}
|
|
15663
15677
|
}
|
|
15664
15678
|
this.setConnectStatus(CallStatus.init);
|
|
15679
|
+
this.stopMessageKeepalive();
|
|
15665
15680
|
}
|
|
15666
15681
|
getAduioReference() {
|
|
15667
15682
|
const { audioRef } = this.callKit.config.getConfig();
|
|
@@ -15797,8 +15812,6 @@ var Connect = class {
|
|
|
15797
15812
|
});
|
|
15798
15813
|
return;
|
|
15799
15814
|
}
|
|
15800
|
-
const { userInfo } = this.callKit.config.getConfig();
|
|
15801
|
-
const { userPart, fsIp, fsPort } = userInfo;
|
|
15802
15815
|
const { registererOptions = {} } = this.reconnectConfig;
|
|
15803
15816
|
this.registerer = new Registerer(this.userAgent, registererOptions);
|
|
15804
15817
|
this.registerer.stateChange.addListener((state) => {
|
|
@@ -15816,6 +15829,7 @@ var Connect = class {
|
|
|
15816
15829
|
if (!this.isInCallRefering()) {
|
|
15817
15830
|
this.setConnectStatus(CallStatus.init);
|
|
15818
15831
|
}
|
|
15832
|
+
this.stopMessageKeepalive();
|
|
15819
15833
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15820
15834
|
registererState: state,
|
|
15821
15835
|
isRegistered: this.isRegistered()
|
|
@@ -15832,27 +15846,26 @@ var Connect = class {
|
|
|
15832
15846
|
});
|
|
15833
15847
|
this.setRegister(true);
|
|
15834
15848
|
if (this.isReConnected) {
|
|
15835
|
-
if (this.
|
|
15836
|
-
const selfUri = `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
|
|
15849
|
+
if (this.canReferInCallToSelf()) {
|
|
15837
15850
|
this.callKit.logger.info(
|
|
15838
15851
|
"Reconnected, referring active session to self",
|
|
15839
15852
|
{
|
|
15840
15853
|
caller: "Connect.setupRegisterer.registererStateChange",
|
|
15841
15854
|
type: "SIP",
|
|
15842
15855
|
content: {
|
|
15843
|
-
selfUri,
|
|
15856
|
+
selfUri: this.getSelfReferUri(),
|
|
15844
15857
|
sessionState: this.currentSession.state,
|
|
15845
15858
|
connectStatus: this.connectStatus
|
|
15846
15859
|
}
|
|
15847
15860
|
}
|
|
15848
15861
|
);
|
|
15849
|
-
this.
|
|
15862
|
+
this.referInCallToSelf().catch((err) => {
|
|
15850
15863
|
this.callKit.logger.error(err, {
|
|
15851
15864
|
caller: "Connect.setupRegisterer.registererStateChange",
|
|
15852
15865
|
type: "SIP",
|
|
15853
15866
|
content: {
|
|
15854
15867
|
errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
|
|
15855
|
-
selfUri
|
|
15868
|
+
selfUri: this.getSelfReferUri()
|
|
15856
15869
|
}
|
|
15857
15870
|
});
|
|
15858
15871
|
});
|
|
@@ -15873,6 +15886,7 @@ var Connect = class {
|
|
|
15873
15886
|
}
|
|
15874
15887
|
this.setIsReConnected(false);
|
|
15875
15888
|
}
|
|
15889
|
+
this.startMessageKeepalive();
|
|
15876
15890
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15877
15891
|
registererState: state,
|
|
15878
15892
|
isRegistered: this.isRegistered()
|
|
@@ -15892,6 +15906,7 @@ var Connect = class {
|
|
|
15892
15906
|
if (!this.isInCallRefering()) {
|
|
15893
15907
|
this.setConnectStatus(CallStatus.init);
|
|
15894
15908
|
}
|
|
15909
|
+
this.stopMessageKeepalive();
|
|
15895
15910
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15896
15911
|
registererState: state,
|
|
15897
15912
|
isRegistered: this.isRegistered(),
|
|
@@ -15912,6 +15927,7 @@ var Connect = class {
|
|
|
15912
15927
|
if (!this.isInCallRefering()) {
|
|
15913
15928
|
this.setConnectStatus(CallStatus.init);
|
|
15914
15929
|
}
|
|
15930
|
+
this.stopMessageKeepalive();
|
|
15915
15931
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
15916
15932
|
registererState: state,
|
|
15917
15933
|
isRegistered: this.isRegistered(),
|
|
@@ -15958,7 +15974,7 @@ var Connect = class {
|
|
|
15958
15974
|
this.mediaStream = await navigator.mediaDevices.getUserMedia(constrains);
|
|
15959
15975
|
return this.mediaStream;
|
|
15960
15976
|
};
|
|
15961
|
-
const { userPart, fsIp, fsPort, iceInfo, wsUrl } = userInfo;
|
|
15977
|
+
const { userPart, fsIp, fsPort, fsPassword, iceInfo, wsUrl } = userInfo;
|
|
15962
15978
|
const connectConfig = {
|
|
15963
15979
|
uri: UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`),
|
|
15964
15980
|
displayName: userPart,
|
|
@@ -15967,6 +15983,8 @@ var Connect = class {
|
|
|
15967
15983
|
traceSip: true
|
|
15968
15984
|
},
|
|
15969
15985
|
logLevel: "error",
|
|
15986
|
+
authorizationUsername: userPart,
|
|
15987
|
+
authorizationPassword: fsPassword,
|
|
15970
15988
|
allowLegacyNotifications: true,
|
|
15971
15989
|
contactName: userPart,
|
|
15972
15990
|
contactParams: { transport: "wss" },
|
|
@@ -16222,7 +16240,10 @@ var Connect = class {
|
|
|
16222
16240
|
}
|
|
16223
16241
|
});
|
|
16224
16242
|
this.setupRegisterer();
|
|
16225
|
-
|
|
16243
|
+
try {
|
|
16244
|
+
await this.registerer.register();
|
|
16245
|
+
this.startMessageKeepalive();
|
|
16246
|
+
} catch (err) {
|
|
16226
16247
|
this.callKit.reset();
|
|
16227
16248
|
this.callKit.logger.error(err?.message, {
|
|
16228
16249
|
caller: "Connect.register",
|
|
@@ -16231,9 +16252,10 @@ var Connect = class {
|
|
|
16231
16252
|
errCode: ErrorCode.WEBRTC_REGISTER_ERROR
|
|
16232
16253
|
}
|
|
16233
16254
|
});
|
|
16234
|
-
}
|
|
16255
|
+
}
|
|
16235
16256
|
},
|
|
16236
16257
|
onDisconnect: (error) => {
|
|
16258
|
+
this.stopMessageKeepalive();
|
|
16237
16259
|
if (error) {
|
|
16238
16260
|
this.callKit.logger.warn("SIP User Agent Disconnected with error", {
|
|
16239
16261
|
caller: "Connect.register",
|
|
@@ -16269,6 +16291,7 @@ var Connect = class {
|
|
|
16269
16291
|
}
|
|
16270
16292
|
reconnectTimer;
|
|
16271
16293
|
reconnectAttempts = 0;
|
|
16294
|
+
messageKeepaliveTimer;
|
|
16272
16295
|
startReconnectTimer() {
|
|
16273
16296
|
if (this._isError || this.isReConnected)
|
|
16274
16297
|
return;
|
|
@@ -16322,8 +16345,53 @@ var Connect = class {
|
|
|
16322
16345
|
}
|
|
16323
16346
|
}, this.reconnectConfig.delay);
|
|
16324
16347
|
}
|
|
16348
|
+
stopMessageKeepalive() {
|
|
16349
|
+
if (this.messageKeepaliveTimer) {
|
|
16350
|
+
clearInterval(this.messageKeepaliveTimer);
|
|
16351
|
+
this.messageKeepaliveTimer = void 0;
|
|
16352
|
+
}
|
|
16353
|
+
}
|
|
16354
|
+
startMessageKeepalive() {
|
|
16355
|
+
const { enableMessageKeepalive, messageKeepaliveInterval } = this.reconnectConfig;
|
|
16356
|
+
if (!enableMessageKeepalive)
|
|
16357
|
+
return;
|
|
16358
|
+
this.stopMessageKeepalive();
|
|
16359
|
+
this.messageKeepaliveTimer = setInterval(() => {
|
|
16360
|
+
this.sendKeepaliveMessage();
|
|
16361
|
+
}, messageKeepaliveInterval * 1e3);
|
|
16362
|
+
}
|
|
16363
|
+
async sendKeepaliveMessage() {
|
|
16364
|
+
try {
|
|
16365
|
+
if (!this.isRegistered() || !this.userAgent)
|
|
16366
|
+
return;
|
|
16367
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
16368
|
+
const { userPart, fsIp, fsPort } = userInfo || {};
|
|
16369
|
+
const target = UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`);
|
|
16370
|
+
if (!target)
|
|
16371
|
+
return;
|
|
16372
|
+
const messager = new Messager(this.userAgent, target, "");
|
|
16373
|
+
await messager.message();
|
|
16374
|
+
this.callKit.logger.info("MESSAGE keepalive ok", {
|
|
16375
|
+
caller: "Connect.sendKeepaliveMessage",
|
|
16376
|
+
type: "SIP",
|
|
16377
|
+
content: {}
|
|
16378
|
+
});
|
|
16379
|
+
} catch (err) {
|
|
16380
|
+
this.callKit.logger.error(err, {
|
|
16381
|
+
caller: "Connect.sendKeepaliveMessage",
|
|
16382
|
+
type: "SIP",
|
|
16383
|
+
content: {}
|
|
16384
|
+
});
|
|
16385
|
+
this.stopMessageKeepalive();
|
|
16386
|
+
this.callKit.trigger(KitEvent.SIP_CONNECT_EVENT, {
|
|
16387
|
+
event: "MESSAGE_KEEPALIVE_FAILED"
|
|
16388
|
+
});
|
|
16389
|
+
this.startReconnectTimer();
|
|
16390
|
+
}
|
|
16391
|
+
}
|
|
16325
16392
|
async stop() {
|
|
16326
16393
|
await this.userAgent.stop();
|
|
16394
|
+
this.stopMessageKeepalive();
|
|
16327
16395
|
}
|
|
16328
16396
|
async unregister() {
|
|
16329
16397
|
this.callKit.logger.info("connect unregister", {
|
|
@@ -16333,6 +16401,7 @@ var Connect = class {
|
|
|
16333
16401
|
isRegistered: this.isRegistered()
|
|
16334
16402
|
}
|
|
16335
16403
|
});
|
|
16404
|
+
this.stopMessageKeepalive();
|
|
16336
16405
|
if (!this.isRegistered() || !this.registerer) {
|
|
16337
16406
|
this.callKit.logger.warn("No registerer to unregister.", {
|
|
16338
16407
|
caller: "Connect.unregister",
|
|
@@ -16681,6 +16750,199 @@ var Connect = class {
|
|
|
16681
16750
|
}
|
|
16682
16751
|
this.currentSession.refer(target, extra?.sessionReferOptions);
|
|
16683
16752
|
}
|
|
16753
|
+
/**
|
|
16754
|
+
* Get the SIP URI for "refer to self" (same as reconnection refer logic).
|
|
16755
|
+
* Shared by referInCallToSelf and internal reconnection refer.
|
|
16756
|
+
*/
|
|
16757
|
+
getSelfReferUri() {
|
|
16758
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
16759
|
+
const { userPart, fsIp, fsPort } = userInfo;
|
|
16760
|
+
return `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
|
|
16761
|
+
}
|
|
16762
|
+
/**
|
|
16763
|
+
* Whether we can refer the current call to self (has active session in Established/Establishing and is calling).
|
|
16764
|
+
* Shared by reconnection logic and referInCallToSelf.
|
|
16765
|
+
*/
|
|
16766
|
+
canReferInCallToSelf() {
|
|
16767
|
+
return !!this.currentSession && (this.currentSession.state === SessionState2.Established || this.currentSession.state === SessionState2.Establishing) && this.isCalling();
|
|
16768
|
+
}
|
|
16769
|
+
/**
|
|
16770
|
+
* Refer the current call to self (e.g. Agent RTP loss recovery, post-reconnect recovery).
|
|
16771
|
+
* Socket and other callers can use this without constructing referTo.
|
|
16772
|
+
*/
|
|
16773
|
+
async referInCallToSelf(callUuid, extra) {
|
|
16774
|
+
if (callUuid && this.currentCallId !== callUuid) {
|
|
16775
|
+
this.callKit.logger.warn(
|
|
16776
|
+
"Cannot refer in call to self: callUuid mismatch",
|
|
16777
|
+
{
|
|
16778
|
+
caller: "Connect.referInCallToSelf",
|
|
16779
|
+
type: "SIP",
|
|
16780
|
+
content: {
|
|
16781
|
+
currentCallId: this.currentCallId,
|
|
16782
|
+
callUuid
|
|
16783
|
+
}
|
|
16784
|
+
}
|
|
16785
|
+
);
|
|
16786
|
+
return;
|
|
16787
|
+
}
|
|
16788
|
+
if (!this.canReferInCallToSelf()) {
|
|
16789
|
+
this.callKit.logger.warn(
|
|
16790
|
+
"Cannot refer in call to self: preconditions not met",
|
|
16791
|
+
{
|
|
16792
|
+
caller: "Connect.referInCallToSelf",
|
|
16793
|
+
type: "SIP",
|
|
16794
|
+
content: {
|
|
16795
|
+
hasCurrentSession: !!this.currentSession,
|
|
16796
|
+
sessionState: this.currentSession?.state,
|
|
16797
|
+
isCalling: this.isCalling()
|
|
16798
|
+
}
|
|
16799
|
+
}
|
|
16800
|
+
);
|
|
16801
|
+
return;
|
|
16802
|
+
}
|
|
16803
|
+
const selfUri = this.getSelfReferUri();
|
|
16804
|
+
return this.referInCall(selfUri, extra);
|
|
16805
|
+
}
|
|
16806
|
+
};
|
|
16807
|
+
|
|
16808
|
+
// core/heartbeat-worker.ts
|
|
16809
|
+
var workerCode = `
|
|
16810
|
+
let timer = null;
|
|
16811
|
+
let interval = 30000;
|
|
16812
|
+
|
|
16813
|
+
self.onmessage = function(e) {
|
|
16814
|
+
const { type, interval: newInterval } = e.data;
|
|
16815
|
+
|
|
16816
|
+
if (type === 'start') {
|
|
16817
|
+
if (timer) {
|
|
16818
|
+
clearInterval(timer);
|
|
16819
|
+
}
|
|
16820
|
+
interval = newInterval || interval;
|
|
16821
|
+
timer = setInterval(() => {
|
|
16822
|
+
self.postMessage({ type: 'tick' });
|
|
16823
|
+
}, interval);
|
|
16824
|
+
}
|
|
16825
|
+
|
|
16826
|
+
if (type === 'stop') {
|
|
16827
|
+
if (timer) {
|
|
16828
|
+
clearInterval(timer);
|
|
16829
|
+
timer = null;
|
|
16830
|
+
}
|
|
16831
|
+
}
|
|
16832
|
+
|
|
16833
|
+
if (type === 'updateInterval') {
|
|
16834
|
+
interval = newInterval;
|
|
16835
|
+
if (timer) {
|
|
16836
|
+
clearInterval(timer);
|
|
16837
|
+
timer = setInterval(() => {
|
|
16838
|
+
self.postMessage({ type: 'tick' });
|
|
16839
|
+
}, interval);
|
|
16840
|
+
}
|
|
16841
|
+
}
|
|
16842
|
+
};
|
|
16843
|
+
`;
|
|
16844
|
+
function createHeartbeatWorker() {
|
|
16845
|
+
try {
|
|
16846
|
+
const blob = new Blob([workerCode], { type: "application/javascript" });
|
|
16847
|
+
const workerUrl = URL.createObjectURL(blob);
|
|
16848
|
+
const worker = new Worker(workerUrl);
|
|
16849
|
+
URL.revokeObjectURL(workerUrl);
|
|
16850
|
+
return worker;
|
|
16851
|
+
} catch {
|
|
16852
|
+
return null;
|
|
16853
|
+
}
|
|
16854
|
+
}
|
|
16855
|
+
var HeartbeatManager = class {
|
|
16856
|
+
worker = null;
|
|
16857
|
+
fallbackTimer = null;
|
|
16858
|
+
interval = 3e4;
|
|
16859
|
+
onTick = null;
|
|
16860
|
+
isRunning = false;
|
|
16861
|
+
constructor() {
|
|
16862
|
+
this.worker = createHeartbeatWorker();
|
|
16863
|
+
if (this.worker) {
|
|
16864
|
+
this.worker.onmessage = (e) => {
|
|
16865
|
+
if (e.data.type === "tick" && this.onTick) {
|
|
16866
|
+
this.onTick();
|
|
16867
|
+
}
|
|
16868
|
+
};
|
|
16869
|
+
}
|
|
16870
|
+
}
|
|
16871
|
+
/**
|
|
16872
|
+
* Start the heartbeat
|
|
16873
|
+
* @param interval - Interval in milliseconds
|
|
16874
|
+
* @param onTick - Callback function to execute on each tick
|
|
16875
|
+
*/
|
|
16876
|
+
start(interval, onTick) {
|
|
16877
|
+
this.stop();
|
|
16878
|
+
this.interval = interval;
|
|
16879
|
+
this.onTick = onTick;
|
|
16880
|
+
this.isRunning = true;
|
|
16881
|
+
if (this.worker) {
|
|
16882
|
+
this.worker.postMessage({
|
|
16883
|
+
type: "start",
|
|
16884
|
+
interval
|
|
16885
|
+
});
|
|
16886
|
+
} else {
|
|
16887
|
+
this.fallbackTimer = setInterval(() => {
|
|
16888
|
+
if (this.onTick) {
|
|
16889
|
+
this.onTick();
|
|
16890
|
+
}
|
|
16891
|
+
}, interval);
|
|
16892
|
+
}
|
|
16893
|
+
}
|
|
16894
|
+
/**
|
|
16895
|
+
* Stop the heartbeat
|
|
16896
|
+
*/
|
|
16897
|
+
stop() {
|
|
16898
|
+
this.isRunning = false;
|
|
16899
|
+
this.onTick = null;
|
|
16900
|
+
if (this.worker) {
|
|
16901
|
+
this.worker.postMessage({ type: "stop" });
|
|
16902
|
+
}
|
|
16903
|
+
if (this.fallbackTimer) {
|
|
16904
|
+
clearInterval(this.fallbackTimer);
|
|
16905
|
+
this.fallbackTimer = null;
|
|
16906
|
+
}
|
|
16907
|
+
}
|
|
16908
|
+
/**
|
|
16909
|
+
* Update the heartbeat interval
|
|
16910
|
+
* @param interval - New interval in milliseconds
|
|
16911
|
+
*/
|
|
16912
|
+
updateInterval(interval) {
|
|
16913
|
+
this.interval = interval;
|
|
16914
|
+
if (!this.isRunning)
|
|
16915
|
+
return;
|
|
16916
|
+
if (this.worker) {
|
|
16917
|
+
this.worker.postMessage({
|
|
16918
|
+
type: "updateInterval",
|
|
16919
|
+
interval
|
|
16920
|
+
});
|
|
16921
|
+
} else if (this.fallbackTimer && this.onTick) {
|
|
16922
|
+
clearInterval(this.fallbackTimer);
|
|
16923
|
+
this.fallbackTimer = setInterval(() => {
|
|
16924
|
+
if (this.onTick) {
|
|
16925
|
+
this.onTick();
|
|
16926
|
+
}
|
|
16927
|
+
}, interval);
|
|
16928
|
+
}
|
|
16929
|
+
}
|
|
16930
|
+
/**
|
|
16931
|
+
* Destroy the heartbeat manager and release resources
|
|
16932
|
+
*/
|
|
16933
|
+
destroy() {
|
|
16934
|
+
this.stop();
|
|
16935
|
+
if (this.worker) {
|
|
16936
|
+
this.worker.terminate();
|
|
16937
|
+
this.worker = null;
|
|
16938
|
+
}
|
|
16939
|
+
}
|
|
16940
|
+
/**
|
|
16941
|
+
* Check if using Web Worker
|
|
16942
|
+
*/
|
|
16943
|
+
isUsingWorker() {
|
|
16944
|
+
return this.worker !== null;
|
|
16945
|
+
}
|
|
16684
16946
|
};
|
|
16685
16947
|
|
|
16686
16948
|
// core/socket.ts
|
|
@@ -16688,7 +16950,7 @@ var Socket = class {
|
|
|
16688
16950
|
callKit;
|
|
16689
16951
|
ws;
|
|
16690
16952
|
lastPingTime = void 0;
|
|
16691
|
-
|
|
16953
|
+
heartbeatManager;
|
|
16692
16954
|
/**
|
|
16693
16955
|
* @description reconnect timer
|
|
16694
16956
|
*/
|
|
@@ -16721,9 +16983,32 @@ var Socket = class {
|
|
|
16721
16983
|
}
|
|
16722
16984
|
constructor(callKit) {
|
|
16723
16985
|
this.callKit = callKit;
|
|
16986
|
+
this.heartbeatManager = new HeartbeatManager();
|
|
16987
|
+
}
|
|
16988
|
+
get isUserSetPingTryCount() {
|
|
16989
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
16990
|
+
const { pingTryCount } = userInfo;
|
|
16991
|
+
return Number.isInteger(pingTryCount) && pingTryCount > 0;
|
|
16724
16992
|
}
|
|
16725
16993
|
get reconnectConfig() {
|
|
16726
|
-
|
|
16994
|
+
const incallConfig = this.callKit.config.getReconnectConfig("incall");
|
|
16995
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
16996
|
+
const { pingTryCount, pingTryCountInterval } = userInfo;
|
|
16997
|
+
if (pingTryCount > 0) {
|
|
16998
|
+
return {
|
|
16999
|
+
...incallConfig,
|
|
17000
|
+
maxAttempts: pingTryCount,
|
|
17001
|
+
interval: pingTryCountInterval * 1e3
|
|
17002
|
+
};
|
|
17003
|
+
}
|
|
17004
|
+
return incallConfig;
|
|
17005
|
+
}
|
|
17006
|
+
get pingInterval() {
|
|
17007
|
+
const { keepaliveInterval } = this.callKit.config.getConfig().userInfo;
|
|
17008
|
+
if (Number.isInteger(keepaliveInterval) && keepaliveInterval > 0) {
|
|
17009
|
+
return keepaliveInterval * 1e3;
|
|
17010
|
+
}
|
|
17011
|
+
return this.reconnectConfig.pingInterval;
|
|
16727
17012
|
}
|
|
16728
17013
|
isConnected() {
|
|
16729
17014
|
return this.connectAuthState.isConnected;
|
|
@@ -16748,7 +17033,17 @@ var Socket = class {
|
|
|
16748
17033
|
this.setConnectAuthState("isConnected", false);
|
|
16749
17034
|
const { enabled } = this.reconnectConfig;
|
|
16750
17035
|
if (!this.callKit.config.isLogin() || !enabled) {
|
|
16751
|
-
this.callKit.
|
|
17036
|
+
if (this.callKit.connect.isCalling()) {
|
|
17037
|
+
this.callKit.logger.warn("Disconnect during call, delay reset", {
|
|
17038
|
+
caller: "Socket.handleDisconnect",
|
|
17039
|
+
type: "INCALL",
|
|
17040
|
+
content: {
|
|
17041
|
+
connectStatus: this.callKit.connect.connectStatus
|
|
17042
|
+
}
|
|
17043
|
+
});
|
|
17044
|
+
} else {
|
|
17045
|
+
this.callKit.reset();
|
|
17046
|
+
}
|
|
16752
17047
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
16753
17048
|
event: "INCALL_NOT_CONNECTED"
|
|
16754
17049
|
});
|
|
@@ -16906,6 +17201,28 @@ var Socket = class {
|
|
|
16906
17201
|
this.setConnectAuthState("startConfirm", true);
|
|
16907
17202
|
this.cleanReconnectState();
|
|
16908
17203
|
}
|
|
17204
|
+
if (data.event === SocketReceiveEvent.AGENT_RTP_LOSS) {
|
|
17205
|
+
this.callKit.logger.warn("Agent RTP loss", {
|
|
17206
|
+
caller: "Socket.onMessage",
|
|
17207
|
+
type: "INCALL",
|
|
17208
|
+
content: {
|
|
17209
|
+
data: {
|
|
17210
|
+
callUuid,
|
|
17211
|
+
...content
|
|
17212
|
+
},
|
|
17213
|
+
event: SocketReceiveEvent.AGENT_RTP_LOSS
|
|
17214
|
+
}
|
|
17215
|
+
});
|
|
17216
|
+
if (callUuid) {
|
|
17217
|
+
this.callKit.connect.referInCallToSelf(callUuid).catch((err) => {
|
|
17218
|
+
this.callKit.logger.error(err, {
|
|
17219
|
+
caller: "Socket.onMessage:AGENT_RTP_LOSS",
|
|
17220
|
+
type: "INCALL",
|
|
17221
|
+
content: { callUuid, event: SocketReceiveEvent.AGENT_RTP_LOSS }
|
|
17222
|
+
});
|
|
17223
|
+
});
|
|
17224
|
+
}
|
|
17225
|
+
}
|
|
16909
17226
|
if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {
|
|
16910
17227
|
this.callKit.trigger(KitEvent.CALL_RINGING, {
|
|
16911
17228
|
time: /* @__PURE__ */ new Date(),
|
|
@@ -16954,6 +17271,18 @@ var Socket = class {
|
|
|
16954
17271
|
this.send(SocketSendEvent.END, { agentId: userInfo.agentId, callUuid });
|
|
16955
17272
|
}
|
|
16956
17273
|
if (data.event === SocketReceiveEvent.ERROR) {
|
|
17274
|
+
if (this.callKit.connect.isCalling()) {
|
|
17275
|
+
this.callKit.logger.warn("socket onMessage error during call, ignore", {
|
|
17276
|
+
caller: "Socket.onMessage",
|
|
17277
|
+
type: "INCALL",
|
|
17278
|
+
content: {
|
|
17279
|
+
errCode: ErrorCode.SOCKET_CONNECT_ERROR,
|
|
17280
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
17281
|
+
data: content
|
|
17282
|
+
}
|
|
17283
|
+
});
|
|
17284
|
+
return;
|
|
17285
|
+
}
|
|
16957
17286
|
this.setConnectAuthState("isError", true);
|
|
16958
17287
|
this.callKit.reset();
|
|
16959
17288
|
this.callKit.logger.error(data.msg, {
|
|
@@ -16962,20 +17291,24 @@ var Socket = class {
|
|
|
16962
17291
|
content: {
|
|
16963
17292
|
errCode: ErrorCode.SOKET_SERVER_ERROR,
|
|
16964
17293
|
data: content,
|
|
16965
|
-
callUuid
|
|
17294
|
+
callUuid,
|
|
17295
|
+
delayReset: this.callKit.connect.isCalling()
|
|
16966
17296
|
}
|
|
16967
17297
|
});
|
|
16968
17298
|
}
|
|
16969
17299
|
if (data.event === SocketReceiveEvent.SESSION_ERROR) {
|
|
16970
17300
|
this.setConnectAuthState("isError", true);
|
|
16971
|
-
this.callKit.
|
|
17301
|
+
if (!this.callKit.connect.isCalling()) {
|
|
17302
|
+
this.callKit.reset();
|
|
17303
|
+
}
|
|
16972
17304
|
this.callKit.logger.error(data.msg, {
|
|
16973
17305
|
caller: `Socket.onMessage:${data.event}`,
|
|
16974
17306
|
type: "INCALL",
|
|
16975
17307
|
content: {
|
|
16976
17308
|
data: content,
|
|
16977
17309
|
event: SocketReceiveEvent.SESSION_ERROR,
|
|
16978
|
-
callUuid
|
|
17310
|
+
callUuid,
|
|
17311
|
+
delayReset: this.callKit.connect.isCalling()
|
|
16979
17312
|
}
|
|
16980
17313
|
});
|
|
16981
17314
|
}
|
|
@@ -17007,6 +17340,18 @@ var Socket = class {
|
|
|
17007
17340
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17008
17341
|
event: "INCALL_NOT_CONNECTED"
|
|
17009
17342
|
});
|
|
17343
|
+
if (this.callKit.connect.isCalling()) {
|
|
17344
|
+
this.callKit.logger.warn("socket send during call, ignore", {
|
|
17345
|
+
caller: "Socket.onMessage",
|
|
17346
|
+
type: "INCALL",
|
|
17347
|
+
content: {
|
|
17348
|
+
errCode: ErrorCode.SOCKET_CONNECT_ERROR,
|
|
17349
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
17350
|
+
data: message
|
|
17351
|
+
}
|
|
17352
|
+
});
|
|
17353
|
+
return;
|
|
17354
|
+
}
|
|
17010
17355
|
this.callKit.reset();
|
|
17011
17356
|
this.callKit.logger.error("socket not connected", {
|
|
17012
17357
|
caller: "Socket.send",
|
|
@@ -17059,8 +17404,8 @@ var Socket = class {
|
|
|
17059
17404
|
return;
|
|
17060
17405
|
this.send(SocketSendEvent.PING);
|
|
17061
17406
|
const now = Date.now();
|
|
17062
|
-
const {
|
|
17063
|
-
if (now - this.lastPingTime > pingInterval + pingTimeout) {
|
|
17407
|
+
const { pingTimeout } = this.reconnectConfig;
|
|
17408
|
+
if (now - this.lastPingTime > this.pingInterval + pingTimeout) {
|
|
17064
17409
|
this.callKit.logger.warn("Ping timeout not connected", {
|
|
17065
17410
|
caller: "Socket.ping",
|
|
17066
17411
|
type: "INCALL",
|
|
@@ -17072,26 +17417,48 @@ var Socket = class {
|
|
|
17072
17417
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17073
17418
|
event: "INCALL_PING_TIMEOUT"
|
|
17074
17419
|
});
|
|
17420
|
+
if (this.isUserSetPingTryCount) {
|
|
17421
|
+
this.handlePingTimeout();
|
|
17422
|
+
}
|
|
17075
17423
|
}
|
|
17076
17424
|
}
|
|
17425
|
+
handlePingTimeout() {
|
|
17426
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
17427
|
+
const { pingTryCount, pingTryCountInterval } = userInfo;
|
|
17428
|
+
this.callKit.logger.warn("Ping timeout, user set ping try count", {
|
|
17429
|
+
caller: "Socket.handlePingTimeout",
|
|
17430
|
+
type: "INCALL",
|
|
17431
|
+
content: {
|
|
17432
|
+
errCode: ErrorCode.SOCKET_PING_TIMEOUT,
|
|
17433
|
+
isUserSetPingTryCount: this.isUserSetPingTryCount,
|
|
17434
|
+
pingTryCount,
|
|
17435
|
+
pingTryCountInterval
|
|
17436
|
+
}
|
|
17437
|
+
});
|
|
17438
|
+
this.attemptReconnect();
|
|
17439
|
+
}
|
|
17077
17440
|
checkPing() {
|
|
17078
|
-
|
|
17079
|
-
clearInterval(this.pingTimer);
|
|
17080
|
-
}
|
|
17081
|
-
const { pingInterval } = this.reconnectConfig;
|
|
17082
|
-
this.pingTimer = setInterval(() => {
|
|
17441
|
+
this.heartbeatManager.start(this.pingInterval, () => {
|
|
17083
17442
|
this.ping();
|
|
17084
|
-
}
|
|
17443
|
+
});
|
|
17444
|
+
this.callKit.logger.info(
|
|
17445
|
+
`Heartbeat started with Worker: ${this.heartbeatManager.isUsingWorker()}`,
|
|
17446
|
+
{
|
|
17447
|
+
caller: "Socket.checkPing",
|
|
17448
|
+
type: "INCALL",
|
|
17449
|
+
content: {
|
|
17450
|
+
pingInterval: this.pingInterval,
|
|
17451
|
+
usingWorker: this.heartbeatManager.isUsingWorker()
|
|
17452
|
+
}
|
|
17453
|
+
}
|
|
17454
|
+
);
|
|
17085
17455
|
}
|
|
17086
17456
|
/**
|
|
17087
17457
|
* reset socket connection and all states
|
|
17088
17458
|
*/
|
|
17089
17459
|
async reset(config) {
|
|
17090
17460
|
const { force = false } = config || {};
|
|
17091
|
-
|
|
17092
|
-
clearInterval(this.pingTimer);
|
|
17093
|
-
this.pingTimer = void 0;
|
|
17094
|
-
}
|
|
17461
|
+
this.heartbeatManager.stop();
|
|
17095
17462
|
if (force) {
|
|
17096
17463
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17097
17464
|
event: "INCALL_RESET"
|
|
@@ -17102,6 +17469,12 @@ var Socket = class {
|
|
|
17102
17469
|
this.setConnectAuthState("startConfirm", false);
|
|
17103
17470
|
this.clearWebSocket();
|
|
17104
17471
|
}
|
|
17472
|
+
/**
|
|
17473
|
+
* Destroy the heartbeat manager
|
|
17474
|
+
*/
|
|
17475
|
+
destroyHeartbeat() {
|
|
17476
|
+
this.heartbeatManager.destroy();
|
|
17477
|
+
}
|
|
17105
17478
|
attemptReconnect() {
|
|
17106
17479
|
if (this.reconnectTimer) {
|
|
17107
17480
|
clearTimeout(this.reconnectTimer);
|
|
@@ -17109,19 +17482,40 @@ var Socket = class {
|
|
|
17109
17482
|
}
|
|
17110
17483
|
const { maxAttempts } = this.reconnectConfig;
|
|
17111
17484
|
if (this.reconnectAttempts >= maxAttempts) {
|
|
17485
|
+
if (this.callKit.connect.isCalling()) {
|
|
17486
|
+
this.callKit.logger.warn("reconnect during call, ignore", {
|
|
17487
|
+
caller: "Socket.attemptReconnect",
|
|
17488
|
+
type: "INCALL",
|
|
17489
|
+
content: {
|
|
17490
|
+
errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
|
|
17491
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
17492
|
+
reconnectAttempts: this.reconnectAttempts
|
|
17493
|
+
}
|
|
17494
|
+
});
|
|
17495
|
+
return;
|
|
17496
|
+
}
|
|
17497
|
+
if (this.isUserSetPingTryCount) {
|
|
17498
|
+
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17499
|
+
event: "INCALL_PING_TIMEOUT_RECONNECT_FAILED_MAX_ATTEMPTS"
|
|
17500
|
+
});
|
|
17501
|
+
}
|
|
17112
17502
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
17113
17503
|
event: "INCALL_RECONNECT_ERROR"
|
|
17114
17504
|
});
|
|
17115
17505
|
this.setConnectAuthState("isError", true);
|
|
17116
17506
|
this.callKit.reset();
|
|
17117
|
-
this.callKit.logger.
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
|
|
17122
|
-
|
|
17507
|
+
this.callKit.logger.warn(
|
|
17508
|
+
"Maximum reconnection attempts reached, trigger reset",
|
|
17509
|
+
{
|
|
17510
|
+
caller: "Socket.attemptReconnect",
|
|
17511
|
+
type: "INCALL",
|
|
17512
|
+
content: {
|
|
17513
|
+
errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
|
|
17514
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
17515
|
+
delayReset: this.callKit.connect.isCalling()
|
|
17516
|
+
}
|
|
17123
17517
|
}
|
|
17124
|
-
|
|
17518
|
+
);
|
|
17125
17519
|
return;
|
|
17126
17520
|
}
|
|
17127
17521
|
if (this.reconnectAttempts === 0) {
|
|
@@ -17227,6 +17621,7 @@ var CallKit = class {
|
|
|
17227
17621
|
content: {
|
|
17228
17622
|
username,
|
|
17229
17623
|
password,
|
|
17624
|
+
ua: navigator.userAgent,
|
|
17230
17625
|
encryptionMethod,
|
|
17231
17626
|
encryptionPassword
|
|
17232
17627
|
}
|
|
@@ -17246,6 +17641,7 @@ var CallKit = class {
|
|
|
17246
17641
|
});
|
|
17247
17642
|
if (user) {
|
|
17248
17643
|
this.config.setConfig("userInfo", {
|
|
17644
|
+
...user,
|
|
17249
17645
|
wsUrl: `wss://${user.wsUrl}`,
|
|
17250
17646
|
sessionId: user.sessionId,
|
|
17251
17647
|
username,
|
|
@@ -17260,6 +17656,9 @@ var CallKit = class {
|
|
|
17260
17656
|
iceInfo: user.iceInfo,
|
|
17261
17657
|
iceGatheringTimeout: user.iceGatheringTimeout,
|
|
17262
17658
|
logGather: user.logGather,
|
|
17659
|
+
keepaliveInterval: user.keepaliveInterval,
|
|
17660
|
+
pingTryCount: user?.pingTryCount,
|
|
17661
|
+
pingTryCountInterval: user?.pingTryCountInterval,
|
|
17263
17662
|
phoneType: user.phoneType,
|
|
17264
17663
|
// encryptionType is in extra
|
|
17265
17664
|
...extra
|
|
@@ -17537,4 +17936,3 @@ var CallKit = class {
|
|
|
17537
17936
|
export {
|
|
17538
17937
|
CallKit
|
|
17539
17938
|
};
|
|
17540
|
-
//# sourceMappingURL=index.mjs.map
|