3s没有接受到新消息才会创建新聊天框

This commit is contained in:
fsy
2025-03-22 15:04:59 +08:00
parent 9f58286bfe
commit 1cbb2653a6
2 changed files with 114 additions and 39 deletions

View File

@@ -20,6 +20,7 @@ class AgoraService {
this.inConversation = false; // 是否在对话状态中
this.speechSegmentCallback = null; // 语音段落回调函数
this.readableTextCallback = null; // 可读文本回调函数
this.lastMessageTime = null; // 最后一次消息接收时间,用于判断是否需要创建新消息
}
/**
@@ -40,45 +41,71 @@ class AgoraService {
this.client.on('stream-message', (uid, message) => {
try {
// 确认接收到的是字节流Uint8Array
if (message instanceof Uint8Array) {
const decodedMessage = new TextDecoder().decode(message);
// console.log('Decoded message (Raw String):', decodedMessage);
const parts = decodedMessage.split('|');
const base64Data = parts[parts.length - 1];
// console.log('Extracted Base64 data:', base64Data);
const jsonString = atob(base64Data);
console.log('Decoded JSON string:', jsonString);
jsonBuffer += jsonString;
if (isCompleteJson(jsonBuffer)) {
const jsonData = JSON.parse(jsonString); // 将字符串解析为 JSON 对象
console.log('Parsed JSON object:', jsonData);
// 确认接收到的是字节流Uint8Array
if (message instanceof Uint8Array) {
const decodedMessage = new TextDecoder().decode(message);
const parts = decodedMessage.split('|');
const base64Data = parts[parts.length - 1];
if (this.readableTextCallback && typeof this.readableTextCallback === 'function') {
this.readableTextCallback(jsonData.text); // 传递解码后的文本到回调
const jsonString = atob(base64Data);
console.log('Decoded JSON string:', jsonString);
// 如果新的JSON字符串以 { 开头说明是一个新的JSON对象的开始
// 丢弃之前已经累积的数据
if (jsonString.trim().startsWith('{')) {
console.log('检测到新的JSON对象开始重置缓冲区');
jsonBuffer = '';
}
jsonBuffer = '';
return jsonData.text;
// 累积JSON字符串
jsonBuffer += jsonString;
// 检查是否是完整的JSON
if (isCompleteJson(jsonBuffer)) {
const jsonData = JSON.parse(jsonBuffer); // 将字符串解析为 JSON 对象
console.log('成功解析完整JSON对象:', jsonData);
// 记录最后一次消息接收时间,用于判断是否需要创建新消息
const currentTime = new Date();
if (!this.lastMessageTime) {
this.lastMessageTime = currentTime;
}
// 计算时间差(毫秒)
const timeDiff = currentTime - this.lastMessageTime;
// 更新最后一次消息时间
this.lastMessageTime = currentTime;
if (this.readableTextCallback && typeof this.readableTextCallback === 'function') {
this.readableTextCallback(jsonData.text); // 传递解码后的文本到回调
}
jsonBuffer = '';
return jsonData.text;
} else {
console.log('JSON不完整当前累积长度:', jsonBuffer.length);
}
} else {
console.log('接收的消息不是Uint8Array:', message);
}
} else {
console.log('Received message is not Uint8Array:', message);
} catch (error) {
console.error('处理stream-message时出错:', error);
}
} catch (error) {
console.error('Error processing stream-message:', error);
}
});
function isCompleteJson(jsonString) {
const openBraces = (jsonString.match(/{/g) || []).length;
const closeBraces = (jsonString.match(/}/g) || []).length;
if (openBraces === 0 || openBraces !== closeBraces) {
return false;
}
try {
JSON.parse(jsonString); // 解析测试是否为合法 JSON
return true; // 如果能被解析,说明是完整的 JSON
JSON.parse(jsonString);
return true;
} catch (error) {
return false; // 捕获解析错误,说明 JSON 不完整
return false;
}
}
@@ -218,6 +245,7 @@ class AgoraService {
this.inConversation = true;
this.speechSegmentCallback = speechCallback;
this.readableTextCallback = textCallback;
this.lastMessageTime = new Date(); // 重置最后一次消息时间
}
/**

View File

@@ -104,12 +104,33 @@ export const useChatStore = defineStore('chat', {
handleReadableText(text) {
if (!text || !text.trim()) return;
const isFromAI = text.includes('\n\n') || text.includes('<think>\n');
const currentTime = new Date();
const sender = isFromAI ? 'ai' : 'user';
// 获取最后一条消息
const lastMessage = this.lastMessage;
// 检查是否需要创建新消息或更新现有消息
if (lastMessage && lastMessage.sender === sender) {
// 计算时间差(毫秒)
const timeDiff = currentTime - new Date(lastMessage.timestamp);
// 如果时间差小于3秒更新最后一条消息
if (timeDiff < 3000) {
// 更新最后一条消息的内容
lastMessage.content = text;
// 更新时间戳
lastMessage.timestamp = currentTime.toISOString();
return;
}
}
// 如果时间差大于3秒或者是不同发送者添加新消息
this.addMessage({
id: Date.now(),
content: text,
sender: isFromAI ? 'ai' : 'user',
timestamp: new Date().toISOString(),
sender: sender,
timestamp: currentTime.toISOString(),
});
},
@@ -176,15 +197,41 @@ export const useChatStore = defineStore('chat', {
* @param {string} text - 语音段落文本
*/
handleSpeechSegment(text) {
console.log("我在这里!");
console.log("处理语音段落:", text);
if (!text || !text.trim()) return;
// 更新当前转写
this.updateTranscript(text);
// 发送消息
this.sendMessage(text);
// 使用与handleReadableText相同的逻辑处理消息
const currentTime = new Date();
const sender = 'user'; // 语音段落总是来自用户
// 获取最后一条消息
const lastMessage = this.lastMessage;
// 检查是否需要创建新消息或更新现有消息
if (lastMessage && lastMessage.sender === sender) {
// 计算时间差(毫秒)
const timeDiff = currentTime - new Date(lastMessage.timestamp);
// 如果时间差小于3秒更新最后一条消息
if (timeDiff < 3000) {
// 更新最后一条消息的内容
lastMessage.content = text;
// 更新时间戳
lastMessage.timestamp = currentTime.toISOString();
return;
}
}
// 如果时间差大于3秒或者是不同发送者添加新消息
this.addMessage({
id: Date.now(),
content: text,
sender: sender,
timestamp: currentTime.toISOString(),
});
},
/**
@@ -201,9 +248,9 @@ export const useChatStore = defineStore('chat', {
stopListening() {
if (!this.inConversation) return;
// 如果有转写内容,发送消息
// 如果有转写内容,使用handleSpeechSegment处理消息
if (this.currentTranscript.trim()) {
this.sendMessage(this.currentTranscript.trim());
this.handleSpeechSegment(this.currentTranscript.trim());
}
this.endConversation();