chenyc
2026-03-22 7885cede659f3255be56f77c1eef2ada7387d6f1
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
// 整个网关程序的入口文件
// 负责:
// 1)初始化各个核心模块(缓存、限流、物模型映射、MQTT、阿里云等);
// 2)创建 TCP Socket 服务,用于接收透析机数据;
// 3)创建 HTTP 服务,对外提供查询与运维接口;
// 4)统一处理优雅关闭逻辑(Ctrl+C / 进程退出信号)。
 
const logger = require("./logger");
const config = require("./config");
const DataCache = require("./dataCache");
const RateLimiter = require("./rateLimiter");
const PropertyMapper = require("./propertyMapper");
const createMqttClient = require("./mqttClient");
const createAliyunManager = require("./aliyunClient");
const createTcpServer = require("./tcpServer");
const createHttpServer = require("./httpServer");
 
function main() {
  // 进程级兜底:记录未捕获异常,避免因为单点问题导致静默退出
  process.on("uncaughtException", (err) => {
    logger.error("uncaughtException", err && (err.stack || err.message || err));
  });
  process.on("unhandledRejection", (reason) => {
    logger.error("unhandledRejection", reason && (reason.stack || reason.message || reason));
  });
 
  // 启动日志,方便从日志文件中定位一次完整的运行周期
  logger.info("Starting SWS Communication Gateway...");
 
  // 初始化核心业务模块
  // dataCache:按设备号缓存“最新一帧”透析机数据
  // rateLimiter:HTTP 接口访问限流
  // propertyMapper:协议字段到物模型属性的映射
  const dataCache = new DataCache();
  const rateLimiter = new RateLimiter();
  const propertyMapper = new PropertyMapper();
 
  // 创建 MQTT 客户端(可通过配置开启/关闭)
  // publishDeviceData:对外暴露的简单发布函数
  const { client: mqttClient, publishDeviceData } = createMqttClient();
 
  // 启动时输出阿里云传输开关状态,便于现场快速确认配置是否生效
  if (config.aliyun && config.aliyun.enabled) {
    logger.info("Aliyun IoT transfer enabled", {
      baseURL: config.aliyun.baseURL
    });
  } else {
    logger.info("Aliyun IoT transfer disabled by config");
  }
 
  // 阿里云物联网对接管理器
  // 封装:根据设备号自动获取三元组、建立连接,并在收到数据时上报属性
  const aliyunManager = createAliyunManager({ propertyMapper });
 
  // 创建 TCP Socket 服务器
  // - dataCache:在 onFrameParsed 时写入最新一帧数据
  // - mqttPublisher:可选,解析成功后往 MQTT 推送
  // - aliyunReporter:可选,解析成功后上报阿里云物联网
  const { server: tcpServer, deviceManager } = createTcpServer({
    dataCache,
    mqttPublisher: config.mqtt && config.mqtt.enabled ? publishDeviceData : null,
    aliyunReporter:
      config.aliyun && config.aliyun.enabled
        ? (deviceNumber, data) => aliyunManager.reportDeviceData(deviceNumber, data)
        : null
  });
 
  // 创建 HTTP 服务,对外提供数据查询与运维接口
  const httpServer = createHttpServer({
    dataCache,
    rateLimiter,
    propertyMapper,
    deviceManager
  });
 
  // 统一的优雅退出逻辑:
  // - 关闭 TCP / HTTP 监听
  // - 断开 MQTT / 阿里云连接
  // - 最后退出进程
  function shutdown() {
    logger.warn("Shutting down gateway...");
    try {
      if (tcpServer) tcpServer.close();
    } catch (e) {}
    try {
      if (httpServer) httpServer.close();
    } catch (e) {}
    try {
      if (mqttClient) mqttClient.end(true);
    } catch (e) {}
    try {
      if (aliyunManager && typeof aliyunManager.closeAll === "function") {
        aliyunManager.closeAll();
      }
    } catch (e) {}
    process.exit(0);
  }
 
  // 进程信号监听:在 Ctrl+C 或系统退出时触发优雅关闭
  process.on("SIGINT", shutdown);
  process.on("SIGTERM", shutdown);
}
 
// 直接启动主函数
main();