Files
MoviePilot-Frontend/SSE_修复报告.md
T

4.6 KiB

SSE (Server-Sent Events) 问题分析和修复报告

问题描述

用户反映使用新的 public/service.js 文件后,SSE (Server-Sent Events) 不能正常工作。

问题分析

通过对项目代码和最新SSE文档的研究,发现了以下问题:

1. 原始代码问题

原始的 express-http-proxy 配置在处理SSE流式传输时存在以下问题:

  • userResDecorator 中的SSE处理逻辑虽然返回了 false,但实际的流式传输机制不够完善
  • 缺乏正确的流管道设置
  • 错误处理不够健壮
  • 缺少专门的SSE代理中间件

2. SSE的技术要求

根据最新的SSE最佳实践,正确的SSE代理需要:

  • 设置正确的HTTP头部:Content-Type: text/event-stream
  • 保持持久连接:Connection: keep-alive
  • 禁用缓存:Cache-Control: no-cache
  • 正确处理流式传输,避免缓冲
  • 优雅处理客户端断开连接

修复方案

主要改进

  1. 引入专门的SSE代理中间件

    • 使用 http-proxy-middleware 包提供专门的SSE支持
    • 分离SSE请求和普通API请求的处理逻辑
  2. 改进的流式传输处理

    // 直接将代理响应流式传输到客户端
    proxyRes.pipe(res);
    
  3. 更好的连接管理

    • 正确处理客户端断开连接
    • 优雅的错误处理
    • 资源清理
  4. 双重代理架构

    • SSE请求使用专门的 createProxyMiddleware
    • 普通API请求继续使用 express-http-proxy

依赖更新

添加了新的依赖:

"http-proxy-middleware": "^3.0.0"

核心修改

  1. SSE检测和路由

    app.use('/api', (req, res, next) => {
      // 检测是否为SSE请求
      const isSSE = req.headers.accept && req.headers.accept.includes('text/event-stream');
    
      if (isSSE) {
        // 使用专门的SSE代理中间件
        sseProxyMiddleware(req, res, next);
      } else {
        // 使用普通API代理中间件
        apiProxyMiddleware(req, res, next);
      }
    });
    
  2. 专门的SSE代理中间件

    const sseProxyMiddleware = createProxyMiddleware({
      target: `http://${proxyConfig.URL}:${proxyConfig.PORT}`,
      changeOrigin: true,
      timeout: 0, // 无超时
      onProxyRes: (proxyRes, req, res) => {
        const isSSE = proxyRes.headers['content-type'] && 
                      proxyRes.headers['content-type'].includes('text/event-stream');
    
        if (isSSE) {
          // 设置正确的SSE响应头
          res.writeHead(proxyRes.statusCode, {
            'Content-Type': 'text/event-stream',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Headers': 'Cache-Control, Content-Type, Authorization'
          });
    
          // 直接流式传输
          proxyRes.pipe(res);
        }
      }
    });
    

实施步骤

  1. 更新 package.json 添加 http-proxy-middleware 依赖
  2. 运行 yarn install 安装新依赖
  3. 修改 public/service.js 实现新的SSE处理逻辑
  4. 🔄 测试SSE功能确保正常工作

受影响的功能

项目中使用SSE的功能包括:

  • 系统进度监控 (/api/system/progress/*)
  • 日志查看 (LoggingView.vue)
  • 消息通知 (MessageView.vue, UserNotification.vue)
  • 文件传输进度 (TransferQueueDialog.vue, ReorganizeDialog.vue)
  • 批量重命名进度 (FileList.vue)

验证方法

可以通过以下方式验证修复效果:

  1. 检查浏览器开发者工具中的Network面板
  2. 确认SSE请求显示为 text/event-stream 类型
  3. 验证数据是否实时流式传输
  4. 测试客户端断开连接后的清理工作

技术参考

本修复方案基于以下最新文档和最佳实践:

结论

通过引入专门的SSE代理中间件和改进的流式传输处理,应该能够解决用户反映的SSE不能正常工作的问题。新的架构更加符合SSE的技术要求,提供了更好的错误处理和连接管理。