Refactor SSE proxy middleware for improved event streaming support

Co-authored-by: jxxghp <jxxghp@163.com>
This commit is contained in:
Cursor Agent
2025-07-05 23:59:58 +00:00
parent 75252fded6
commit 723fa96519

View File

@@ -1,141 +0,0 @@
# 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. **改进的流式传输处理**
```javascript
// 直接将代理响应流式传输到客户端
proxyRes.pipe(res);
```
3. **更好的连接管理**
- 正确处理客户端断开连接
- 优雅的错误处理
- 资源清理
4. **双重代理架构**
- SSE请求使用专门的 `createProxyMiddleware`
- 普通API请求继续使用 `express-http-proxy`
### 依赖更新
添加了新的依赖:
```json
"http-proxy-middleware": "^3.0.0"
```
### 核心修改
1. **SSE检测和路由**
```javascript
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代理中间件**
```javascript
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. 测试客户端断开连接后的清理工作
## 技术参考
本修复方案基于以下最新文档和最佳实践:
- [Server-Sent Events: A Practical Guide for the Real World](https://tigerabrodi.blog/server-sent-events-a-practical-guide-for-the-real-world)
- [Building an SSE Proxy: Streaming and Forwarding Server-Sent Events](https://medium.com/@sercan.celenk/building-an-sse-proxy-in-go-streaming-and-forwarding-server-sent-events-1c951d3acd70)
- [How to Proxy and Modify OpenAI Stream Responses](https://medium.com/@TechTim42/how-to-proxy-and-modify-openai-stream-responses-for-enhanced-user-experience-82cb9ed29b46)
- [express-http-proxy SSE 最佳实践](https://tigerabrodi.blog/server-sent-events-a-practical-guide-for-the-real-world)
## 结论
通过引入专门的SSE代理中间件和改进的流式传输处理应该能够解决用户反映的SSE不能正常工作的问题。新的架构更加符合SSE的技术要求提供了更好的错误处理和连接管理。