fix(ai): 修复WebSocket重复回调及意外关闭问题
This commit is contained in:
@@ -88,6 +88,16 @@ export default {
|
||||
return new Promise((resolve, reject) => {
|
||||
const match = Config.baseUrl.match(/^(?:https?:\/\/|wss?:\/\/)([^\/\s:]+)/);
|
||||
const domain = match ? match[1] : '';
|
||||
|
||||
// 修复 5:Domain 提取失败时提前拒绝
|
||||
if (!domain) {
|
||||
const errorMsg = 'WebSocket 域名配置无效';
|
||||
console.error(errorMsg);
|
||||
reject(new Error(errorMsg));
|
||||
if (onComplete) onComplete({ error: errorMsg });
|
||||
return;
|
||||
}
|
||||
|
||||
const wssUrl = `wss://${domain}/ws/aikefu`;
|
||||
const socketTask = wx.connectSocket({
|
||||
url: wssUrl,
|
||||
@@ -97,6 +107,29 @@ export default {
|
||||
let content = '';
|
||||
let conversationId = '';
|
||||
let isAuthenticated = false;
|
||||
let closedNormally = false;
|
||||
let settled = false;
|
||||
|
||||
// 安全地拒绝(防止重复调用)
|
||||
function safeReject(error) {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timeout);
|
||||
reject(error);
|
||||
}
|
||||
|
||||
// 安全地完成
|
||||
function safeResolve(result) {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timeout);
|
||||
resolve(result);
|
||||
}
|
||||
|
||||
// 安全地触发 onComplete
|
||||
function safeComplete(result) {
|
||||
if (onComplete) onComplete(result);
|
||||
}
|
||||
|
||||
socketTask.onOpen(() => {
|
||||
socketTask.send({
|
||||
@@ -128,8 +161,8 @@ export default {
|
||||
} else if (data.type === 'auth_failed') {
|
||||
const errorMsg = '认证失败,请重新登录';
|
||||
console.error(errorMsg, data);
|
||||
reject(new Error(errorMsg));
|
||||
if (onComplete) onComplete({ error: errorMsg });
|
||||
safeComplete({ error: errorMsg });
|
||||
safeReject(new Error(errorMsg));
|
||||
socketTask.close();
|
||||
}
|
||||
|
||||
@@ -146,10 +179,9 @@ export default {
|
||||
if (conversationId) {
|
||||
this.setConversationId(conversationId);
|
||||
}
|
||||
if (onComplete) {
|
||||
onComplete({ content, conversation_id: conversationId });
|
||||
}
|
||||
resolve({ content, conversation_id: conversationId });
|
||||
closedNormally = true;
|
||||
safeComplete({ content, conversation_id: conversationId });
|
||||
safeResolve({ content, conversation_id: conversationId });
|
||||
socketTask.close();
|
||||
}
|
||||
|
||||
@@ -165,21 +197,27 @@ export default {
|
||||
socketTask.onError((err) => {
|
||||
const errorMsg = 'WebSocket 连接失败';
|
||||
console.error(errorMsg, err);
|
||||
reject(new Error(errorMsg));
|
||||
if (onComplete) onComplete({ error: errorMsg });
|
||||
safeComplete({ error: errorMsg });
|
||||
safeReject(new Error(errorMsg));
|
||||
});
|
||||
|
||||
socketTask.onClose(() => {
|
||||
if (!closedNormally && !settled) {
|
||||
const errorMsg = 'WebSocket 连接意外关闭';
|
||||
console.error(errorMsg);
|
||||
safeComplete({ error: errorMsg });
|
||||
safeReject(new Error(errorMsg));
|
||||
}
|
||||
});
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
if (!isAuthenticated || content === '') {
|
||||
console.warn('WebSocket 超时,强制关闭');
|
||||
socketTask.close();
|
||||
reject(new Error('AI服务响应超时'));
|
||||
if (onComplete) onComplete({ error: 'AI服务响应超时' });
|
||||
safeComplete({ error: 'AI服务响应超时' });
|
||||
safeReject(new Error('AI服务响应超时'));
|
||||
}
|
||||
}, 10000);
|
||||
}, 20000);
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user