Spaces:
Running
Running
File size: 5,264 Bytes
146bdba |
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 |
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { createLogger } from './utils/logger.js';
import { config, validateConfig } from './config/index.js';
import { notionClient } from './services/NotionClient.js';
import { streamManager } from './services/StreamManager.js';
import { proxyPool } from './ProxyPool.js';
import { proxyServer } from './ProxyServer.js';
import { requestLogger, errorHandler, requestLimits } from './middleware/auth.js';
import apiRouter from './routes/api.js';
// 获取当前目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const logger = createLogger('App');
/**
* 应用程序类
* 负责初始化和管理整个应用
*/
class Application {
constructor() {
this.app = express();
this.server = null;
}
/**
* 配置Express中间件
*/
configureMiddleware() {
// 请求体解析
this.app.use(express.json(requestLimits.json));
this.app.use(express.urlencoded(requestLimits.urlencoded));
// 静态文件服务
const publicPath = join(dirname(__dirname), 'public');
this.app.use(express.static(publicPath));
// 管理界面路由
this.app.get('/admin', (req, res) => {
res.sendFile(join(publicPath, 'admin.html'));
});
// 请求日志
this.app.use(requestLogger);
// API路由
this.app.use(apiRouter);
// 错误处理(必须放在最后)
this.app.use(errorHandler);
}
/**
* 初始化服务
*/
async initializeServices() {
// 验证配置
const configErrors = validateConfig();
if (configErrors.length > 0) {
throw new Error(`配置错误:\n${configErrors.join('\n')}`);
}
// 初始化代理服务器
if (config.proxy.enableServer) {
try {
await proxyServer.start();
logger.success('代理服务器启动成功');
} catch (error) {
logger.error(`启动代理服务器失败: ${error.message}`);
// 代理服务器启动失败不应该阻止应用启动
}
}
// 初始化Notion客户端
await notionClient.initialize();
// 初始化代理池
if (config.proxy.useNativePool) {
logger.info('正在初始化本地代理池...');
proxyPool.logLevel = 'info';
proxyPool.showProgressBar = true;
proxyPool.setCountry(config.proxy.country);
await proxyPool.initialize();
logger.success(`代理池初始化完成,当前代理国家: ${proxyPool.proxyCountry}`);
}
}
/**
* 启动应用
*/
async start() {
try {
// 初始化服务
await this.initializeServices();
// 配置中间件
this.configureMiddleware();
// 启动服务器
this.server = this.app.listen(config.server.port, () => {
logger.info(`服务已启动 - 端口: ${config.server.port}`);
logger.info(`访问地址: http://localhost:${config.server.port}`);
logger.info(`管理界面: http://localhost:${config.server.port}/admin`);
const status = notionClient.getStatus();
if (status.initialized) {
logger.success('系统初始化状态: ✅');
logger.success(`可用cookie数量: ${status.validCookies}`);
} else {
logger.warning('系统初始化状态: ❌');
logger.warning('警告: 系统未成功初始化,API调用将无法正常工作');
logger.warning('请检查NOTION_COOKIE配置是否有效');
}
});
} catch (error) {
logger.error(`应用启动失败: ${error.message}`, error);
process.exit(1);
}
}
/**
* 优雅关闭应用
*/
async shutdown() {
logger.info('正在关闭应用...');
// 关闭所有活跃流
streamManager.closeAll();
// 关闭代理服务器
if (proxyServer) {
try {
proxyServer.stop();
logger.info('代理服务器已关闭');
} catch (error) {
logger.error(`关闭代理服务器时出错: ${error.message}`);
}
}
// 关闭Express服务器
if (this.server) {
await new Promise((resolve) => {
this.server.close(resolve);
});
logger.info('HTTP服务器已关闭');
}
logger.success('应用已优雅关闭');
}
}
// 创建应用实例
const application = new Application();
// 注册进程信号处理
process.on('SIGINT', handleShutdown);
process.on('SIGTERM', handleShutdown);
process.on('SIGQUIT', handleShutdown);
async function handleShutdown(signal) {
logger.info(`收到${signal}信号,正在关闭应用...`);
await application.shutdown();
process.exit(0);
}
// 处理未捕获的异常
process.on('uncaughtException', (error) => {
logger.error('未捕获的异常:', error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
logger.error('未处理的Promise拒绝:', reason);
process.exit(1);
});
application.start();
export { application };
|