@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.global.js
CHANGED
|
@@ -1736,7 +1736,7 @@ var WebCall = (() => {
|
|
|
1736
1736
|
var require_follow_redirects = __commonJS({
|
|
1737
1737
|
"../../node_modules/.pnpm/follow-redirects@1.15.9/node_modules/follow-redirects/index.js"(exports, module) {
|
|
1738
1738
|
var url = __require("url");
|
|
1739
|
-
var
|
|
1739
|
+
var URL2 = url.URL;
|
|
1740
1740
|
var http = __require("http");
|
|
1741
1741
|
var https = __require("https");
|
|
1742
1742
|
var Writable = __require("stream").Writable;
|
|
@@ -1752,7 +1752,7 @@ var WebCall = (() => {
|
|
|
1752
1752
|
})();
|
|
1753
1753
|
var useNativeURL = false;
|
|
1754
1754
|
try {
|
|
1755
|
-
assert(new
|
|
1755
|
+
assert(new URL2(""));
|
|
1756
1756
|
} catch (error) {
|
|
1757
1757
|
useNativeURL = error.code === "ERR_INVALID_URL";
|
|
1758
1758
|
}
|
|
@@ -2132,7 +2132,7 @@ var WebCall = (() => {
|
|
|
2132
2132
|
function parseUrl(input) {
|
|
2133
2133
|
var parsed;
|
|
2134
2134
|
if (useNativeURL) {
|
|
2135
|
-
parsed = new
|
|
2135
|
+
parsed = new URL2(input);
|
|
2136
2136
|
} else {
|
|
2137
2137
|
parsed = validateUrl(url.parse(input));
|
|
2138
2138
|
if (!isString(parsed.protocol)) {
|
|
@@ -2142,7 +2142,7 @@ var WebCall = (() => {
|
|
|
2142
2142
|
return parsed;
|
|
2143
2143
|
}
|
|
2144
2144
|
function resolveUrl(relative, base) {
|
|
2145
|
-
return useNativeURL ? new
|
|
2145
|
+
return useNativeURL ? new URL2(relative, base) : parseUrl(url.resolve(base, relative));
|
|
2146
2146
|
}
|
|
2147
2147
|
function validateUrl(input) {
|
|
2148
2148
|
if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
|
|
@@ -2221,7 +2221,7 @@ var WebCall = (() => {
|
|
|
2221
2221
|
return typeof value === "object" && "length" in value;
|
|
2222
2222
|
}
|
|
2223
2223
|
function isURL(value) {
|
|
2224
|
-
return
|
|
2224
|
+
return URL2 && value instanceof URL2;
|
|
2225
2225
|
}
|
|
2226
2226
|
module.exports = wrap({ http, https });
|
|
2227
2227
|
module.exports.wrap = wrap;
|
|
@@ -3237,7 +3237,7 @@ var WebCall = (() => {
|
|
|
3237
3237
|
const res = await this.post({
|
|
3238
3238
|
url: "/auth/agentUser/login",
|
|
3239
3239
|
method: "post",
|
|
3240
|
-
data: params
|
|
3240
|
+
data: { ...params, browserVersion: navigator.userAgent }
|
|
3241
3241
|
});
|
|
3242
3242
|
return res;
|
|
3243
3243
|
} finally {
|
|
@@ -3700,7 +3700,11 @@ var WebCall = (() => {
|
|
|
3700
3700
|
ERROR: "ERROR",
|
|
3701
3701
|
SESSION_ERROR: "SESSION_ERROR",
|
|
3702
3702
|
WAITING_QUEUE: "WAITING_QUEUE",
|
|
3703
|
-
CUSTOMER_MATCH_BLACK_PHONE: "CUSTOMER_MATCH_BLACK_PHONE"
|
|
3703
|
+
CUSTOMER_MATCH_BLACK_PHONE: "CUSTOMER_MATCH_BLACK_PHONE",
|
|
3704
|
+
/**
|
|
3705
|
+
* Agent RTP loss
|
|
3706
|
+
*/
|
|
3707
|
+
AGENT_RTP_LOSS: "AGENT_RTP_LOSS"
|
|
3704
3708
|
};
|
|
3705
3709
|
var EncryptionMethod = {
|
|
3706
3710
|
NONE: "NONE",
|
|
@@ -3745,7 +3749,9 @@ var WebCall = (() => {
|
|
|
3745
3749
|
delay: 1e3,
|
|
3746
3750
|
registererOptions: {
|
|
3747
3751
|
refreshFrequency: 90
|
|
3748
|
-
}
|
|
3752
|
+
},
|
|
3753
|
+
enableMessageKeepalive: true,
|
|
3754
|
+
messageKeepaliveInterval: 30
|
|
3749
3755
|
};
|
|
3750
3756
|
|
|
3751
3757
|
// core/call.ts
|
|
@@ -3889,13 +3895,13 @@ var WebCall = (() => {
|
|
|
3889
3895
|
// package.json
|
|
3890
3896
|
var package_default = {
|
|
3891
3897
|
name: "@koi-design/callkit",
|
|
3892
|
-
version: "2.3.
|
|
3898
|
+
version: "2.3.1-beta.2",
|
|
3893
3899
|
description: "callkit",
|
|
3894
3900
|
author: "koi",
|
|
3895
3901
|
license: "ISC",
|
|
3896
3902
|
scripts: {
|
|
3897
3903
|
build: "tsup",
|
|
3898
|
-
start: "
|
|
3904
|
+
start: "vite --host 0.0.0.0",
|
|
3899
3905
|
dev: "tsup --watch",
|
|
3900
3906
|
lint: "eslint -c ../../.eslintrc.js --ext .jsx,.js,.tsx,.ts ./package --fix",
|
|
3901
3907
|
release: "tsup && node scripts/pkg.js"
|
|
@@ -18730,7 +18736,15 @@ ${log}` : log;
|
|
|
18730
18736
|
this.callKit = callKit;
|
|
18731
18737
|
}
|
|
18732
18738
|
get reconnectConfig() {
|
|
18733
|
-
|
|
18739
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
18740
|
+
const { enableMessageKeepalive } = userInfo;
|
|
18741
|
+
const { messageKeepaliveInterval } = userInfo;
|
|
18742
|
+
const defaultConfig = this.callKit.config.getReconnectConfig("sip");
|
|
18743
|
+
if (enableMessageKeepalive) {
|
|
18744
|
+
defaultConfig.enableMessageKeepalive = enableMessageKeepalive;
|
|
18745
|
+
defaultConfig.messageKeepaliveInterval = messageKeepaliveInterval;
|
|
18746
|
+
}
|
|
18747
|
+
return defaultConfig;
|
|
18734
18748
|
}
|
|
18735
18749
|
// current call id for invite data
|
|
18736
18750
|
currentCallId = null;
|
|
@@ -18854,6 +18868,7 @@ ${log}` : log;
|
|
|
18854
18868
|
}
|
|
18855
18869
|
}
|
|
18856
18870
|
this.setConnectStatus(CallStatus.init);
|
|
18871
|
+
this.stopMessageKeepalive();
|
|
18857
18872
|
}
|
|
18858
18873
|
getAduioReference() {
|
|
18859
18874
|
const { audioRef } = this.callKit.config.getConfig();
|
|
@@ -18989,8 +19004,6 @@ ${log}` : log;
|
|
|
18989
19004
|
});
|
|
18990
19005
|
return;
|
|
18991
19006
|
}
|
|
18992
|
-
const { userInfo } = this.callKit.config.getConfig();
|
|
18993
|
-
const { userPart, fsIp, fsPort } = userInfo;
|
|
18994
19007
|
const { registererOptions = {} } = this.reconnectConfig;
|
|
18995
19008
|
this.registerer = new Registerer(this.userAgent, registererOptions);
|
|
18996
19009
|
this.registerer.stateChange.addListener((state) => {
|
|
@@ -19008,6 +19021,7 @@ ${log}` : log;
|
|
|
19008
19021
|
if (!this.isInCallRefering()) {
|
|
19009
19022
|
this.setConnectStatus(CallStatus.init);
|
|
19010
19023
|
}
|
|
19024
|
+
this.stopMessageKeepalive();
|
|
19011
19025
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
19012
19026
|
registererState: state,
|
|
19013
19027
|
isRegistered: this.isRegistered()
|
|
@@ -19024,27 +19038,26 @@ ${log}` : log;
|
|
|
19024
19038
|
});
|
|
19025
19039
|
this.setRegister(true);
|
|
19026
19040
|
if (this.isReConnected) {
|
|
19027
|
-
if (this.
|
|
19028
|
-
const selfUri = `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
|
|
19041
|
+
if (this.canReferInCallToSelf()) {
|
|
19029
19042
|
this.callKit.logger.info(
|
|
19030
19043
|
"Reconnected, referring active session to self",
|
|
19031
19044
|
{
|
|
19032
19045
|
caller: "Connect.setupRegisterer.registererStateChange",
|
|
19033
19046
|
type: "SIP",
|
|
19034
19047
|
content: {
|
|
19035
|
-
selfUri,
|
|
19048
|
+
selfUri: this.getSelfReferUri(),
|
|
19036
19049
|
sessionState: this.currentSession.state,
|
|
19037
19050
|
connectStatus: this.connectStatus
|
|
19038
19051
|
}
|
|
19039
19052
|
}
|
|
19040
19053
|
);
|
|
19041
|
-
this.
|
|
19054
|
+
this.referInCallToSelf().catch((err) => {
|
|
19042
19055
|
this.callKit.logger.error(err, {
|
|
19043
19056
|
caller: "Connect.setupRegisterer.registererStateChange",
|
|
19044
19057
|
type: "SIP",
|
|
19045
19058
|
content: {
|
|
19046
19059
|
errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR,
|
|
19047
|
-
selfUri
|
|
19060
|
+
selfUri: this.getSelfReferUri()
|
|
19048
19061
|
}
|
|
19049
19062
|
});
|
|
19050
19063
|
});
|
|
@@ -19065,6 +19078,7 @@ ${log}` : log;
|
|
|
19065
19078
|
}
|
|
19066
19079
|
this.setIsReConnected(false);
|
|
19067
19080
|
}
|
|
19081
|
+
this.startMessageKeepalive();
|
|
19068
19082
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
19069
19083
|
registererState: state,
|
|
19070
19084
|
isRegistered: this.isRegistered()
|
|
@@ -19084,6 +19098,7 @@ ${log}` : log;
|
|
|
19084
19098
|
if (!this.isInCallRefering()) {
|
|
19085
19099
|
this.setConnectStatus(CallStatus.init);
|
|
19086
19100
|
}
|
|
19101
|
+
this.stopMessageKeepalive();
|
|
19087
19102
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
19088
19103
|
registererState: state,
|
|
19089
19104
|
isRegistered: this.isRegistered(),
|
|
@@ -19104,6 +19119,7 @@ ${log}` : log;
|
|
|
19104
19119
|
if (!this.isInCallRefering()) {
|
|
19105
19120
|
this.setConnectStatus(CallStatus.init);
|
|
19106
19121
|
}
|
|
19122
|
+
this.stopMessageKeepalive();
|
|
19107
19123
|
this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {
|
|
19108
19124
|
registererState: state,
|
|
19109
19125
|
isRegistered: this.isRegistered(),
|
|
@@ -19150,7 +19166,7 @@ ${log}` : log;
|
|
|
19150
19166
|
this.mediaStream = await navigator.mediaDevices.getUserMedia(constrains);
|
|
19151
19167
|
return this.mediaStream;
|
|
19152
19168
|
};
|
|
19153
|
-
const { userPart, fsIp, fsPort, iceInfo, wsUrl } = userInfo;
|
|
19169
|
+
const { userPart, fsIp, fsPort, fsPassword, iceInfo, wsUrl } = userInfo;
|
|
19154
19170
|
const connectConfig = {
|
|
19155
19171
|
uri: UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`),
|
|
19156
19172
|
displayName: userPart,
|
|
@@ -19159,6 +19175,8 @@ ${log}` : log;
|
|
|
19159
19175
|
traceSip: true
|
|
19160
19176
|
},
|
|
19161
19177
|
logLevel: "error",
|
|
19178
|
+
authorizationUsername: userPart,
|
|
19179
|
+
authorizationPassword: fsPassword,
|
|
19162
19180
|
allowLegacyNotifications: true,
|
|
19163
19181
|
contactName: userPart,
|
|
19164
19182
|
contactParams: { transport: "wss" },
|
|
@@ -19414,7 +19432,10 @@ ${log}` : log;
|
|
|
19414
19432
|
}
|
|
19415
19433
|
});
|
|
19416
19434
|
this.setupRegisterer();
|
|
19417
|
-
|
|
19435
|
+
try {
|
|
19436
|
+
await this.registerer.register();
|
|
19437
|
+
this.startMessageKeepalive();
|
|
19438
|
+
} catch (err) {
|
|
19418
19439
|
this.callKit.reset();
|
|
19419
19440
|
this.callKit.logger.error(err?.message, {
|
|
19420
19441
|
caller: "Connect.register",
|
|
@@ -19423,9 +19444,10 @@ ${log}` : log;
|
|
|
19423
19444
|
errCode: ErrorCode.WEBRTC_REGISTER_ERROR
|
|
19424
19445
|
}
|
|
19425
19446
|
});
|
|
19426
|
-
}
|
|
19447
|
+
}
|
|
19427
19448
|
},
|
|
19428
19449
|
onDisconnect: (error) => {
|
|
19450
|
+
this.stopMessageKeepalive();
|
|
19429
19451
|
if (error) {
|
|
19430
19452
|
this.callKit.logger.warn("SIP User Agent Disconnected with error", {
|
|
19431
19453
|
caller: "Connect.register",
|
|
@@ -19461,6 +19483,7 @@ ${log}` : log;
|
|
|
19461
19483
|
}
|
|
19462
19484
|
reconnectTimer;
|
|
19463
19485
|
reconnectAttempts = 0;
|
|
19486
|
+
messageKeepaliveTimer;
|
|
19464
19487
|
startReconnectTimer() {
|
|
19465
19488
|
if (this._isError || this.isReConnected)
|
|
19466
19489
|
return;
|
|
@@ -19514,8 +19537,53 @@ ${log}` : log;
|
|
|
19514
19537
|
}
|
|
19515
19538
|
}, this.reconnectConfig.delay);
|
|
19516
19539
|
}
|
|
19540
|
+
stopMessageKeepalive() {
|
|
19541
|
+
if (this.messageKeepaliveTimer) {
|
|
19542
|
+
clearInterval(this.messageKeepaliveTimer);
|
|
19543
|
+
this.messageKeepaliveTimer = void 0;
|
|
19544
|
+
}
|
|
19545
|
+
}
|
|
19546
|
+
startMessageKeepalive() {
|
|
19547
|
+
const { enableMessageKeepalive, messageKeepaliveInterval } = this.reconnectConfig;
|
|
19548
|
+
if (!enableMessageKeepalive)
|
|
19549
|
+
return;
|
|
19550
|
+
this.stopMessageKeepalive();
|
|
19551
|
+
this.messageKeepaliveTimer = setInterval(() => {
|
|
19552
|
+
this.sendKeepaliveMessage();
|
|
19553
|
+
}, messageKeepaliveInterval * 1e3);
|
|
19554
|
+
}
|
|
19555
|
+
async sendKeepaliveMessage() {
|
|
19556
|
+
try {
|
|
19557
|
+
if (!this.isRegistered() || !this.userAgent)
|
|
19558
|
+
return;
|
|
19559
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
19560
|
+
const { userPart, fsIp, fsPort } = userInfo || {};
|
|
19561
|
+
const target = UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`);
|
|
19562
|
+
if (!target)
|
|
19563
|
+
return;
|
|
19564
|
+
const messager = new Messager(this.userAgent, target, "");
|
|
19565
|
+
await messager.message();
|
|
19566
|
+
this.callKit.logger.info("MESSAGE keepalive ok", {
|
|
19567
|
+
caller: "Connect.sendKeepaliveMessage",
|
|
19568
|
+
type: "SIP",
|
|
19569
|
+
content: {}
|
|
19570
|
+
});
|
|
19571
|
+
} catch (err) {
|
|
19572
|
+
this.callKit.logger.error(err, {
|
|
19573
|
+
caller: "Connect.sendKeepaliveMessage",
|
|
19574
|
+
type: "SIP",
|
|
19575
|
+
content: {}
|
|
19576
|
+
});
|
|
19577
|
+
this.stopMessageKeepalive();
|
|
19578
|
+
this.callKit.trigger(KitEvent.SIP_CONNECT_EVENT, {
|
|
19579
|
+
event: "MESSAGE_KEEPALIVE_FAILED"
|
|
19580
|
+
});
|
|
19581
|
+
this.startReconnectTimer();
|
|
19582
|
+
}
|
|
19583
|
+
}
|
|
19517
19584
|
async stop() {
|
|
19518
19585
|
await this.userAgent.stop();
|
|
19586
|
+
this.stopMessageKeepalive();
|
|
19519
19587
|
}
|
|
19520
19588
|
async unregister() {
|
|
19521
19589
|
this.callKit.logger.info("connect unregister", {
|
|
@@ -19525,6 +19593,7 @@ ${log}` : log;
|
|
|
19525
19593
|
isRegistered: this.isRegistered()
|
|
19526
19594
|
}
|
|
19527
19595
|
});
|
|
19596
|
+
this.stopMessageKeepalive();
|
|
19528
19597
|
if (!this.isRegistered() || !this.registerer) {
|
|
19529
19598
|
this.callKit.logger.warn("No registerer to unregister.", {
|
|
19530
19599
|
caller: "Connect.unregister",
|
|
@@ -19873,6 +19942,199 @@ ${log}` : log;
|
|
|
19873
19942
|
}
|
|
19874
19943
|
this.currentSession.refer(target, extra?.sessionReferOptions);
|
|
19875
19944
|
}
|
|
19945
|
+
/**
|
|
19946
|
+
* Get the SIP URI for "refer to self" (same as reconnection refer logic).
|
|
19947
|
+
* Shared by referInCallToSelf and internal reconnection refer.
|
|
19948
|
+
*/
|
|
19949
|
+
getSelfReferUri() {
|
|
19950
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
19951
|
+
const { userPart, fsIp, fsPort } = userInfo;
|
|
19952
|
+
return `sip:manualCallAgent${userPart}@${fsIp}:${fsPort}`;
|
|
19953
|
+
}
|
|
19954
|
+
/**
|
|
19955
|
+
* Whether we can refer the current call to self (has active session in Established/Establishing and is calling).
|
|
19956
|
+
* Shared by reconnection logic and referInCallToSelf.
|
|
19957
|
+
*/
|
|
19958
|
+
canReferInCallToSelf() {
|
|
19959
|
+
return !!this.currentSession && (this.currentSession.state === SessionState2.Established || this.currentSession.state === SessionState2.Establishing) && this.isCalling();
|
|
19960
|
+
}
|
|
19961
|
+
/**
|
|
19962
|
+
* Refer the current call to self (e.g. Agent RTP loss recovery, post-reconnect recovery).
|
|
19963
|
+
* Socket and other callers can use this without constructing referTo.
|
|
19964
|
+
*/
|
|
19965
|
+
async referInCallToSelf(callUuid, extra) {
|
|
19966
|
+
if (callUuid && this.currentCallId !== callUuid) {
|
|
19967
|
+
this.callKit.logger.warn(
|
|
19968
|
+
"Cannot refer in call to self: callUuid mismatch",
|
|
19969
|
+
{
|
|
19970
|
+
caller: "Connect.referInCallToSelf",
|
|
19971
|
+
type: "SIP",
|
|
19972
|
+
content: {
|
|
19973
|
+
currentCallId: this.currentCallId,
|
|
19974
|
+
callUuid
|
|
19975
|
+
}
|
|
19976
|
+
}
|
|
19977
|
+
);
|
|
19978
|
+
return;
|
|
19979
|
+
}
|
|
19980
|
+
if (!this.canReferInCallToSelf()) {
|
|
19981
|
+
this.callKit.logger.warn(
|
|
19982
|
+
"Cannot refer in call to self: preconditions not met",
|
|
19983
|
+
{
|
|
19984
|
+
caller: "Connect.referInCallToSelf",
|
|
19985
|
+
type: "SIP",
|
|
19986
|
+
content: {
|
|
19987
|
+
hasCurrentSession: !!this.currentSession,
|
|
19988
|
+
sessionState: this.currentSession?.state,
|
|
19989
|
+
isCalling: this.isCalling()
|
|
19990
|
+
}
|
|
19991
|
+
}
|
|
19992
|
+
);
|
|
19993
|
+
return;
|
|
19994
|
+
}
|
|
19995
|
+
const selfUri = this.getSelfReferUri();
|
|
19996
|
+
return this.referInCall(selfUri, extra);
|
|
19997
|
+
}
|
|
19998
|
+
};
|
|
19999
|
+
|
|
20000
|
+
// core/heartbeat-worker.ts
|
|
20001
|
+
var workerCode = `
|
|
20002
|
+
let timer = null;
|
|
20003
|
+
let interval = 30000;
|
|
20004
|
+
|
|
20005
|
+
self.onmessage = function(e) {
|
|
20006
|
+
const { type, interval: newInterval } = e.data;
|
|
20007
|
+
|
|
20008
|
+
if (type === 'start') {
|
|
20009
|
+
if (timer) {
|
|
20010
|
+
clearInterval(timer);
|
|
20011
|
+
}
|
|
20012
|
+
interval = newInterval || interval;
|
|
20013
|
+
timer = setInterval(() => {
|
|
20014
|
+
self.postMessage({ type: 'tick' });
|
|
20015
|
+
}, interval);
|
|
20016
|
+
}
|
|
20017
|
+
|
|
20018
|
+
if (type === 'stop') {
|
|
20019
|
+
if (timer) {
|
|
20020
|
+
clearInterval(timer);
|
|
20021
|
+
timer = null;
|
|
20022
|
+
}
|
|
20023
|
+
}
|
|
20024
|
+
|
|
20025
|
+
if (type === 'updateInterval') {
|
|
20026
|
+
interval = newInterval;
|
|
20027
|
+
if (timer) {
|
|
20028
|
+
clearInterval(timer);
|
|
20029
|
+
timer = setInterval(() => {
|
|
20030
|
+
self.postMessage({ type: 'tick' });
|
|
20031
|
+
}, interval);
|
|
20032
|
+
}
|
|
20033
|
+
}
|
|
20034
|
+
};
|
|
20035
|
+
`;
|
|
20036
|
+
function createHeartbeatWorker() {
|
|
20037
|
+
try {
|
|
20038
|
+
const blob = new Blob([workerCode], { type: "application/javascript" });
|
|
20039
|
+
const workerUrl = URL.createObjectURL(blob);
|
|
20040
|
+
const worker = new Worker(workerUrl);
|
|
20041
|
+
URL.revokeObjectURL(workerUrl);
|
|
20042
|
+
return worker;
|
|
20043
|
+
} catch {
|
|
20044
|
+
return null;
|
|
20045
|
+
}
|
|
20046
|
+
}
|
|
20047
|
+
var HeartbeatManager = class {
|
|
20048
|
+
worker = null;
|
|
20049
|
+
fallbackTimer = null;
|
|
20050
|
+
interval = 3e4;
|
|
20051
|
+
onTick = null;
|
|
20052
|
+
isRunning = false;
|
|
20053
|
+
constructor() {
|
|
20054
|
+
this.worker = createHeartbeatWorker();
|
|
20055
|
+
if (this.worker) {
|
|
20056
|
+
this.worker.onmessage = (e) => {
|
|
20057
|
+
if (e.data.type === "tick" && this.onTick) {
|
|
20058
|
+
this.onTick();
|
|
20059
|
+
}
|
|
20060
|
+
};
|
|
20061
|
+
}
|
|
20062
|
+
}
|
|
20063
|
+
/**
|
|
20064
|
+
* Start the heartbeat
|
|
20065
|
+
* @param interval - Interval in milliseconds
|
|
20066
|
+
* @param onTick - Callback function to execute on each tick
|
|
20067
|
+
*/
|
|
20068
|
+
start(interval, onTick) {
|
|
20069
|
+
this.stop();
|
|
20070
|
+
this.interval = interval;
|
|
20071
|
+
this.onTick = onTick;
|
|
20072
|
+
this.isRunning = true;
|
|
20073
|
+
if (this.worker) {
|
|
20074
|
+
this.worker.postMessage({
|
|
20075
|
+
type: "start",
|
|
20076
|
+
interval
|
|
20077
|
+
});
|
|
20078
|
+
} else {
|
|
20079
|
+
this.fallbackTimer = setInterval(() => {
|
|
20080
|
+
if (this.onTick) {
|
|
20081
|
+
this.onTick();
|
|
20082
|
+
}
|
|
20083
|
+
}, interval);
|
|
20084
|
+
}
|
|
20085
|
+
}
|
|
20086
|
+
/**
|
|
20087
|
+
* Stop the heartbeat
|
|
20088
|
+
*/
|
|
20089
|
+
stop() {
|
|
20090
|
+
this.isRunning = false;
|
|
20091
|
+
this.onTick = null;
|
|
20092
|
+
if (this.worker) {
|
|
20093
|
+
this.worker.postMessage({ type: "stop" });
|
|
20094
|
+
}
|
|
20095
|
+
if (this.fallbackTimer) {
|
|
20096
|
+
clearInterval(this.fallbackTimer);
|
|
20097
|
+
this.fallbackTimer = null;
|
|
20098
|
+
}
|
|
20099
|
+
}
|
|
20100
|
+
/**
|
|
20101
|
+
* Update the heartbeat interval
|
|
20102
|
+
* @param interval - New interval in milliseconds
|
|
20103
|
+
*/
|
|
20104
|
+
updateInterval(interval) {
|
|
20105
|
+
this.interval = interval;
|
|
20106
|
+
if (!this.isRunning)
|
|
20107
|
+
return;
|
|
20108
|
+
if (this.worker) {
|
|
20109
|
+
this.worker.postMessage({
|
|
20110
|
+
type: "updateInterval",
|
|
20111
|
+
interval
|
|
20112
|
+
});
|
|
20113
|
+
} else if (this.fallbackTimer && this.onTick) {
|
|
20114
|
+
clearInterval(this.fallbackTimer);
|
|
20115
|
+
this.fallbackTimer = setInterval(() => {
|
|
20116
|
+
if (this.onTick) {
|
|
20117
|
+
this.onTick();
|
|
20118
|
+
}
|
|
20119
|
+
}, interval);
|
|
20120
|
+
}
|
|
20121
|
+
}
|
|
20122
|
+
/**
|
|
20123
|
+
* Destroy the heartbeat manager and release resources
|
|
20124
|
+
*/
|
|
20125
|
+
destroy() {
|
|
20126
|
+
this.stop();
|
|
20127
|
+
if (this.worker) {
|
|
20128
|
+
this.worker.terminate();
|
|
20129
|
+
this.worker = null;
|
|
20130
|
+
}
|
|
20131
|
+
}
|
|
20132
|
+
/**
|
|
20133
|
+
* Check if using Web Worker
|
|
20134
|
+
*/
|
|
20135
|
+
isUsingWorker() {
|
|
20136
|
+
return this.worker !== null;
|
|
20137
|
+
}
|
|
19876
20138
|
};
|
|
19877
20139
|
|
|
19878
20140
|
// core/socket.ts
|
|
@@ -19880,7 +20142,7 @@ ${log}` : log;
|
|
|
19880
20142
|
callKit;
|
|
19881
20143
|
ws;
|
|
19882
20144
|
lastPingTime = void 0;
|
|
19883
|
-
|
|
20145
|
+
heartbeatManager;
|
|
19884
20146
|
/**
|
|
19885
20147
|
* @description reconnect timer
|
|
19886
20148
|
*/
|
|
@@ -19913,9 +20175,32 @@ ${log}` : log;
|
|
|
19913
20175
|
}
|
|
19914
20176
|
constructor(callKit) {
|
|
19915
20177
|
this.callKit = callKit;
|
|
20178
|
+
this.heartbeatManager = new HeartbeatManager();
|
|
20179
|
+
}
|
|
20180
|
+
get isUserSetPingTryCount() {
|
|
20181
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
20182
|
+
const { pingTryCount } = userInfo;
|
|
20183
|
+
return Number.isInteger(pingTryCount) && pingTryCount > 0;
|
|
19916
20184
|
}
|
|
19917
20185
|
get reconnectConfig() {
|
|
19918
|
-
|
|
20186
|
+
const incallConfig = this.callKit.config.getReconnectConfig("incall");
|
|
20187
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
20188
|
+
const { pingTryCount, pingTryCountInterval } = userInfo;
|
|
20189
|
+
if (pingTryCount > 0) {
|
|
20190
|
+
return {
|
|
20191
|
+
...incallConfig,
|
|
20192
|
+
maxAttempts: pingTryCount,
|
|
20193
|
+
interval: pingTryCountInterval * 1e3
|
|
20194
|
+
};
|
|
20195
|
+
}
|
|
20196
|
+
return incallConfig;
|
|
20197
|
+
}
|
|
20198
|
+
get pingInterval() {
|
|
20199
|
+
const { keepaliveInterval } = this.callKit.config.getConfig().userInfo;
|
|
20200
|
+
if (Number.isInteger(keepaliveInterval) && keepaliveInterval > 0) {
|
|
20201
|
+
return keepaliveInterval * 1e3;
|
|
20202
|
+
}
|
|
20203
|
+
return this.reconnectConfig.pingInterval;
|
|
19919
20204
|
}
|
|
19920
20205
|
isConnected() {
|
|
19921
20206
|
return this.connectAuthState.isConnected;
|
|
@@ -19940,7 +20225,17 @@ ${log}` : log;
|
|
|
19940
20225
|
this.setConnectAuthState("isConnected", false);
|
|
19941
20226
|
const { enabled } = this.reconnectConfig;
|
|
19942
20227
|
if (!this.callKit.config.isLogin() || !enabled) {
|
|
19943
|
-
this.callKit.
|
|
20228
|
+
if (this.callKit.connect.isCalling()) {
|
|
20229
|
+
this.callKit.logger.warn("Disconnect during call, delay reset", {
|
|
20230
|
+
caller: "Socket.handleDisconnect",
|
|
20231
|
+
type: "INCALL",
|
|
20232
|
+
content: {
|
|
20233
|
+
connectStatus: this.callKit.connect.connectStatus
|
|
20234
|
+
}
|
|
20235
|
+
});
|
|
20236
|
+
} else {
|
|
20237
|
+
this.callKit.reset();
|
|
20238
|
+
}
|
|
19944
20239
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
19945
20240
|
event: "INCALL_NOT_CONNECTED"
|
|
19946
20241
|
});
|
|
@@ -20098,6 +20393,28 @@ ${log}` : log;
|
|
|
20098
20393
|
this.setConnectAuthState("startConfirm", true);
|
|
20099
20394
|
this.cleanReconnectState();
|
|
20100
20395
|
}
|
|
20396
|
+
if (data.event === SocketReceiveEvent.AGENT_RTP_LOSS) {
|
|
20397
|
+
this.callKit.logger.warn("Agent RTP loss", {
|
|
20398
|
+
caller: "Socket.onMessage",
|
|
20399
|
+
type: "INCALL",
|
|
20400
|
+
content: {
|
|
20401
|
+
data: {
|
|
20402
|
+
callUuid,
|
|
20403
|
+
...content
|
|
20404
|
+
},
|
|
20405
|
+
event: SocketReceiveEvent.AGENT_RTP_LOSS
|
|
20406
|
+
}
|
|
20407
|
+
});
|
|
20408
|
+
if (callUuid) {
|
|
20409
|
+
this.callKit.connect.referInCallToSelf(callUuid).catch((err) => {
|
|
20410
|
+
this.callKit.logger.error(err, {
|
|
20411
|
+
caller: "Socket.onMessage:AGENT_RTP_LOSS",
|
|
20412
|
+
type: "INCALL",
|
|
20413
|
+
content: { callUuid, event: SocketReceiveEvent.AGENT_RTP_LOSS }
|
|
20414
|
+
});
|
|
20415
|
+
});
|
|
20416
|
+
}
|
|
20417
|
+
}
|
|
20101
20418
|
if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {
|
|
20102
20419
|
this.callKit.trigger(KitEvent.CALL_RINGING, {
|
|
20103
20420
|
time: /* @__PURE__ */ new Date(),
|
|
@@ -20146,6 +20463,18 @@ ${log}` : log;
|
|
|
20146
20463
|
this.send(SocketSendEvent.END, { agentId: userInfo.agentId, callUuid });
|
|
20147
20464
|
}
|
|
20148
20465
|
if (data.event === SocketReceiveEvent.ERROR) {
|
|
20466
|
+
if (this.callKit.connect.isCalling()) {
|
|
20467
|
+
this.callKit.logger.warn("socket onMessage error during call, ignore", {
|
|
20468
|
+
caller: "Socket.onMessage",
|
|
20469
|
+
type: "INCALL",
|
|
20470
|
+
content: {
|
|
20471
|
+
errCode: ErrorCode.SOCKET_CONNECT_ERROR,
|
|
20472
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
20473
|
+
data: content
|
|
20474
|
+
}
|
|
20475
|
+
});
|
|
20476
|
+
return;
|
|
20477
|
+
}
|
|
20149
20478
|
this.setConnectAuthState("isError", true);
|
|
20150
20479
|
this.callKit.reset();
|
|
20151
20480
|
this.callKit.logger.error(data.msg, {
|
|
@@ -20154,20 +20483,24 @@ ${log}` : log;
|
|
|
20154
20483
|
content: {
|
|
20155
20484
|
errCode: ErrorCode.SOKET_SERVER_ERROR,
|
|
20156
20485
|
data: content,
|
|
20157
|
-
callUuid
|
|
20486
|
+
callUuid,
|
|
20487
|
+
delayReset: this.callKit.connect.isCalling()
|
|
20158
20488
|
}
|
|
20159
20489
|
});
|
|
20160
20490
|
}
|
|
20161
20491
|
if (data.event === SocketReceiveEvent.SESSION_ERROR) {
|
|
20162
20492
|
this.setConnectAuthState("isError", true);
|
|
20163
|
-
this.callKit.
|
|
20493
|
+
if (!this.callKit.connect.isCalling()) {
|
|
20494
|
+
this.callKit.reset();
|
|
20495
|
+
}
|
|
20164
20496
|
this.callKit.logger.error(data.msg, {
|
|
20165
20497
|
caller: `Socket.onMessage:${data.event}`,
|
|
20166
20498
|
type: "INCALL",
|
|
20167
20499
|
content: {
|
|
20168
20500
|
data: content,
|
|
20169
20501
|
event: SocketReceiveEvent.SESSION_ERROR,
|
|
20170
|
-
callUuid
|
|
20502
|
+
callUuid,
|
|
20503
|
+
delayReset: this.callKit.connect.isCalling()
|
|
20171
20504
|
}
|
|
20172
20505
|
});
|
|
20173
20506
|
}
|
|
@@ -20199,6 +20532,18 @@ ${log}` : log;
|
|
|
20199
20532
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
20200
20533
|
event: "INCALL_NOT_CONNECTED"
|
|
20201
20534
|
});
|
|
20535
|
+
if (this.callKit.connect.isCalling()) {
|
|
20536
|
+
this.callKit.logger.warn("socket send during call, ignore", {
|
|
20537
|
+
caller: "Socket.onMessage",
|
|
20538
|
+
type: "INCALL",
|
|
20539
|
+
content: {
|
|
20540
|
+
errCode: ErrorCode.SOCKET_CONNECT_ERROR,
|
|
20541
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
20542
|
+
data: message
|
|
20543
|
+
}
|
|
20544
|
+
});
|
|
20545
|
+
return;
|
|
20546
|
+
}
|
|
20202
20547
|
this.callKit.reset();
|
|
20203
20548
|
this.callKit.logger.error("socket not connected", {
|
|
20204
20549
|
caller: "Socket.send",
|
|
@@ -20251,8 +20596,8 @@ ${log}` : log;
|
|
|
20251
20596
|
return;
|
|
20252
20597
|
this.send(SocketSendEvent.PING);
|
|
20253
20598
|
const now = Date.now();
|
|
20254
|
-
const {
|
|
20255
|
-
if (now - this.lastPingTime > pingInterval + pingTimeout) {
|
|
20599
|
+
const { pingTimeout } = this.reconnectConfig;
|
|
20600
|
+
if (now - this.lastPingTime > this.pingInterval + pingTimeout) {
|
|
20256
20601
|
this.callKit.logger.warn("Ping timeout not connected", {
|
|
20257
20602
|
caller: "Socket.ping",
|
|
20258
20603
|
type: "INCALL",
|
|
@@ -20264,26 +20609,48 @@ ${log}` : log;
|
|
|
20264
20609
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
20265
20610
|
event: "INCALL_PING_TIMEOUT"
|
|
20266
20611
|
});
|
|
20612
|
+
if (this.isUserSetPingTryCount) {
|
|
20613
|
+
this.handlePingTimeout();
|
|
20614
|
+
}
|
|
20267
20615
|
}
|
|
20268
20616
|
}
|
|
20617
|
+
handlePingTimeout() {
|
|
20618
|
+
const { userInfo } = this.callKit.config.getConfig();
|
|
20619
|
+
const { pingTryCount, pingTryCountInterval } = userInfo;
|
|
20620
|
+
this.callKit.logger.warn("Ping timeout, user set ping try count", {
|
|
20621
|
+
caller: "Socket.handlePingTimeout",
|
|
20622
|
+
type: "INCALL",
|
|
20623
|
+
content: {
|
|
20624
|
+
errCode: ErrorCode.SOCKET_PING_TIMEOUT,
|
|
20625
|
+
isUserSetPingTryCount: this.isUserSetPingTryCount,
|
|
20626
|
+
pingTryCount,
|
|
20627
|
+
pingTryCountInterval
|
|
20628
|
+
}
|
|
20629
|
+
});
|
|
20630
|
+
this.attemptReconnect();
|
|
20631
|
+
}
|
|
20269
20632
|
checkPing() {
|
|
20270
|
-
|
|
20271
|
-
clearInterval(this.pingTimer);
|
|
20272
|
-
}
|
|
20273
|
-
const { pingInterval } = this.reconnectConfig;
|
|
20274
|
-
this.pingTimer = setInterval(() => {
|
|
20633
|
+
this.heartbeatManager.start(this.pingInterval, () => {
|
|
20275
20634
|
this.ping();
|
|
20276
|
-
}
|
|
20635
|
+
});
|
|
20636
|
+
this.callKit.logger.info(
|
|
20637
|
+
`Heartbeat started with Worker: ${this.heartbeatManager.isUsingWorker()}`,
|
|
20638
|
+
{
|
|
20639
|
+
caller: "Socket.checkPing",
|
|
20640
|
+
type: "INCALL",
|
|
20641
|
+
content: {
|
|
20642
|
+
pingInterval: this.pingInterval,
|
|
20643
|
+
usingWorker: this.heartbeatManager.isUsingWorker()
|
|
20644
|
+
}
|
|
20645
|
+
}
|
|
20646
|
+
);
|
|
20277
20647
|
}
|
|
20278
20648
|
/**
|
|
20279
20649
|
* reset socket connection and all states
|
|
20280
20650
|
*/
|
|
20281
20651
|
async reset(config) {
|
|
20282
20652
|
const { force = false } = config || {};
|
|
20283
|
-
|
|
20284
|
-
clearInterval(this.pingTimer);
|
|
20285
|
-
this.pingTimer = void 0;
|
|
20286
|
-
}
|
|
20653
|
+
this.heartbeatManager.stop();
|
|
20287
20654
|
if (force) {
|
|
20288
20655
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
20289
20656
|
event: "INCALL_RESET"
|
|
@@ -20294,6 +20661,12 @@ ${log}` : log;
|
|
|
20294
20661
|
this.setConnectAuthState("startConfirm", false);
|
|
20295
20662
|
this.clearWebSocket();
|
|
20296
20663
|
}
|
|
20664
|
+
/**
|
|
20665
|
+
* Destroy the heartbeat manager
|
|
20666
|
+
*/
|
|
20667
|
+
destroyHeartbeat() {
|
|
20668
|
+
this.heartbeatManager.destroy();
|
|
20669
|
+
}
|
|
20297
20670
|
attemptReconnect() {
|
|
20298
20671
|
if (this.reconnectTimer) {
|
|
20299
20672
|
clearTimeout(this.reconnectTimer);
|
|
@@ -20301,19 +20674,40 @@ ${log}` : log;
|
|
|
20301
20674
|
}
|
|
20302
20675
|
const { maxAttempts } = this.reconnectConfig;
|
|
20303
20676
|
if (this.reconnectAttempts >= maxAttempts) {
|
|
20677
|
+
if (this.callKit.connect.isCalling()) {
|
|
20678
|
+
this.callKit.logger.warn("reconnect during call, ignore", {
|
|
20679
|
+
caller: "Socket.attemptReconnect",
|
|
20680
|
+
type: "INCALL",
|
|
20681
|
+
content: {
|
|
20682
|
+
errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
|
|
20683
|
+
isCalling: this.callKit.connect.isCalling(),
|
|
20684
|
+
reconnectAttempts: this.reconnectAttempts
|
|
20685
|
+
}
|
|
20686
|
+
});
|
|
20687
|
+
return;
|
|
20688
|
+
}
|
|
20689
|
+
if (this.isUserSetPingTryCount) {
|
|
20690
|
+
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
20691
|
+
event: "INCALL_PING_TIMEOUT_RECONNECT_FAILED_MAX_ATTEMPTS"
|
|
20692
|
+
});
|
|
20693
|
+
}
|
|
20304
20694
|
this.callKit.trigger(KitEvent.INCALL_CONNECT_EVENT, {
|
|
20305
20695
|
event: "INCALL_RECONNECT_ERROR"
|
|
20306
20696
|
});
|
|
20307
20697
|
this.setConnectAuthState("isError", true);
|
|
20308
20698
|
this.callKit.reset();
|
|
20309
|
-
this.callKit.logger.
|
|
20310
|
-
|
|
20311
|
-
|
|
20312
|
-
|
|
20313
|
-
|
|
20314
|
-
|
|
20699
|
+
this.callKit.logger.warn(
|
|
20700
|
+
"Maximum reconnection attempts reached, trigger reset",
|
|
20701
|
+
{
|
|
20702
|
+
caller: "Socket.attemptReconnect",
|
|
20703
|
+
type: "INCALL",
|
|
20704
|
+
content: {
|
|
20705
|
+
errCode: ErrorCode.SOCKET_RECONNECT_FAILED,
|
|
20706
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
20707
|
+
delayReset: this.callKit.connect.isCalling()
|
|
20708
|
+
}
|
|
20315
20709
|
}
|
|
20316
|
-
|
|
20710
|
+
);
|
|
20317
20711
|
return;
|
|
20318
20712
|
}
|
|
20319
20713
|
if (this.reconnectAttempts === 0) {
|
|
@@ -20419,6 +20813,7 @@ ${log}` : log;
|
|
|
20419
20813
|
content: {
|
|
20420
20814
|
username,
|
|
20421
20815
|
password,
|
|
20816
|
+
ua: navigator.userAgent,
|
|
20422
20817
|
encryptionMethod,
|
|
20423
20818
|
encryptionPassword
|
|
20424
20819
|
}
|
|
@@ -20438,6 +20833,7 @@ ${log}` : log;
|
|
|
20438
20833
|
});
|
|
20439
20834
|
if (user) {
|
|
20440
20835
|
this.config.setConfig("userInfo", {
|
|
20836
|
+
...user,
|
|
20441
20837
|
wsUrl: `wss://${user.wsUrl}`,
|
|
20442
20838
|
sessionId: user.sessionId,
|
|
20443
20839
|
username,
|
|
@@ -20452,6 +20848,9 @@ ${log}` : log;
|
|
|
20452
20848
|
iceInfo: user.iceInfo,
|
|
20453
20849
|
iceGatheringTimeout: user.iceGatheringTimeout,
|
|
20454
20850
|
logGather: user.logGather,
|
|
20851
|
+
keepaliveInterval: user.keepaliveInterval,
|
|
20852
|
+
pingTryCount: user?.pingTryCount,
|
|
20853
|
+
pingTryCountInterval: user?.pingTryCountInterval,
|
|
20455
20854
|
phoneType: user.phoneType,
|
|
20456
20855
|
// encryptionType is in extra
|
|
20457
20856
|
...extra
|
|
@@ -20728,4 +21127,3 @@ ${log}` : log;
|
|
|
20728
21127
|
};
|
|
20729
21128
|
return __toCommonJS(core_exports);
|
|
20730
21129
|
})();
|
|
20731
|
-
//# sourceMappingURL=index.global.js.map
|