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

364 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🔄 自动重连功能说明
## 功能描述
页面刷新后,自动重新连接之前已连接的 MCP 服务器。
## 工作原理
### 1. 保存连接状态
当你连接或断开服务器时,连接状态会自动保存到浏览器的 `localStorage` 中。
### 2. 页面加载时
1.`localStorage` 加载服务器配置
2. 检查哪些服务器之前是"已连接"状态
3. 自动尝试重新连接这些服务器
### 3. 重连过程
```
页面刷新
loadServers() - 加载配置,所有服务器状态设为 'disconnected'
MCPSettings 组件挂载
autoReconnect() - 自动重连
检查 localStorage 中哪些服务器之前是 'connected'
并行重连所有这些服务器
成功:服务器状态变为 'connected'
失败:服务器保持 'disconnected'
```
## 代码实现
### 1. Store 中的自动重连函数
**文件**: `web/src/stores/newServer.ts`
```typescript
// 自动重连之前已连接的服务器
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`
```typescript
// 组件挂载时自动重连之前已连接的服务器
onMounted(async () => {
console.log('🚀 MCPSettings 组件已挂载,开始自动重连...')
try {
await serverStore.autoReconnect()
} catch (error) {
console.error('自动重连失败:', error)
}
})
```
### 3. 加载服务器时的处理
```typescript
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` 钩子:
```typescript
// 注释掉这段代码即可禁用自动重连
/*
onMounted(async () => {
console.log('🚀 MCPSettings 组件已挂载,开始自动重连...')
try {
await serverStore.autoReconnect()
} catch (error) {
console.error('自动重连失败:', error)
}
})
*/
```
### 手动触发重连
你也可以在需要时手动调用:
```typescript
// 在组件中
const reconnect = async () => {
await serverStore.autoReconnect()
}
// 在模板中
<n-button @click="reconnect">重新连接所有服务器</n-button>
```
## 优势
### ✅ 用户体验提升
- 刷新页面后无需手动重新连接
- 自动恢复之前的工作状态
- 减少重复操作
### ✅ 可靠性
- 使用 `Promise.allSettled()` 确保所有重连尝试都完成
- 单个服务器失败不影响其他服务器
- 详细的错误日志方便调试
### ✅ 性能
- 并行重连多个服务器
- 不阻塞页面渲染
- 异步执行,不影响用户操作
## 限制
### ⚠️ 实际连接仍会断开
- 页面刷新会断开 WebSocket/HTTP 连接
- 即使显示"已连接",也需要重新建立连接
- 自动重连是重新创建连接,不是恢复旧连接
### ⚠️ 依赖服务器可用性
- 如果 MCP 服务器未运行,自动重连会失败
- 网络问题会导致重连失败
- 用户需要确保 MCP 服务器在运行
### ⚠️ 不会保存会话状态
- 不保存之前的工具调用历史
- 不保存资源读取状态
- 只恢复连接,不恢复会话数据
## 测试步骤
### 1. 准备环境
```bash
# 启动 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 中是否保存了服务器配置?
**解决方案**:
```javascript
// 在控制台检查 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 问题?
**解决方案**:
```bash
# 测试 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
- ✅ 不影响性能(并行处理)
- ✅ 容错性好(单个失败不影响其他)
- ✅ 日志详细(方便调试)
现在请刷新页面测试自动重连功能!🚀