const express = require('express'); const cors = require('cors'); const helmet = require('helmet'); const compression = require('compression'); require('dotenv').config(); const logger = require('./utils/logger'); const sequelize = require('./config/database'); const routes = require('./api/routes'); const Scheduler = require('./core/scheduler'); const MultiSubscriptionManager = require('./core/multiSubscriptionManager'); const BotManager = require('./core/botManager'); const app = express(); const PORT = process.env.PORT || 3000; // 中间件 app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net"], scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net"], scriptSrcAttr: ["'unsafe-inline'"], fontSrc: ["'self'", "https://cdn.jsdelivr.net", "data:"], imgSrc: ["'self'", "data:", "https:"], mediaSrc: ["'self'", "data:"], connectSrc: ["'self'"], frameSrc: ["'none'"], objectSrc: ["'none'"], upgradeInsecureRequests: [] } } })); app.use(compression()); app.use(cors()); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); // 静态文件服务 app.use(express.static('public')); // 请求日志中间件 - 只记录重要请求 app.use((req, res, next) => { // 只记录重要的API请求,不记录频繁的自动刷新请求 if (req.path.startsWith('/api/') && !req.path.includes('/favicon') && !req.path.includes('/sw.js') && !req.path.includes('/stats') && !req.path.includes('/test/results')) { logger.info(`${req.method} ${req.path}`); } next(); }); // API路由 app.use('/api', routes); // 健康检查 app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString(), uptime: process.uptime() }); }); // 根路径 app.get('/', (req, res) => { res.json({ name: 'Clash Speed Test', version: '1.0.0', description: 'Clash节点测速工具,支持定时监控和Telegram通知', endpoints: { health: '/health', api: '/api' } }); }); // 错误处理中间件 app.use((err, req, res, next) => { logger.error('未处理的错误', { error: err.message, stack: err.stack, path: req.path, method: req.method }); res.status(500).json({ success: false, error: process.env.NODE_ENV === 'production' ? '服务器内部错误' : err.message }); }); // 404处理 app.use('*', (req, res) => { res.status(404).json({ success: false, error: '接口不存在' }); }); // 处理未捕获的Promise拒绝 process.on('unhandledRejection', (reason, promise) => { logger.error('未处理的Promise拒绝', { reason: { code: reason.code, message: reason.message }, promise: { isFulfilled: promise.isFulfilled, isRejected: promise.isRejected, rejectionReason: promise.rejectionReason } }); }); // 启动应用 async function startApp() { try { // 测试数据库连接 await sequelize.authenticate(); logger.info('数据库连接成功'); // 同步数据库模型 await sequelize.sync({ alter: true }); logger.info('数据库模型同步完成'); // 启动调度器 const scheduler = new Scheduler(); scheduler.start(); app.set('scheduler', scheduler); // 启动多订阅管理器 const subscriptionManager = new MultiSubscriptionManager(); subscriptionManager.startAutoUpdate(); // 设置测速触发器 subscriptionManager.setSpeedTestTrigger(() => { scheduler.runSpeedTest().catch(error => { logger.error('订阅更新后自动测速失败', { error: error.message }); }); }); app.set('subscriptionManager', subscriptionManager); // 启动Telegram机器人管理器 const botManager = new BotManager(); app.set('botManager', botManager); // 检查是否启用启动时立即测速 const enableStartupSpeedTest = process.env.ENABLE_SCHEDULED_SPEED_TEST !== 'false'; if (enableStartupSpeedTest) { // 立即开始测速 setTimeout(async () => { try { logger.info('应用启动后立即开始测速'); await scheduler.runSpeedTest(); } catch (error) { logger.error('启动测速失败', { error: error.message }); } }, 3000); // 延迟3秒开始,确保应用完全启动 } else { logger.info('启动时立即测速功能已禁用'); } // 启动服务器 app.listen(PORT, () => { logger.info(`服务器启动成功,端口: ${PORT}`); logger.info(`前端界面: http://localhost:${PORT}`); }); } catch (error) { logger.error('应用启动失败', { error: error.message }); process.exit(1); } } // 优雅关闭 process.on('SIGTERM', async () => { logger.info('收到SIGTERM信号,开始优雅关闭'); const scheduler = app.get('scheduler'); if (scheduler) { scheduler.stop(); } const subscriptionManager = app.get('subscriptionManager'); if (subscriptionManager) { subscriptionManager.stopAutoUpdate(); } const botManager = app.get('botManager'); if (botManager) { botManager.stop(); } await sequelize.close(); logger.info('应用已关闭'); process.exit(0); }); process.on('SIGINT', async () => { logger.info('收到SIGINT信号,开始优雅关闭'); const scheduler = app.get('scheduler'); if (scheduler) { scheduler.stop(); } const subscriptionManager = app.get('subscriptionManager'); if (subscriptionManager) { subscriptionManager.stopAutoUpdate(); } const botManager = app.get('botManager'); if (botManager) { botManager.stop(); } await sequelize.close(); logger.info('应用已关闭'); process.exit(0); }); // 未捕获的异常处理 process.on('uncaughtException', (error) => { logger.error('未捕获的异常', { error: error.message, stack: error.stack }); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { logger.error('未处理的Promise拒绝', { reason, promise }); process.exit(1); }); // 启动应用 startApp();