Files
autoclip/docs/WEBSOCKET_FIXES_SUMMARY.md

4.3 KiB
Raw Blame History

WebSocket问题修复总结

问题分析

根据日志分析,发现了三个主要问题:

  1. 自动断开重连每10秒左右就有断开重连说明缺少心跳机制
  2. 重复日志每10秒出现"新增0移除0未变8"的重复日志
  3. 进度跳跃前端从0%直接跳到100%,缺少快照机制

修复方案

1. 修复WebSocket自动断开重连问题

问题根因:缺少心跳机制,代理/浏览器在10~60s内回收"静默连接"

解决方案

  • 前端每25秒发送一次ping心跳
  • 后端收到ping后立即回复pong
  • 前端5秒内没收到pong就主动重连
  • 添加指数退避重连机制

修改文件

  • frontend/src/hooks/useWebSocket.ts:添加心跳机制和重连逻辑

2. 修复重复日志问题

问题根因前端频繁调用syncSubscriptions后端每次都记录INFO日志

解决方案

  • 前端添加300ms防抖机制
  • 后端只在有实际变化时才记录INFO日志
  • 无变化的同步降为DEBUG级别

修改文件

  • frontend/src/hooks/useWebSocket.ts:添加防抖机制
  • backend/services/websocket_gateway_service.py:优化日志级别

3. 实现进度快照机制

问题根因前端错过中间的WebSocket推送缺少"最新快照/补发机制"

解决方案

  • 后端每次发布进度时同时保存快照到Redis Hash
  • 用户订阅时立即发送最新快照
  • 快照标记为snapshot: true,前端可识别

修改文件

  • backend/services/progress_event_service.py:添加快照存储和获取
  • backend/services/websocket_gateway_service.py:订阅时发送快照

4. 修复asyncio.run()错误

问题根因:在已运行的事件循环中调用asyncio.run()

解决方案

  • 使用asyncio.get_running_loop()create_task()
  • 避免在async上下文中创建新的事件循环

修改文件

  • backend/api/v1/bilibili.py:修复事件循环冲突

5. 优化WebSocket发送机制

问题根因:直接调用websocket.send_text()可能导致close后send错误

解决方案

  • 所有消息发送都通过队列机制
  • 避免在连接关闭后发送消息

修改文件

  • backend/core/websocket_manager.py:统一使用队列发送

技术细节

心跳机制实现

// 前端心跳
const HEARTBEAT_INTERVAL = 25000; // 25秒
const HEARTBEAT_TIMEOUT = 5000;   // 5秒超时

// 发送ping
globalWs.send(JSON.stringify({ type: 'ping' }));

// 处理pong
if (data.type === 'pong') {
  clearTimeout(heartbeatTimeout);
}

快照机制实现

# 发布进度时保存快照
snapshot_key = f"progress:last:{channel}"
await redis_client.hset(snapshot_key, mapping=filtered_dict)

# 订阅时发送快照
snapshot = await progress_event_service.get_task_snapshot(task_id)
if snapshot:
    snapshot_message = {**snapshot, "snapshot": True}
    await manager.send_personal_message(snapshot_message, user_id)

防抖机制实现

// 300ms防抖
if (syncDebounceTimeout) {
  clearTimeout(syncDebounceTimeout);
}
syncDebounceTimeout = window.setTimeout(() => {
  // 发送同步请求
}, SYNC_DEBOUNCE_DELAY);

测试验证

创建了完整的测试脚本验证修复效果:

  • Redis连接测试
  • 进度快照测试
  • WebSocket网关测试

所有测试通过,修复效果良好。

预期效果

修复后应该实现:

  1. 稳定的WebSocket连接:不再频繁断开重连
  2. 清晰的日志输出:减少重复日志,只在有变化时记录
  3. 平滑的进度显示前端能立即看到最新进度不会从0%直接跳到100%
  4. 稳定的系统运行不再出现asyncio事件循环错误
  5. 可靠的消息传递避免close后send的错误

使用建议

  1. 监控日志:观察是否还有频繁的断开重连
  2. 测试进度:启动一个处理任务,观察前端进度是否平滑显示
  3. 检查快照:刷新页面后应该立即显示最新进度
  4. 验证心跳在浏览器开发者工具中可以看到ping/pong消息

后续优化

  1. Redis Stream可考虑使用Redis Stream实现更完整的消息历史
  2. 连接池优化Redis连接管理
  3. 监控指标添加WebSocket连接数和消息统计
  4. 错误恢复:增强网络异常时的自动恢复能力