From 71ab7523da8b221a94f16dcf14838aca2b03cb9c Mon Sep 17 00:00:00 2001 From: hypercross Date: Wed, 18 Mar 2026 15:22:44 +0800 Subject: [PATCH] fix: shutdown --- src/cli/commands/mcp.ts | 60 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/cli/commands/mcp.ts b/src/cli/commands/mcp.ts index c03a9d7..16c081c 100644 --- a/src/cli/commands/mcp.ts +++ b/src/cli/commands/mcp.ts @@ -471,17 +471,63 @@ async function mcpServeAction(host: string, options: MCPOptions) { await server.connect(transport); console.error('TTRPG 卡牌生成 MCP 服务器已启动(stdio)'); - // 监听进程退出事件,关闭服务器 - process.on('SIGINT', () => { + // 清理函数 + let isShuttingDown = false; + async function shutdown() { + if (isShuttingDown) return; + isShuttingDown = true; + console.error('\n正在关闭服务器...'); + + try { + // 先关闭服务器,这会触发 transport 的关闭 + await server.close(); + console.error('MCP 服务器已关闭'); + } catch (e) { + console.error('关闭 MCP 服务器时出错:', e); + } + + try { + // 确保 transport 被关闭 + await transport.close(); + console.error('MCP Transport 已关闭'); + } catch (e) { + console.error('关闭 MCP Transport 时出错:', e); + } + + try { + // 关闭内容服务器 + contentServer.close(); + console.error('内容服务器已关闭'); + } catch (e) { + console.error('关闭内容服务器时出错:', e); + } + + // 给异步清理一些时间 + setTimeout(() => { + process.exit(0); + }, 100); + } + + // 监听进程退出事件 + process.on('SIGINT', () => shutdown()); + process.on('SIGTERM', () => shutdown()); + + // Windows 上 Ctrl+C 会触发 'SIGINT',但也监听 'exit' 事件作为后备 + process.on('exit', () => { contentServer.close(); - process.exit(0); }); - process.on('SIGTERM', () => { - console.error('\n正在关闭服务器...'); - contentServer.close(); - process.exit(0); + // 监听 stdin 结束事件(当客户端关闭连接时) + process.stdin.on('end', () => { + console.error('客户端已断开连接,正在关闭...'); + shutdown(); + }); + + // 监听 stdin 关闭事件 + process.stdin.on('close', () => { + console.error('stdin 已关闭,正在关闭服务器...'); + shutdown(); }); } else { // TODO: 支持 HTTP 传输