Files
map-client-vue/web/AUTO_RECONNECT_GUIDE.md
2025-10-14 14:18:20 +08:00

10 KiB
Raw Blame History

🔄 自动重连功能说明

功能描述

页面刷新后,自动重新连接之前已连接的 MCP 服务器。

工作原理

1. 保存连接状态

当你连接或断开服务器时,连接状态会自动保存到浏览器的 localStorage 中。

2. 页面加载时

  1. localStorage 加载服务器配置
  2. 检查哪些服务器之前是"已连接"状态
  3. 自动尝试重新连接这些服务器

3. 重连过程

页面刷新
  ↓
loadServers() - 加载配置,所有服务器状态设为 'disconnected'
  ↓
MCPSettings 组件挂载
  ↓
autoReconnect() - 自动重连
  ↓
检查 localStorage 中哪些服务器之前是 'connected'
  ↓
并行重连所有这些服务器
  ↓
成功:服务器状态变为 'connected'
失败:服务器保持 'disconnected'

代码实现

1. Store 中的自动重连函数

文件: web/src/stores/newServer.ts

// 自动重连之前已连接的服务器
const autoReconnect = async () => {
  const stored = localStorage.getItem('mcp-servers')
  if (!stored) return
  
  try {
    const parsedServers = JSON.parse(stored) as MCPServerConfig[]
    const wasConnected = parsedServers.filter(s => s.status === 'connected')
    
    if (wasConnected.length > 0) {
      console.log(`🔄 发现 ${wasConnected.length} 个之前已连接的服务器,尝试自动重连...`)
      
      // 并行重连所有服务器
      const reconnectPromises = wasConnected.map(async (server) => {
        const currentServer = servers.value.find(s => s.id === server.id)
        if (currentServer) {
          try {
            console.log(`🔌 自动重连: ${server.name}`)
            await connectServer(server.id)
            console.log(`✅ 自动重连成功: ${server.name}`)
          } catch (err) {
            console.warn(`⚠️ 自动重连失败: ${server.name}`, err)
            // 失败了也不要抛出错误,继续尝试其他服务器
          }
        }
      })
      
      await Promise.allSettled(reconnectPromises)
      console.log(`✅ 自动重连完成`)
    }
  } catch (err) {
    console.error('自动重连失败:', err)
  }
}

2. 组件中调用自动重连

文件: web/src/components/MCPSettings.vue

// 组件挂载时自动重连之前已连接的服务器
onMounted(async () => {
  console.log('🚀 MCPSettings 组件已挂载,开始自动重连...')
  try {
    await serverStore.autoReconnect()
  } catch (error) {
    console.error('自动重连失败:', error)
  }
})

3. 加载服务器时的处理

const loadServers = () => {
  try {
    const stored = localStorage.getItem('mcp-servers')
    if (stored) {
      const parsedServers = JSON.parse(stored) as MCPServerConfig[]
      servers.value = parsedServers.map(server => ({
        ...server,
        // 保留之前的连接状态,但将 'connected' 改为 'disconnected'
        // 因为页面刷新后实际连接已断开
        status: server.status === 'connected' ? 'disconnected' : server.status,
        // 清除能力信息,因为连接已断开
        capabilities: undefined
      }))
      
      console.log(`📦 加载了 ${servers.value.length} 个服务器配置`)
    }
  } catch (err) {
    console.error('加载服务器配置失败:', err)
    error.value = '加载服务器配置失败'
  }
}

使用示例

场景:正常使用流程

  1. 首次连接服务器

    用户操作: 点击"连接"按钮
    结果: 服务器状态变为 'connected'
    存储: localStorage 保存 status: 'connected'
    
  2. 刷新页面

    加载阶段:
    - loadServers() 读取 localStorage
    - 发现服务器之前是 'connected'
    - 暂时设为 'disconnected'(因为连接已丢失)
    - 页面显示"未连接"状态
    
    挂载阶段:
    - MCPSettings 组件挂载
    - 调用 autoReconnect()
    - 检测到服务器之前已连接
    - 自动尝试重新连接
    
  3. 自动重连成功

    结果: 
    - 服务器状态变回 'connected'
    - 页面显示"已连接"状态
    - 绿色圆点显示
    - 工具列表恢复显示
    
  4. 自动重连失败

    原因: MCP 服务器未运行或网络问题
    结果:
    - 服务器保持 'disconnected' 状态
    - 控制台显示警告: ⚠️ 自动重连失败: xxx
    - 用户可以手动点击"连接"按钮重试
    

控制台日志

成功的自动重连

