@xmov/avatar 2.4.0-beta.4 → 2.4.0-beta.5
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.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.modern.js +1 -1
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +1 -1
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/utils/request.d.ts +1 -0
- package/package.json +1 -1
- package/src/index.ts +8 -5
- package/src/modules/ResourceManager.ts +18 -1
- package/src/utils/request.ts +2 -0
package/dist/utils/request.d.ts
CHANGED
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1320,7 +1320,9 @@ export default class XmovAvatar {
|
|
|
1320
1320
|
private handleBeforeUnload = () => {
|
|
1321
1321
|
if (!this._isClientMode && (this.resourceManager?.session_id || this.resourceManager?.session_request_id)) {
|
|
1322
1322
|
// Page dismissal cannot wait for E2E and TTSA shutdown before starting DELETE.
|
|
1323
|
-
this.beforeUnloadStopSessionPromise ??= this.resourceManager.stopSession("beforeunload", { keepalive: true })
|
|
1323
|
+
this.beforeUnloadStopSessionPromise ??= this.resourceManager.stopSession("beforeunload", { keepalive: true }).catch((error) => {
|
|
1324
|
+
(window as any).avatarSDKLogger.warn(this.TAG, "页面卸载时停止会话失败", error);
|
|
1325
|
+
});
|
|
1324
1326
|
}
|
|
1325
1327
|
void this.destroy("beforeunload");
|
|
1326
1328
|
};
|
|
@@ -1466,9 +1468,10 @@ export default class XmovAvatar {
|
|
|
1466
1468
|
this.ttsa?.sendSdkPoint('close_session', {
|
|
1467
1469
|
reason: stop_reason,
|
|
1468
1470
|
});
|
|
1469
|
-
|
|
1471
|
+
// An unload DELETE is already in flight; neither await nor cancel it.
|
|
1472
|
+
const res = this.beforeUnloadStopSessionPromise ? undefined : await this.resourceManager.stopSession(stop_reason);
|
|
1470
1473
|
await this.destroyClient();
|
|
1471
|
-
if(res) {
|
|
1474
|
+
if(res || this.beforeUnloadStopSessionPromise) {
|
|
1472
1475
|
this.onStatusChange(AvatarStatus.close);
|
|
1473
1476
|
}
|
|
1474
1477
|
return res
|
|
@@ -1489,8 +1492,8 @@ export default class XmovAvatar {
|
|
|
1489
1492
|
(window as any).avatarSDKLogger.warn(this.TAG, "TTSA client_quit 未确认,继续释放本地资源", error);
|
|
1490
1493
|
} finally {
|
|
1491
1494
|
try {
|
|
1492
|
-
if (!this._isClientMode) {
|
|
1493
|
-
await
|
|
1495
|
+
if (!this._isClientMode && !this.beforeUnloadStopSessionPromise) {
|
|
1496
|
+
await this.resourceManager.stopSession(stopReason);
|
|
1494
1497
|
}
|
|
1495
1498
|
} finally {
|
|
1496
1499
|
await this.destroyClient();
|
|
@@ -10,6 +10,8 @@ import { headersNeedSign, generateRequestId } from "../utils/encodeToken";
|
|
|
10
10
|
// import { isDEV } from "../utils";
|
|
11
11
|
import CacheManager from './cache-manager';
|
|
12
12
|
|
|
13
|
+
const STOP_SESSION_TIMEOUT_MS = 3000;
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* 资源处理模块,加载并存储资源
|
|
15
17
|
*/
|
|
@@ -407,6 +409,7 @@ export default class ResourceManager {
|
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
async stopSession(stop_reason: string, options: { keepalive?: boolean } = {}) {
|
|
412
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
410
413
|
try {
|
|
411
414
|
const url = `${this.options.gatewayServer}`;
|
|
412
415
|
// session_id 尚未返回时(如 init 未完成就 destroy),只要有 request_id 仍发请求,
|
|
@@ -424,7 +427,19 @@ export default class ResourceManager {
|
|
|
424
427
|
data.request_id = this.session_request_id;
|
|
425
428
|
}
|
|
426
429
|
const { headers, data: signedData } = headersNeedSign(this.options.appId, this.options.appSecret, "DELETE", url, data);
|
|
427
|
-
|
|
430
|
+
// Unload requests must be allowed to outlive the document. Ordinary
|
|
431
|
+
// DELETEs have a deadline covering both response headers and body.
|
|
432
|
+
const controller = options.keepalive ? undefined : new AbortController();
|
|
433
|
+
if (controller) {
|
|
434
|
+
timeout = setTimeout(() => controller.abort(), STOP_SESSION_TIMEOUT_MS);
|
|
435
|
+
}
|
|
436
|
+
const response = await request(url, {
|
|
437
|
+
method: "DELETE",
|
|
438
|
+
data: signedData,
|
|
439
|
+
headers: { ...headers, ...this.options.headers },
|
|
440
|
+
keepalive: options.keepalive,
|
|
441
|
+
signal: controller?.signal,
|
|
442
|
+
});
|
|
428
443
|
return await response.json();
|
|
429
444
|
} catch (error) {
|
|
430
445
|
this.sdk.onMessage({
|
|
@@ -432,6 +447,8 @@ export default class ResourceManager {
|
|
|
432
447
|
message: `Error: 停止会话失败`,
|
|
433
448
|
e: error,
|
|
434
449
|
});
|
|
450
|
+
} finally {
|
|
451
|
+
if (timeout !== undefined) clearTimeout(timeout);
|
|
435
452
|
}
|
|
436
453
|
}
|
|
437
454
|
|
package/src/utils/request.ts
CHANGED
|
@@ -5,6 +5,7 @@ interface RequestOptions {
|
|
|
5
5
|
data?: Record<string, any>
|
|
6
6
|
headers?: Record<string, string>
|
|
7
7
|
keepalive?: boolean
|
|
8
|
+
signal?: AbortSignal
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
interface ErrorResponse {
|
|
@@ -23,6 +24,7 @@ export default async function request(
|
|
|
23
24
|
const config: RequestInit = {
|
|
24
25
|
method,
|
|
25
26
|
keepalive: options.keepalive,
|
|
27
|
+
signal: options.signal,
|
|
26
28
|
// headers,
|
|
27
29
|
headers: {
|
|
28
30
|
'Content-Type': 'application/json',
|