#!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('myself-project-nodejs:server'); var http = require('http'); require('dotenv').config(); /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * Create HTTP server. */ var server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ const { grb2DownloadManager } = require("../schema/downloadGrib2"); const { getGrib2FileUrl } = require("../schema/getGrb2FileUrl"); async function initDownloadManager() { global.downloadManager = { manager: new grb2DownloadManager(), getGrib2FileUrl, downloadTimmer: null, downloadTimmerInterval: 3600 }; // console.log("气象文件下载器已初始化完成...随项目初次启动默认执行一次下载任务..."); const downloader = global.downloadManager.manager; // 监听事件 downloader.on(downloader.EVENTS.STATUS_CHANGE, (status) => { console.log('状态变更:', status); }); downloader.on(downloader.EVENTS.TASK_ADDED, (task) => { console.log('任务已添加:', task.fileName); }); downloader.on(downloader.EVENTS.TASK_START, (task) => { console.log('任务开始:', task.fileName); }); // downloader.on(downloader.EVENTS.TASK_PROGRESS, (progress) => { // console.log(`下载进度: ${progress.task.fileName} - ${progress.percent.toFixed(2)}%`); // }); downloader.on(downloader.EVENTS.TASK_COMPLETE, (task) => { console.log('任务完成:', task.fileName); }); downloader.on(downloader.EVENTS.TASK_SKIP, (task, reason) => { console.log('任务跳过:', task.fileName, '-', reason); }); downloader.on(downloader.EVENTS.TASK_ERROR, (task, error) => { console.log('任务错误:', task.fileName, '-', error.message); }); downloader.on(downloader.EVENTS.QUEUE_EMPTY, () => { console.log('队列已空'); }); downloader.on(downloader.EVENTS.ALL_COMPLETE, (result) => { console.log('所有任务完成'); console.log('成功:', result.completed.length); console.log('失败:', result.failed.length); }); startDownload(); console.log(`已启动自动化下载计时器,${formatTime(global.downloadManager.downloadTimmerInterval)}后将再次自动下载气象模型`); global.downloadManager.downloadTimmer = setInterval(() => { startDownload(); }, global.downloadManager.downloadTimmerInterval * 1000) } // https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_1p00.pl?dir=/gfs.20250909/00/atmos&file=gfs.t00z.pgrb2.1p00.f003&all_var=on&all_lev=on&toplat=90&leftlon=0&rightlon=360&bottomlat=-90 async function startDownload() { const urls = await global.downloadManager.getGrib2FileUrl(); global.downloadManager.manager.addTasks(urls); global.downloadManager.manager.start(); } function formatTime(seconds) { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; let str = ``; if (hours > 0) { str += `${hours}小时`; } if (minutes > 0) { str += `${hours > 0 ? (minutes < 0 ? "0" + minutes : minutes) : minutes}分` } if (minutes > 0 || secs > 0) { str += `${minutes > 0 ? (secs < 0 ? "0" + secs : secs) : secs}秒` } return str; } server.listen(port, () => { console.log("api server running at http://127.0.0.1:" + port) // initDownloadManager(); }); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); }