1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
// run-gost.js const { spawn } = require('child_process'); const fs = require('fs'); const path = require('path');
const LOG_DIR = path.join(__dirname, 'logs'); if (!fs.existsSync(LOG_DIR)) fs.mkdirSync(LOG_DIR, { recursive: true });
const stdoutLog = fs.createWriteStream(path.join(LOG_DIR, 'gost.out.log'), { flags: 'a' }); const stderrLog = fs.createWriteStream(path.join(LOG_DIR, 'gost.err.log'), { flags: 'a' });
// 根据你的环境设置可执行文件路径: // - 如果 gost 位于当前目录且有可执行权限,用 './gost' // - 如果在 Windows,通常为 'gost.exe' const gostBinary = process.platform === 'win32' ? 'gost.exe' : './gost';
// 组装参数(与原命令一致) const args = [ '-D',
// '-L', 'ss://chacha20-ietf-poly1305:123456%[email protected]:2164' // '-L', 'ss+ws://chacha20-ietf-poly1305:123456%2A@:2164?path=/ws' '-L', 'socks5://:2164?udp=true&udpBufferSize=4096' ];
// 启动子进程 const gost = spawn(gostBinary, args, { cwd: __dirname, // 在当前目录运行,确保 ./gost 能被找到 stdio: ['ignore', 'pipe', 'pipe'], // 我们手动处理 stdout/stderr windowsHide: true });
// 打印启动信息 console.log(`[${new Date().toISOString()}] Starting gost: ${gostBinary} ${args.join(' ')}`);
// 处理输出:同时写入文件与控制台 gost.stdout.on('data', (data) => { const line = data.toString(); process.stdout.write(line); stdoutLog.write(`[${new Date().toISOString()}] ${line}`); });
gost.stderr.on('data', (data) => { const line = data.toString(); process.stderr.write(line); stderrLog.write(`[${new Date().toISOString()}] ${line}`); });
// 退出事件 gost.on('close', (code, signal) => { const msg = `[${new Date().toISOString()}] gost exited (code=${code}, signal=${signal})\n`; console.log(msg); stderrLog.write(msg); // 根据需要,决定是否自动重启 // restartGost(); });
// 错误事件(比如二进制不存在、权限不足) gost.on('error', (err) => { const msg = `[${new Date().toISOString()}] Failed to start gost: ${err.stack || err}\n`; console.error(msg); stderrLog.write(msg); });
// 可选:简单的自动重启逻辑 function restartGost(delayMs = 3000) { console.log(`[${new Date().toISOString()}] Restarting gost in ${delayMs}ms...`); setTimeout(() => { // 这里可以封装成函数重新 spawn // 为简洁起见,你也可以用 PM2 来管理重启,见下文 process.exit(1); // 让外部进程管理器(如 PM2)重启 }, delayMs); }
// 优雅退出:中断时关闭文件句柄与子进程 function shutdown() { try { gost.kill('SIGINT'); } catch {} stdoutLog.end(); stderrLog.end(); process.exit(0); }
process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown);
|