first commit

This commit is contained in:
douboer
2025-10-14 14:18:20 +08:00
commit d93bc02772
66 changed files with 21393 additions and 0 deletions

363
web/AUTO_RECONNECT_GUIDE.md Normal file
View 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
- ✅ 不影响性能(并行处理)
- ✅ 容错性好(单个失败不影响其他)
- ✅ 日志详细(方便调试)
现在请刷新页面测试自动重连功能!🚀