diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index b58ede82..d1e6be73 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -148,8 +148,6 @@ class ConnectionHandler: self.memory = _memory self.intent = _intent - self.is_exiting = False # 标记是否正在执行退出流程 - # 为每个连接单独管理声纹识别 self.voiceprint_provider = None @@ -350,10 +348,6 @@ class ConnectionHandler: async def _route_message(self, message): """消息路由""" - # 退出状态丢弃所有消息 - if self.is_exiting: - return - # 检查是否已经获取到真实的绑定状态 if not self.bind_completed_event.is_set(): # 还没有获取到真实状态,等待直到获取到真实状态或超时 diff --git a/main/xiaozhi-server/core/handle/abortHandle.py b/main/xiaozhi-server/core/handle/abortHandle.py index b74b2893..c4a2fa88 100644 --- a/main/xiaozhi-server/core/handle/abortHandle.py +++ b/main/xiaozhi-server/core/handle/abortHandle.py @@ -7,12 +7,9 @@ TAG = __name__ async def handleAbortMessage(conn: "ConnectionHandler"): - if conn.close_after_chat or conn.is_exiting: - conn.logger.bind(tag=TAG).info("退出流程中被打断,直接关闭连接") - return - conn.logger.bind(tag=TAG).info("Abort message received") # 设置成打断状态,会自动打断llm、tts任务 + conn.close_after_chat = False conn.client_abort = True conn.clear_queues() # 打断客户端说话状态 diff --git a/main/xiaozhi-server/core/handle/intentHandler.py b/main/xiaozhi-server/core/handle/intentHandler.py index 4d173259..4172653f 100644 --- a/main/xiaozhi-server/core/handle/intentHandler.py +++ b/main/xiaozhi-server/core/handle/intentHandler.py @@ -33,10 +33,6 @@ async def handle_user_intent(conn: "ConnectionHandler", text): if await check_direct_exit(conn, filtered_text): return True - # 明确再见不被打断 - if conn.is_exiting: - return True - # 检查是否是唤醒词 if await checkWakeupWords(conn, filtered_text): return True @@ -62,7 +58,6 @@ async def check_direct_exit(conn: "ConnectionHandler", text): if text == cmd: conn.logger.bind(tag=TAG).info(f"识别到明确的退出命令: {text}") await send_stt_message(conn, text) - conn.is_exiting = True await conn.close() return True return False diff --git a/main/xiaozhi-server/core/handle/receiveAudioHandle.py b/main/xiaozhi-server/core/handle/receiveAudioHandle.py index 7e234a9e..ae4673a0 100644 --- a/main/xiaozhi-server/core/handle/receiveAudioHandle.py +++ b/main/xiaozhi-server/core/handle/receiveAudioHandle.py @@ -15,8 +15,6 @@ TAG = __name__ async def handleAudioMessage(conn: "ConnectionHandler", audio): - if conn.is_exiting: - return # 当前片段是否有人说话 have_voice = conn.vad.is_vad(conn, audio) # 如果设备刚刚被唤醒,短暂忽略VAD检测 diff --git a/main/xiaozhi-server/core/providers/asr/base.py b/main/xiaozhi-server/core/providers/asr/base.py index 6ede6a5d..986dd275 100644 --- a/main/xiaozhi-server/core/providers/asr/base.py +++ b/main/xiaozhi-server/core/providers/asr/base.py @@ -84,12 +84,6 @@ class ASRProviderBase(ABC): async def handle_voice_stop(self, conn: "ConnectionHandler", asr_audio_task: List[bytes]): """并行处理ASR和声纹识别""" try: - # 如果处于退出流程中,直接关闭连接,不处理新消息 - if conn.close_after_chat or conn.is_exiting: - logger.bind(tag=TAG).info("退出流程中收到新消息,直接关闭连接") - await conn.close() - return - total_start_time = time.monotonic() # 准备音频数据 diff --git a/main/xiaozhi-server/core/providers/asr/doubao_stream.py b/main/xiaozhi-server/core/providers/asr/doubao_stream.py index d9a36f4d..5c34aa77 100644 --- a/main/xiaozhi-server/core/providers/asr/doubao_stream.py +++ b/main/xiaozhi-server/core/providers/asr/doubao_stream.py @@ -26,6 +26,7 @@ class ASRProvider(ASRProviderBase): self.asr_ws = None self.forward_task = None self.is_processing = False # 添加处理状态标志 + self._is_stopping = False # 添加停止标志,防止竞态条件 # 配置参数 self.appid = str(config.get("appid")) @@ -148,7 +149,7 @@ class ASRProvider(ASRProviderBase): return # 发送当前音频数据 - if self.asr_ws and self.is_processing: + if self.asr_ws and self.is_processing and not self._is_stopping: try: pcm_frame = self.decoder.decode(audio, 960) payload = gzip.compress(pcm_frame) @@ -256,6 +257,7 @@ class ASRProvider(ASRProviderBase): await self.asr_ws.close() self.asr_ws = None self.is_processing = False + self._is_stopping = False # 重置所有音频相关状态 conn.reset_audio_states() @@ -264,9 +266,11 @@ class ASRProvider(ASRProviderBase): asyncio.create_task(self.asr_ws.close()) self.asr_ws = None self.is_processing = False + self._is_stopping = False async def _send_stop_request(self): """发送最后一个音频帧以通知服务器结束""" + self._is_stopping = True # 先标记为停止状态,阻止后续音频发送 if self.asr_ws: try: # 发送结束标记的音频帧(gzip压缩的空数据) diff --git a/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py b/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py index 154c4f89..79347659 100644 --- a/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py +++ b/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py @@ -31,12 +31,12 @@ handle_exit_intent_function_desc = { "handle_exit_intent", handle_exit_intent_function_desc, ToolType.SYSTEM_CTL ) def handle_exit_intent(conn: "ConnectionHandler", say_goodbye: str | None = None): - conn.is_exiting = True # 处理退出意图 try: if say_goodbye is None: say_goodbye = "再见,祝您生活愉快!" - conn.close_after_chat = True + if not conn.close_after_chat: + conn.close_after_chat = True logger.bind(tag=TAG).info(f"退出意图已处理:{say_goodbye}") return ActionResponse( action=Action.RESPONSE, result="退出意图已处理", response=say_goodbye