Files
plantai-desktop/server.js
T

55 lines
2.1 KiB
JavaScript
Raw Normal View History

// server.js —— 主进程内嵌的本地 HTTP 服务:
// 静态托管 renderer-dist(前端构建产物)+ 把 /api 反代到可配置后端。
// 仅监听 127.0.0.1,不做公网暴露。反代参数对齐 deploy/nginx/plantai.conf:
// SSE 流(问答/生信)不缓冲、长超时由后端自控,大文件上传不受限。
const path = require('path');
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
function createServer({ staticDir, backendUrl }) {
const app = express();
const proxy = createProxyMiddleware({
target: backendUrl,
changeOrigin: true,
ws: false,
xfwd: true,
// http-proxy 侧不设响应/套接字超时(SSE 看门狗 1200s / 上传 600s 由后端自断)
proxyTimeout: 0,
timeout: 0,
on: {
error: (err, req, res) => {
// 后端不可达时返回结构化 502 信封(对齐前端 http.js 的错误契约),避免进程崩溃。
// 注意:http-proxy 的 error 事件里 res 可能是 net.Socket(连接失败),需防御式判断。
if (!res || typeof res.writeHead !== 'function') return;
if (res.headersSent) return res.end();
res.writeHead(502, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(
JSON.stringify({
ok: false,
error: { code: 'NETWORK', message: '后端不可达', degraded: false },
})
);
},
},
});
// 只代理 /api,并保留完整路径(/api/xxx → backend/api/xxx)。
// 注意:不能写成 app.use('/api', proxy) —— Express 会剥掉 /api 前缀,导致后端收到 /xxx 而 404。
app.use((req, res, next) => {
if (req.path.startsWith('/api')) return proxy(req, res, next);
next();
});
// 静态托管 + SPA fallback(前端无 vue-router,单页;仍兜底到 index.html)
app.use(express.static(staticDir));
app.use((req, res, next) => {
if (req.method !== 'GET' || req.path.startsWith('/api')) return next();
res.sendFile(path.join(staticDir, 'index.html'));
});
return app;
}
module.exports = { createServer };