From 43d2adff7068d5a4c1e912e265ba24091b45aacf Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Wed, 7 May 2025 09:11:59 +0800 Subject: [PATCH] =?UTF-8?q?update:=E6=9B=B4=E6=96=B0=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E9=85=8D=E7=BD=AE=E5=B9=B6=E9=87=8D=E6=96=B0=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/connection.py | 70 +---------------- main/xiaozhi-server/core/handle/textHandle.py | 50 +++++++++++- main/xiaozhi-server/core/websocket_server.py | 78 ++++++++++++++++++- 3 files changed, 126 insertions(+), 72 deletions(-) diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 6b503b66..ac22c272 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -53,9 +53,9 @@ class ConnectionHandler: server=None, ): self.config = config - self.server = server self.logger = setup_logging() self.auth = AuthMiddleware(config) + self.server = server # 保存server实例的引用 self.need_bind = False self.bind_code = None @@ -233,74 +233,6 @@ class ConnectionHandler: elif isinstance(message, bytes): await handleAudioMessage(self, message) - async def handle_config_update(self, message): - """处理配置更新请求""" - content = message.get("content", {}) - new_config = content - - # 遍历所有支持的配置模块 - updated_modules = [] - for config_model in ["tts", "llm", "vad", "asr", "memory", "intent"]: - if config_model not in new_config: - continue - - new_content = new_config[config_model] - old_content = self.config.get(config_model, {}) - - # 记录配置变更 - self.logger.bind(tag=TAG).info( - f"配置更新: {config_model} 旧值: {json.dumps(old_content, ensure_ascii=False)} " - f"新值: {json.dumps(new_content, ensure_ascii=False)}" - ) - - # 深度合并配置 - if isinstance(old_content, dict) and isinstance(new_content, dict): - merged = {**old_content, **new_content} - self.config[config_model] = merged - else: - self.config[config_model] = new_content - - # 标记需要重新初始化的模块 - if config_model in ["llm", "tts", "asr", "vad", "intent", "memory"]: - updated_modules.append(config_model) - - # 同步更新 WebSocketServer 的配置 - if self.server: - async with self.server.config_lock: # 使用锁确保线程安全 - for config_model in updated_modules: - self.server.config[config_model].update(new_config[config_model]) - - # 批量初始化模块 - if updated_modules: - try: - self._initialize_components(self.config) - self.logger.bind(tag=TAG).info( - f"已重新初始化模块: {', '.join(updated_modules)}" - ) - except Exception as e: - self.logger.bind(tag=TAG).error(f"模块初始化失败: {str(e)}") - await self.websocket.send( - json.dumps( - { - "type": "config_update_response", - "status": "error", - "message": f"模块初始化失败: {str(e)}", - } - ) - ) - return - - # 返回成功响应 - await self.websocket.send( - json.dumps( - { - "type": "config_update_response", - "status": "success", - "message": f"已更新配置: {', '.join(updated_modules)}", - } - ) - ) - def _initialize_components(self, private_config): """初始化组件""" if private_config is not None: diff --git a/main/xiaozhi-server/core/handle/textHandle.py b/main/xiaozhi-server/core/handle/textHandle.py index d350f78c..0bded15b 100644 --- a/main/xiaozhi-server/core/handle/textHandle.py +++ b/main/xiaozhi-server/core/handle/textHandle.py @@ -80,7 +80,7 @@ async def handleTextMessage(conn, message): await conn.websocket.send( json.dumps( { - "type": "config_update_response", + "type": "server", "status": "error", "message": "服务器密钥验证失败", } @@ -89,6 +89,52 @@ async def handleTextMessage(conn, message): return # 动态更新配置 if msg_json["action"] == "update_config": - await conn.handle_config_update(msg_json) + try: + # 更新WebSocketServer的配置 + if not conn.server: + await conn.websocket.send( + json.dumps( + { + "type": "config_update_response", + "status": "error", + "message": "无法获取服务器实例", + } + ) + ) + return + + if not await conn.server.update_config(): + await conn.websocket.send( + json.dumps( + { + "type": "config_update_response", + "status": "error", + "message": "更新服务器配置失败", + } + ) + ) + return + + # 发送成功响应 + await conn.websocket.send( + json.dumps( + { + "type": "config_update_response", + "status": "success", + "message": "配置更新成功", + } + ) + ) + except Exception as e: + conn.logger.bind(tag=TAG).error(f"更新配置失败: {str(e)}") + await conn.websocket.send( + json.dumps( + { + "type": "config_update_response", + "status": "error", + "message": f"更新配置失败: {str(e)}", + } + ) + ) except json.JSONDecodeError: await conn.websocket.send(message) diff --git a/main/xiaozhi-server/core/websocket_server.py b/main/xiaozhi-server/core/websocket_server.py index 06f00594..9e84aaec 100644 --- a/main/xiaozhi-server/core/websocket_server.py +++ b/main/xiaozhi-server/core/websocket_server.py @@ -3,6 +3,7 @@ import websockets from config.logger import setup_logging from core.connection import ConnectionHandler from core.utils.util import initialize_modules +from config.config_loader import get_config_from_api TAG = __name__ @@ -51,7 +52,7 @@ class WebSocketServer: self._tts, self._memory, self._intent, - self, # 传入当前 WebSocketServer 实例 + self, # 传入server实例 ) self.active_connections.add(handler) try: @@ -67,3 +68,78 @@ class WebSocketServer: else: # 如果是普通 HTTP 请求,返回 "server is running" return websocket.respond(200, "Server is running\n") + + async def update_config(self) -> bool: + """更新服务器配置并重新初始化组件 + + Returns: + bool: 更新是否成功 + """ + try: + async with self.config_lock: + # 重新获取配置 + new_config = get_config_from_api(self.config) + if new_config is None: + self.logger.bind(tag=TAG).error("获取新配置失败") + return False + + # 检查 VAD 和 ASR 类型是否需要更新 + update_vad = False + update_asr = False + + # 获取当前和新的 VAD 类型 + current_vad_module = self.config["selected_module"]["VAD"] + new_vad_module = new_config["selected_module"]["VAD"] + current_vad_type = ( + current_vad_module + if "type" not in self.config["VAD"][current_vad_module] + else self.config["VAD"][current_vad_module]["type"] + ) + new_vad_type = ( + new_vad_module + if "type" not in new_config["VAD"][new_vad_module] + else new_config["VAD"][new_vad_module]["type"] + ) + update_vad = current_vad_type != new_vad_type + + # 获取当前和新的 ASR 类型 + current_asr_module = self.config["selected_module"]["ASR"] + new_asr_module = new_config["selected_module"]["ASR"] + current_asr_type = ( + current_asr_module + if "type" not in self.config["ASR"][current_asr_module] + else self.config["ASR"][current_asr_module]["type"] + ) + new_asr_type = ( + new_asr_module + if "type" not in new_config["ASR"][new_asr_module] + else new_config["ASR"][new_asr_module]["type"] + ) + update_asr = current_asr_type != new_asr_type + + # 更新配置 + self.config = new_config + # 重新初始化组件 + modules = initialize_modules( + self.logger, + new_config, + update_vad, + update_asr, + "LLM" in new_config["selected_module"], + "TTS" in new_config["selected_module"], + "Memory" in new_config["selected_module"], + "Intent" in new_config["selected_module"], + ) + + # 更新组件实例 + self._vad = modules["vad"] if "vad" in modules else None + self._asr = modules["asr"] if "asr" in modules else None + self._tts = modules["tts"] if "tts" in modules else None + self._llm = modules["llm"] if "llm" in modules else None + self._intent = modules["intent"] if "intent" in modules else None + self._memory = modules["memory"] if "memory" in modules else None + + return True + except Exception as e: + self.logger.bind(tag=TAG).error(f"更新服务器配置失败: {str(e)}") + return False