feat(0.2.1): 单端口生产架构 —— /sync 同域反代 (去掉 13002 独立同步端口), 新增 deploy/prod 生产编排
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
// PowerSync 同域反代 (0.2.1): 把 /sync、/socket 转发到内网同步服务,
|
||||
// 对外只暴露应用本身一个端口 (无需单独的 powersync 端口)。
|
||||
// - 未配置 POWERSYNC_UPSTREAM 时直接跳过 (本地开发/无同步服务时行为不变)
|
||||
// - 必须挂在 express.json()/cors 之前: 同步走长连接流式响应, 不能被 body 解析打断
|
||||
import http from 'node:http'
|
||||
import https from 'node:https'
|
||||
|
||||
const PREFIXES = ['/sync', '/socket']
|
||||
|
||||
export function powersyncProxy() {
|
||||
const upstream = process.env.POWERSYNC_UPSTREAM
|
||||
if (!upstream) return (_req, _res, next) => next()
|
||||
|
||||
let target
|
||||
try {
|
||||
target = new URL(upstream)
|
||||
} catch {
|
||||
console.error('[powersync-proxy] POWERSYNC_UPSTREAM 非法:', upstream)
|
||||
return (_req, _res, next) => next()
|
||||
}
|
||||
const transport = target.protocol === 'https:' ? https : http
|
||||
const basePort = Number(target.port) || (target.protocol === 'https:' ? 443 : 80)
|
||||
console.log('[powersync-proxy] 同步请求转发到', target.origin)
|
||||
|
||||
return (req, res, next) => {
|
||||
if (!PREFIXES.some((p) => req.url === p || req.url.startsWith(p + '/') || req.url.startsWith(p + '?'))) {
|
||||
return next()
|
||||
}
|
||||
const headers = { ...req.headers, host: target.host }
|
||||
const upstreamReq = transport.request(
|
||||
{
|
||||
protocol: target.protocol,
|
||||
hostname: target.hostname,
|
||||
port: basePort,
|
||||
method: req.method,
|
||||
path: req.url,
|
||||
headers,
|
||||
},
|
||||
(upstreamRes) => {
|
||||
res.writeHead(upstreamRes.statusCode || 502, upstreamRes.headers)
|
||||
upstreamRes.pipe(res)
|
||||
},
|
||||
)
|
||||
upstreamReq.on('error', (e) => {
|
||||
console.error('[powersync-proxy] 转发失败:', e.message)
|
||||
if (!res.headersSent) res.writeHead(502, { 'content-type': 'text/plain' })
|
||||
res.end('powersync upstream error')
|
||||
})
|
||||
// 长连接: 客户端断开时同步断开上游
|
||||
req.on('aborted', () => upstreamReq.destroy())
|
||||
res.on('close', () => upstreamReq.destroy())
|
||||
req.pipe(upstreamReq)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user