fix(addon/aikefu): 修复EventSource有额外的空表数据输出,导致前端EventSource捕捉到error事件
This commit is contained in:
@@ -213,6 +213,8 @@ class Kefu extends BaseApi
|
|||||||
if ($stream) {
|
if ($stream) {
|
||||||
// 处理流式响应
|
// 处理流式响应
|
||||||
$this->handleStreamingResponse($url, $requestData, $headers, $message, $user_id);
|
$this->handleStreamingResponse($url, $requestData, $headers, $message, $user_id);
|
||||||
|
// 流式响应处理完成后必须退出脚本,避免返回额外内容
|
||||||
|
exit;
|
||||||
} else {
|
} else {
|
||||||
// 处理非流式响应
|
// 处理非流式响应
|
||||||
return $this->handleBlockingResponse($url, $requestData, $headers, $message, $user_id, $conversation_id);
|
return $this->handleBlockingResponse($url, $requestData, $headers, $message, $user_id, $conversation_id);
|
||||||
@@ -617,12 +619,16 @@ class Kefu extends BaseApi
|
|||||||
'content' => $assistant_content
|
'content' => $assistant_content
|
||||||
];
|
];
|
||||||
echo "event: done\ndata: " . json_encode($done_data) . "\n\n";
|
echo "event: done\ndata: " . json_encode($done_data) . "\n\n";
|
||||||
|
|
||||||
|
// 发送连接关闭事件,让客户端知道连接已正常结束
|
||||||
|
echo "event: close\ndata: {\"status\":\"completed\"}\n\n";
|
||||||
|
|
||||||
// 只在有输出缓冲时才刷新
|
// 只在有输出缓冲时才刷新
|
||||||
if (ob_get_level() > 0) {
|
if (ob_get_level() > 0) {
|
||||||
ob_flush();
|
ob_flush();
|
||||||
}
|
}
|
||||||
flush();
|
flush();
|
||||||
$this->log('发送done事件,会话ID:' . $real_conversation_id, 'info');
|
$this->log('发送done和close事件,会话ID:' . $real_conversation_id, 'info');
|
||||||
|
|
||||||
// 保存助手的完整回复
|
// 保存助手的完整回复
|
||||||
if (!empty($real_conversation_id) && !empty($real_assistant_message_id) && !empty($assistant_content)) {
|
if (!empty($real_conversation_id) && !empty($real_assistant_message_id) && !empty($assistant_content)) {
|
||||||
@@ -637,6 +643,9 @@ class Kefu extends BaseApi
|
|||||||
$error_msg = 'AI客服请求异常:' . $e->getMessage() . ',错误行:' . $e->getLine() . ',错误文件:' . $e->getFile();
|
$error_msg = 'AI客服请求异常:' . $e->getMessage() . ',错误行:' . $e->getLine() . ',错误文件:' . $e->getFile();
|
||||||
$this->log($error_msg, 'error');
|
$this->log($error_msg, 'error');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 流式响应处理完成后必须退出脚本,避免EventSource协议错误
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -231,7 +231,7 @@
|
|||||||
|
|
||||||
if (data.event === 'message_end') {
|
if (data.event === 'message_end') {
|
||||||
statusText.textContent = '对话完成';
|
statusText.textContent = '对话完成';
|
||||||
sendBtn.disabled = false;
|
// 不要在这里关闭连接,等待done和close事件
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.conversation_id) {
|
if (data.conversation_id) {
|
||||||
@@ -257,16 +257,35 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 监听连接关闭事件
|
||||||
|
es.addEventListener('close', (event) => {
|
||||||
|
console.log('收到连接关闭事件:', event);
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
console.log('连接正常结束:', data);
|
||||||
|
if (es) {
|
||||||
|
es.close();
|
||||||
|
es = null;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析关闭事件失败:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 监听错误事件
|
// 监听错误事件
|
||||||
es.addEventListener('error', (error) => {
|
es.addEventListener('error', (error) => {
|
||||||
console.error('EventSource 错误:', error);
|
console.error('EventSource 错误:', error);
|
||||||
// 添加更详细的错误信息
|
// 添加更详细的错误信息
|
||||||
if (es.readyState === EventSource.CLOSED) {
|
if (es.readyState === EventSource.CLOSED) {
|
||||||
console.error('EventSource 连接已关闭');
|
console.log('EventSource 连接已正常关闭');
|
||||||
|
statusText.textContent = '连接已关闭';
|
||||||
} else if (es.readyState === EventSource.CONNECTING) {
|
} else if (es.readyState === EventSource.CONNECTING) {
|
||||||
console.error('EventSource 连接中出现错误');
|
console.error('EventSource 连接中出现错误');
|
||||||
|
statusText.textContent = '连接错误';
|
||||||
|
} else {
|
||||||
|
console.error('EventSource 未知错误');
|
||||||
|
statusText.textContent = '连接错误';
|
||||||
}
|
}
|
||||||
statusText.textContent = '连接错误';
|
|
||||||
sendBtn.disabled = false;
|
sendBtn.disabled = false;
|
||||||
if (es) {
|
if (es) {
|
||||||
es.close();
|
es.close();
|
||||||
@@ -274,11 +293,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听关闭事件
|
|
||||||
es.addEventListener('close', () => {
|
|
||||||
console.log('EventSource 连接关闭');
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('创建 EventSource 失败:', error);
|
console.error('创建 EventSource 失败:', error);
|
||||||
statusText.textContent = '请求失败';
|
statusText.textContent = '请求失败';
|
||||||
|
|||||||
@@ -365,6 +365,8 @@ class Kefu extends BaseApi
|
|||||||
|
|
||||||
// 触发事件,让监听器处理流式响应
|
// 触发事件,让监听器处理流式响应
|
||||||
event('KefuChat', $event_data);
|
event('KefuChat', $event_data);
|
||||||
|
// 流式响应需要终止脚本执行,避免输出额外内容导致EventSource错误
|
||||||
|
exit;
|
||||||
} else {
|
} else {
|
||||||
// 触发智能客服聊天事件(非流式)
|
// 触发智能客服聊天事件(非流式)
|
||||||
$result = event('KefuChat', $event_data);
|
$result = event('KefuChat', $event_data);
|
||||||
|
|||||||
Reference in New Issue
Block a user