Spaces:
Paused
Paused
File size: 5,980 Bytes
8c0c410 15296c6 c058c1e 8c0c410 15296c6 8c0c410 |
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
import { spawn } from 'child_process';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import fs from 'fs';
import os from 'os';
import dotenv from 'dotenv';
import chalk from 'chalk';
// 获取当前文件的目录路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// 加载环境变量
dotenv.config({ path: join(dirname(__dirname), '.env') });
// 日志配置
const logger = {
info: (message) => console.log(chalk.blue(`[ProxyServer] ${message}`)),
error: (message) => console.error(chalk.red(`[ProxyServer] ${message}`)),
warning: (message) => console.warn(chalk.yellow(`[ProxyServer] ${message}`)),
success: (message) => console.log(chalk.green(`[ProxyServer] ${message}`)),
};
class ProxyServer {
constructor() {
this.proxyProcess = null;
this.platform = process.env.PROXY_SERVER_PLATFORM || 'auto';
this.port = process.env.PROXY_SERVER_PORT || 10655;
this.logPath = process.env.PROXY_SERVER_LOG_PATH || './proxy_server.log';
this.enabled = process.env.ENABLE_PROXY_SERVER === 'true';
this.proxyAuthToken = process.env.PROXY_AUTH_TOKEN || 'default_token';
this.logStream = null;
}
// 获取当前系统平台
detectPlatform() {
if (this.platform !== 'auto') {
return this.platform;
}
const platform = os.platform();
const arch = os.arch();
if (platform === 'win32') {
return 'windows';
} else if (platform === 'linux') {
if (arch === 'arm64') {
return 'android';
} else {
return 'linux';
}
} else if (platform === 'android') {
return 'android';
} else {
logger.warning(`未知平台: ${platform}, ${arch}, 默认使用linux版本`);
return 'linux';
}
}
// 获取代理服务器可执行文件路径
getProxyServerPath() {
const platform = this.detectPlatform();
const proxyDir = join(__dirname, 'proxy');
switch (platform) {
case 'windows':
return join(proxyDir, 'chrome_proxy_server_windows_amd64.exe');
case 'linux':
return join(proxyDir, 'chrome_proxy_server_linux_amd64');
case 'android':
return join(proxyDir, 'chrome_proxy_server_android_arm64');
default:
logger.error(`不支持的平台: ${platform}`);
return null;
}
}
// 启动代理服务器
async start() {
if (!this.enabled) {
logger.info('代理服务器未启用,跳过启动');
return;
}
if (this.proxyProcess) {
logger.warning('代理服务器已经在运行中');
return;
}
const proxyServerPath = this.getProxyServerPath();
if (!proxyServerPath) {
logger.error('无法获取代理服务器路径');
return;
}
try {
// 确保可执行文件有执行权限(在Linux/Android上)
if (this.detectPlatform() !== 'windows') {
try {
fs.chmodSync(proxyServerPath, 0o755);
} catch (err) {
logger.warning(`无法设置执行权限: ${err.message}`);
}
}
// 创建日志文件
this.logStream = fs.createWriteStream(this.logPath, { flags: 'a' });
// 修复 stdio 参数问题
// 启动代理服务器进程
this.proxyProcess = spawn(proxyServerPath, [
'--port', this.port.toString(),
'--token', this.proxyAuthToken
], {
stdio: ['ignore', 'pipe', 'pipe'], // 使用pipe而不是直接传递流
detached: false
});
// 将进程的输出重定向到日志文件
if (this.proxyProcess.stdout) {
this.proxyProcess.stdout.pipe(this.logStream);
}
if (this.proxyProcess.stderr) {
this.proxyProcess.stderr.pipe(this.logStream);
}
// 设置进程事件处理
this.proxyProcess.on('error', (err) => {
logger.error(`代理服务器启动失败: ${err.message}`);
this.proxyProcess = null;
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
});
this.proxyProcess.on('exit', (code, signal) => {
logger.info(`代理服务器已退出,退出码: ${code}, 信号: ${signal}`);
this.proxyProcess = null;
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
});
// 等待一段时间,确保服务器启动
await new Promise(resolve => setTimeout(resolve, 1000));
if (this.proxyProcess && this.proxyProcess.exitCode === null) {
logger.success(`代理服务器已启动,端口: ${this.port}, 日志文件: ${this.logPath}`);
return true;
} else {
logger.error('代理服务器启动失败');
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
return false;
}
} catch (error) {
logger.error(`启动代理服务器时出错: ${error.message}`);
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
return false;
}
}
// 停止代理服务器
stop() {
if (!this.proxyProcess) {
//logger.info('代理服务器已关闭');
return;
}
try {
// 在Windows上使用taskkill确保子进程也被终止
if (this.detectPlatform() === 'windows' && this.proxyProcess.pid) {
spawn('taskkill', ['/pid', this.proxyProcess.pid, '/f', '/t']);
} else {
// 在Linux/Android上使用kill信号
this.proxyProcess.kill('SIGTERM');
}
logger.success('代理服务器已停止');
} catch (error) {
logger.error(`停止代理服务器时出错: ${error.message}`);
} finally {
this.proxyProcess = null;
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
}
}
}
// 创建单例
const proxyServer = new ProxyServer();
// 导出
export { proxyServer }; |