🚀 MCPSettings 组件已挂载,开始自动重连...
🔄 发现 2 个之前已连接的服务器,尝试自动重连...
🔌 自动重连: xhs-http
🔌 自动重连: test-sse-server
🔗 正在连接到 MCP 服务器: xhs-http (http://0.0.0.0:3100/mcp)
🔄 原始URL: http://0.0.0.0:3100/mcp
🔄 转换后URL: http://localhost:3100/mcp
✅ 成功连接到 MCP 服务器: xhs-http
✅ 自动重连成功: xhs-http
✅ 自动重连成功: test-sse-server
✅ 自动重连完成

部分失败的自动重连

🚀 MCPSettings 组件已挂载,开始自动重连...
🔄 发现 2 个之前已连接的服务器,尝试自动重连...
🔌 自动重连: xhs-http
🔌 自动重连: offline-server
✅ 自动重连成功: xhs-http
❌ 连接 MCP 服务器失败: offline-server
⚠️ 自动重连失败: offline-server Error: 网络连接失败
✅ 自动重连完成

配置选项

禁用自动重连(可选)

如果你不想要自动重连功能,可以注释掉 MCPSettings.vue 中的 onMounted 钩子:

// 注释掉这段代码即可禁用自动重连
/*
onMounted(async () => {
  console.log('🚀 MCPSettings 组件已挂载,开始自动重连...')
  try {
    await serverStore.autoReconnect()
  } catch (error) {
    console.error('自动重连失败:', error)
  }
})
*/

手动触发重连

你也可以在需要时手动调用:

// 在组件中
const reconnect = async () => {
  await serverStore.autoReconnect()
}

// 在模板中
<n-button @click="reconnect">重新连接所有服务器</n-button>

优势

用户体验提升

  • 刷新页面后无需手动重新连接
  • 自动恢复之前的工作状态
  • 减少重复操作

可靠性

  • 使用 Promise.allSettled() 确保所有重连尝试都完成
  • 单个服务器失败不影响其他服务器
  • 详细的错误日志方便调试

性能

  • 并行重连多个服务器
  • 不阻塞页面渲染
  • 异步执行,不影响用户操作

限制

⚠️ 实际连接仍会断开

  • 页面刷新会断开 WebSocket/HTTP 连接
  • 即使显示"已连接",也需要重新建立连接
  • 自动重连是重新创建连接,不是恢复旧连接

⚠️ 依赖服务器可用性

  • 如果 MCP 服务器未运行,自动重连会失败
  • 网络问题会导致重连失败
  • 用户需要确保 MCP 服务器在运行

⚠️ 不会保存会话状态

  • 不保存之前的工具调用历史
  • 不保存资源读取状态
  • 只恢复连接,不恢复会话数据

测试步骤

1. 准备环境

# 启动 MCP 服务器
cd /Users/gavin/xhs/mcp_client/xhsLoginMCP
node server.js

# 启动前端开发服务器
cd /Users/gavin/xhs/mcp_client/mcp-client-vue/web
npx vite

2. 连接服务器

  1. 访问 http://localhost:5175/(或当前端口)
  2. 找到服务器卡片
  3. 点击"连接"按钮
  4. 确认状态变为"已连接"

3. 刷新页面

  1. Cmd + R 或点击浏览器刷新按钮
  2. 打开控制台(Cmd + Option + I
  3. 观察自动重连日志

4. 验证结果

预期行为:

  • 页面加载时短暂显示"未连接"1-2秒
  • 自动开始重连(控制台显示日志)
  • 重连成功后状态变为"已连接"
  • 可以看到工具列表
  • 绿色圆点显示

如果 MCP 服务器未运行:

  • 自动重连失败
  • 控制台显示警告
  • 服务器保持"未连接"状态
  • 可以手动点击"连接"按钮重试

故障排查

Q1: 刷新后没有自动重连

检查:

  1. 控制台是否有 "🚀 MCPSettings 组件已挂载" 日志?
  2. 是否有 "🔄 发现 X 个之前已连接的服务器" 日志?
  3. localStorage 中是否保存了服务器配置?

解决方案:

// 在控制台检查 localStorage
const stored = localStorage.getItem('mcp-servers')
const servers = JSON.parse(stored)
console.log('保存的服务器:', servers)
console.log('之前已连接的:', servers.filter(s => s.status === 'connected'))

Q2: 自动重连一直失败

检查:

  1. MCP 服务器是否在运行?
  2. 端口是否正确?
  3. 是否有 CORS 问题?

解决方案:

# 测试 MCP 服务器
curl -X POST http://localhost:3100/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","clientInfo":{"name":"test","version":"1.0.0"}}}'

Q3: 部分服务器重连成功,部分失败

这是正常的!不同服务器可能有不同的可用性:

  • 检查失败服务器的错误日志
  • 确认失败的服务器是否在运行
  • 可以手动重试失败的服务器

未来改进

可能的功能增强

  1. 重连延迟配置: 允许用户设置自动重连的延迟时间
  2. 重连重试: 如果首次重连失败,自动重试几次
  3. 选择性重连: 允许用户选择哪些服务器需要自动重连
  4. 重连通知: 使用 toast 通知告知用户重连结果
  5. 状态指示器: 显示重连进度(重连中 X/Y

性能优化

  1. 智能重连: 只重连最近使用的服务器
  2. 延迟重连: 延迟几秒再重连,避免页面加载卡顿
  3. 优先级重连: 先重连重要的服务器

总结

自动重连功能显著改善了用户体验,特别是在开发和调试过程中频繁刷新页面时。通过保存连接状态并在页面加载时自动恢复,用户无需每次都手动重新连接服务器。

关键点:

  • 自动且透明
  • 可靠性高(使用 Promise.allSettled
  • 不影响性能(并行处理)
  • 容错性好(单个失败不影响其他)
  • 日志详细(方便调试)

现在请刷新页面测试自动重连功能!🚀