From 8c18e48b97cb50d8a020eeeba3ebfd00d651c283 Mon Sep 17 00:00:00 2001 From: Sakura-RanChen <1908198662@qq.com> Date: Wed, 22 Apr 2026 15:55:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E5=81=9C=E6=AD=A2=E5=B8=A7=E5=8F=91?= =?UTF-8?q?=E9=80=81=E5=90=8E=E4=B8=8E=E5=8E=9F=E5=85=88=E9=9F=B3=E9=A2=91?= =?UTF-8?q?=E6=97=B6=E5=BA=8F=E9=97=AE=E9=A2=98=20=E5=9B=9E=E9=80=80?= =?UTF-8?q?=E9=80=80=E5=87=BA=E5=B7=A5=E5=85=B7=E6=89=93=E6=96=AD=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=88=E5=9C=A8=E5=A4=A7=E6=A8=A1=E5=9E=8B=E6=80=9D?= =?UTF-8?q?=E8=80=83=E6=9C=9F=E9=97=B4=E8=BF=9B=E8=A1=8C=E6=89=93=E6=96=AD?= =?UTF-8?q?=EF=BC=8C=E7=84=B6=E5=90=8E=E5=A4=A7=E6=A8=A1=E5=9E=8B=E7=AB=8B?= =?UTF-8?q?=E9=A9=AC=E8=B0=83=E7=94=A8=E9=80=80=E5=87=BA=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E4=BC=9A=E9=80=A0=E6=88=90=E6=AD=BB=E9=94=81=EF=BC=8C=E5=9B=A0?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=80=9D=E8=80=83=E6=97=B6=E9=97=B4=E5=92=8C?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E8=B0=83=E7=94=A8=E5=B7=A5=E5=85=B7=E4=B8=8D?= =?UTF-8?q?=E7=A1=AE=E5=AE=9A=E6=80=A7=EF=BC=8C=E7=8A=B6=E6=80=81=E9=9A=BE?= =?UTF-8?q?=E7=AE=A1=E7=90=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/connection.py | 6 ------ main/xiaozhi-server/core/handle/abortHandle.py | 4 ---- main/xiaozhi-server/core/handle/intentHandler.py | 5 ----- main/xiaozhi-server/core/handle/receiveAudioHandle.py | 2 -- main/xiaozhi-server/core/providers/asr/base.py | 6 ------ main/xiaozhi-server/core/providers/asr/doubao_stream.py | 6 +++++- .../plugins_func/functions/handle_exit_intent.py | 1 - 7 files changed, 5 insertions(+), 25 deletions(-) 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..b7bf1611 100644 --- a/main/xiaozhi-server/core/handle/abortHandle.py +++ b/main/xiaozhi-server/core/handle/abortHandle.py @@ -7,10 +7,6 @@ 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.client_abort = True 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..bd24f372 100644 --- a/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py +++ b/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py @@ -31,7 +31,6 @@ 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: From ff66b815a58f46b2879f5821e6b2494e65fd5e31 Mon Sep 17 00:00:00 2001 From: Sakura-RanChen <1908198662@qq.com> Date: Thu, 23 Apr 2026 10:17:43 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E5=9C=A8=E6=A8=A1=E5=9E=8B=E5=92=8C?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E8=B0=83=E7=94=A8=E6=9C=9F=E9=97=B4=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E6=89=93=E6=96=AD=E5=90=8E=E8=AF=B4=E5=AE=8C=E8=AF=9D?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=80=80=E5=87=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/handle/abortHandle.py | 1 + .../plugins_func/functions/handle_exit_intent.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/main/xiaozhi-server/core/handle/abortHandle.py b/main/xiaozhi-server/core/handle/abortHandle.py index b7bf1611..c4a2fa88 100644 --- a/main/xiaozhi-server/core/handle/abortHandle.py +++ b/main/xiaozhi-server/core/handle/abortHandle.py @@ -9,6 +9,7 @@ TAG = __name__ async def handleAbortMessage(conn: "ConnectionHandler"): 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/plugins_func/functions/handle_exit_intent.py b/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py index bd24f372..79347659 100644 --- a/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py +++ b/main/xiaozhi-server/plugins_func/functions/handle_exit_intent.py @@ -35,7 +35,8 @@ def handle_exit_intent(conn: "ConnectionHandler", say_goodbye: str | None = None 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