// 配置文件:默认配置 + 同级目录 ../config.json 覆盖
|
// 这样打包成可执行文件 / APK 时,只需修改外部 JSON 即可调整参数。
|
|
const fs = require("fs");
|
const path = require("path");
|
|
const defaultConfig = {
|
log: {
|
// 是否写入本地日志文件
|
toFile: true,
|
// 日志目录(相对本项目根目录)
|
dir: "../logs",
|
// 预留日志级别控制(当前未严格使用)
|
level: "debug"
|
},
|
tcp: {
|
host: "0.0.0.0",
|
// 为避免本机已有程序占用,测试阶段改用 19000 端口
|
port: 19000,
|
idleTimeoutMs: 2 * 60 * 1000, // 设备超时时间 2 分钟
|
// 单连接缓冲区上限,防止异常数据导致内存持续增长
|
maxBufferBytes: 1024 * 1024,
|
// 每次 data 事件最多解析帧数,避免单连接长时间占用事件循环
|
maxFramesPerChunk: 50,
|
// TCP 最大并发连接数(覆盖 50 台透析机场景并保留余量)
|
maxConnections: 200
|
},
|
http: {
|
enabled: false,
|
host: "0.0.0.0",
|
// HTTP 服务测试端口改为 19001
|
port: 19001,
|
cors: {
|
enabled: true,
|
origins: ["*"]
|
},
|
rateLimit: {
|
singleDeviceMs: 5000,
|
allDevicesMs: 60 * 1000
|
}
|
},
|
mqtt: {
|
enabled: false,
|
url: "mqtt.ihemodialysis.com",
|
port: 62283,
|
username: "data",
|
password: "data#2018",
|
reconnectPeriod: 5000,
|
defaultTopicPrefix: "touxiji",
|
// 是否对每台机的最后一条消息做 retain,方便后续订阅方随时获取最新快照
|
retain: true
|
},
|
aliyun: {
|
enabled: true,
|
// 旧项目中三元组接口的基础地址,如需更换请修改此处
|
baseURL: "https://things.icoldchain.cn/",
|
// 其他阿里云物联网接入参数可在此扩展
|
}
|
};
|
|
// 递归浅合并:以 external 为准覆盖 default
|
function mergeConfig(defaultCfg, externalCfg) {
|
if (!externalCfg || typeof externalCfg !== "object") return defaultCfg;
|
const result = { ...defaultCfg };
|
for (const key of Object.keys(externalCfg)) {
|
const val = externalCfg[key];
|
if (
|
val &&
|
typeof val === "object" &&
|
!Array.isArray(val) &&
|
typeof defaultCfg[key] === "object" &&
|
defaultCfg[key] !== null
|
) {
|
result[key] = mergeConfig(defaultCfg[key], val);
|
} else {
|
result[key] = val;
|
}
|
}
|
return result;
|
}
|
|
// 运行根目录:
|
// - 普通 Node 环境下:项目根目录;
|
// - 使用 pkg 打包后:可执行文件所在目录。
|
const appRoot = (function () {
|
if (process.pkg) {
|
// pkg 打包后的场景
|
return path.dirname(process.execPath);
|
}
|
// 开发环境:src 目录的上一级
|
return path.resolve(__dirname, "..");
|
})();
|
|
let externalConfig = {};
|
try {
|
const jsonPath = path.join(appRoot, "config.json");
|
if (fs.existsSync(jsonPath)) {
|
const raw = fs.readFileSync(jsonPath, "utf8");
|
externalConfig = JSON.parse(raw);
|
}
|
} catch (e) {
|
// 如果 JSON 解析失败,直接忽略,继续使用默认配置
|
}
|
|
module.exports = mergeConfig(defaultConfig, externalConfig);
|