first commit
This commit is contained in:
363
web/AUTO_RECONNECT_GUIDE.md
Normal file
363
web/AUTO_RECONNECT_GUIDE.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# 🔄 自动重连功能说明
|
||||
|
||||
## 功能描述
|
||||
|
||||
页面刷新后,自动重新连接之前已连接的 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)
|
||||
- ✅ 不影响性能(并行处理)
|
||||
- ✅ 容错性好(单个失败不影响其他)
|
||||
- ✅ 日志详细(方便调试)
|
||||
|
||||
现在请刷新页面测试自动重连功能!🚀
|
||||
Reference in New Issue
Block a user