rollback service.js

This commit is contained in:
jxxghp
2025-07-08 22:17:00 +08:00
parent a6847f7f53
commit f2bc832aca

View File

@@ -1,7 +1,6 @@
const path = require('node:path')
const express = require('express')
const proxy = require('express-http-proxy')
const { createProxyMiddleware } = require('http-proxy-middleware')
const app = express()
const port = process.env.NGINX_PORT || 3000
@@ -15,141 +14,16 @@ const proxyConfig = {
// 静态文件服务目录
app.use(express.static(__dirname))
// 创建专门的SSE代理中间件
const sseProxyMiddleware = createProxyMiddleware({
target: `http://${proxyConfig.URL}:${proxyConfig.PORT}`,
changeOrigin: true,
ws: false,
timeout: 0, // 无超时
proxyTimeout: 0, // 无超时
headers: {
'Connection': 'keep-alive',
'Cache-Control': 'no-cache'
},
onProxyRes: (proxyRes, req, res) => {
// 检测SSE响应
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);
// 处理客户端断开连接
req.on('close', () => {
console.log('Client disconnected from SSE stream');
if (proxyRes.destroy) {
proxyRes.destroy();
}
});
// 处理代理响应结束
proxyRes.on('end', () => {
console.log('SSE stream ended');
if (!res.headersSent) {
res.end();
}
});
// 处理代理响应错误
proxyRes.on('error', (err) => {
console.error('SSE proxy response error:', err);
if (!res.headersSent) {
res.status(500).end();
}
});
// 配置代理中间件将请求转发给后端API
app.use(
'/api',
proxy(`${proxyConfig.URL}:${proxyConfig.PORT}`, {
// 路径加上 /api 前缀
proxyReqPathResolver: (req) => {
return `/api${req.url}`
}
},
onError: (err, req, res) => {
console.error('SSE proxy error:', err);
if (!res.headersSent) {
res.status(500).json({ error: 'Proxy error' });
}
}
});
// 创建普通API代理中间件
const apiProxyMiddleware = proxy(`${proxyConfig.URL}:${proxyConfig.PORT}`, {
// 路径加上 /api 前缀
proxyReqPathResolver: (req) => {
return `/api${req.url}`
},
proxyReqOptDecorator: (proxyReqOpts, srcReq) => {
proxyReqOpts.headers = proxyReqOpts.headers || {};
// 检测是否为SSE请求
const isSSE = srcReq.headers.accept && srcReq.headers.accept.includes('text/event-stream');
if (!isSSE) {
// 普通请求设置超时
proxyReqOpts.timeout = 600000; // 600秒超时
}
return proxyReqOpts;
},
userResDecorator: (proxyRes, proxyResData, userReq, userRes) => {
// 只处理非SSE响应
const isSSEResponse = proxyRes.headers['content-type'] &&
proxyRes.headers['content-type'].includes('text/event-stream');
if (!isSSEResponse) {
// 普通响应:正常处理
return proxyResData;
}
// SSE响应不在这里处理已经由专门的中间件处理
return proxyResData;
},
// 错误处理
proxyErrorHandler: (err, res, next) => {
// 客户端断开连接的正常情况
if (err.code === 'ECONNRESET' || err.code === 'EPIPE') {
console.log('Client disconnected:', err.code);
if (!res.headersSent) {
res.end();
}
return;
}
// 超时错误处理
if (err.code === 'ETIMEDOUT') {
console.log('Proxy request timed out:', err.code);
if (!res.headersSent) {
res.status(504).send('Gateway Timeout');
}
return;
}
// 其他错误
console.error('Proxy error:', err);
if (!res.headersSent) {
res.status(500).send('Internal Server Error');
}
}
});
// 配置API代理路由
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);
}
});
})
);
// 配置代理中间件将CookieCloud请求转发给后端API
app.use(