#include "spdlog/spdlog.h" #include "FromMQTT.h" #include "commonDefine.h" #include #include #include #include FromMQTT::FromMQTT(QObject* parent) { } FromMQTT::~FromMQTT() { } /* 传入MQTT地址和端口 */ void FromMQTT::setAddrInfo(const QString& ip, int port) { m_mqttIP = ip; m_mqttPort = port; m_isReadConfig.store(false); } /* 初始化MQTT */ bool FromMQTT::initMQTT() { if(m_isReadConfig.load()) { readConfig(); } /* 连接MQTT */ setIPAndPort(m_mqttIP, m_mqttPort); addSubcribe(m_topic_WebAPI, 0); // 订阅WebAPI主题 connectToServer(); /* 等待mqtt回复webapi信息(不阻塞UI,收到立即退出)*/ waitForWebInfo(m_timeOut); SPDLOG_INFO("WebAPI URL: {}", m_webAPIUrl.toStdString()); SPDLOG_INFO("WebAPI DBID: {}", m_webAPIID.toStdString()); if(m_webAPIUrl.isEmpty()) { SPDLOG_ERROR("接收MQTT消息超时,获取WebAPI信息失败"); return false; } /* 开启MQTT订阅 */ addSubcribe(m_topic_UpdatePlan); return true; } /* 读取配置文件 */ void FromMQTT::readConfig() { QString strConfigPath = QApplication::applicationDirPath() + m_configName; QSettings setting(strConfigPath, QSettings::IniFormat); setting.beginGroup("MQTTINFO"); m_mqttIP = setting.value("MQTTAddr", "").toString(); m_mqttPort = setting.value("MQTTPort", 1883).toInt(); m_timeOut = setting.value("MQTTTimeOut", 20000).toInt(); setting.endGroup(); } /* 接收到消息,子类继承这个解析消息数据 */ void FromMQTT::recvMessage(const QMQTT::Message& message) { SPDLOG_TRACE("接收到MQTT消息: {}", message.payload().toStdString()); QString payload = QString::fromUtf8(message.payload()); if(message.topic() == m_topic_WebAPI) { /* 处理WebAPI消息 */ try { nJson jsonMsg = nJson::parse(payload.toStdString()); m_webAPIUrl = jsonMsg["webaddr"].is_null() ? "" : jsonMsg["webaddr"].get().c_str(); m_webAPIID = jsonMsg["serverid"].is_null() ? "" : jsonMsg["serverid"].get().c_str(); m_isGetWebInfoSuccess.store(true); emit signal_webInfoReady(); // 通知等待逻辑退出 }nJsonCatchNoReturn SPDLOG_TRACE("WebAPI信息获取成功: URL = {}, ID = {}", m_webAPIUrl.toStdString(), m_webAPIID.toStdString()); } else if(message.topic() == m_topic_UpdatePlan) { /* 处理管理站消息 */ try { nJson jsonMsg = nJson::parse(payload.toStdString()); SPDLOG_INFO("MQTT接收到刷新报警时段消息"); emit signal_updatePlan(); }nJsonCatchNoReturn } } /* 等待WebAPI信息到达,使用事件循环+信号的方式,不阻塞主UI刷新 */ bool FromMQTT::waitForWebInfo(int timeoutMs) { if(m_isGetWebInfoSuccess.load()) return true; // 已经有了 QEventLoop loop; QTimer timer; timer.setSingleShot(true); if(timeoutMs > 0) { timer.start(timeoutMs); QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); } // 收到Web信息立即退出 QMetaObject::Connection c = QObject::connect(this, &FromMQTT::signal_webInfoReady, &loop, &QEventLoop::quit); loop.exec(); // 期间UI主事件循环仍可运行 QObject::disconnect(c); return m_isGetWebInfoSuccess.load(); }