61 lines
2.0 KiB
JavaScript
61 lines
2.0 KiB
JavaScript
import { spawn } from 'node:child_process'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const serverDir = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
export function startQuicServer({ onEvent } = {}) {
|
|
if (process.env.QUIC_ENABLED === 'false') return null
|
|
|
|
const script = path.join(serverDir, 'quic', 'server.py')
|
|
const python = process.env.QUIC_PYTHON || (process.platform === 'win32' ? 'py' : 'python3')
|
|
const args = process.platform === 'win32' && !process.env.QUIC_PYTHON
|
|
? ['-3', script]
|
|
: [script]
|
|
|
|
const child = spawn(python, args, {
|
|
cwd: path.resolve(serverDir, '..'),
|
|
env: {
|
|
...process.env,
|
|
QUIC_HOST: process.env.QUIC_HOST || '0.0.0.0',
|
|
QUIC_PORT: process.env.QUIC_PORT || '5175',
|
|
QUIC_CERT_FILE: process.env.QUIC_CERT_FILE || path.join(serverDir, 'certs', 'quic-gateway.crt'),
|
|
QUIC_KEY_FILE: process.env.QUIC_KEY_FILE || path.join(serverDir, 'certs', 'quic-gateway.key')
|
|
},
|
|
stdio: ['ignore', 'pipe', 'pipe']
|
|
})
|
|
|
|
child.stdout.setEncoding('utf8')
|
|
child.stderr.setEncoding('utf8')
|
|
let stdoutBuffer = ''
|
|
child.stdout.on('data', data => {
|
|
stdoutBuffer += data
|
|
const lines = stdoutBuffer.split(/\r?\n/)
|
|
stdoutBuffer = lines.pop() || ''
|
|
for (const line of lines) {
|
|
if (!line) continue
|
|
console.log(line)
|
|
try {
|
|
onEvent?.(JSON.parse(line))
|
|
} catch {
|
|
// Keep non-JSON Python diagnostics visible without feeding the registry.
|
|
}
|
|
}
|
|
})
|
|
child.stderr.on('data', data => process.stderr.write(data))
|
|
child.on('error', error => console.error('[quic] 无法启动 Python 服务:', error.message))
|
|
child.on('exit', (code, signal) => {
|
|
if (code !== 0 && signal !== 'SIGTERM') {
|
|
console.error(`[quic] 服务异常退出 (code=${code}, signal=${signal || 'none'})`)
|
|
}
|
|
})
|
|
|
|
const stop = () => {
|
|
if (!child.killed) child.kill()
|
|
}
|
|
process.once('SIGINT', stop)
|
|
process.once('SIGTERM', stop)
|
|
process.once('exit', stop)
|
|
return child
|
|
}
|