mqttclient.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "mqttclient.h"
  2. #include <QJsonDocument>
  3. #include <QJsonObject>
  4. #include <QMessageBox>
  5. #include "../global.h"
  6. #include "../logger.h"
  7. MqttClient *MqttClient::instance = nullptr;
  8. MqttClient::MqttClient(QObject *parent) : QObject(parent), mqClient(new QMqttClient(this)) {
  9. // 连接信号和槽
  10. connect(mqClient, &QMqttClient::connected, this, &MqttClient::onConnected);
  11. // TODO: connect(mqClient, &QMqttClient::disconnected, this, &MqttClient::onDisconnected);
  12. connect(mqClient, &QMqttClient::stateChanged, this, &MqttClient::onStateChanged);
  13. connect(mqClient, &QMqttClient::errorChanged, this, &MqttClient::onError);
  14. connect(mqClient, &QMqttClient::messageReceived, this, &MqttClient::onMessageReceived);
  15. connect(mqClient, &QMqttClient::errorChanged, this, [this](QMqttClient::ClientError error) {
  16. Logger::getInstance().error(QString("MQTT client occured error: %1").arg(error));
  17. });
  18. }
  19. // 单例模式
  20. MqttClient *MqttClient::getInstance() {
  21. if (instance == nullptr) {
  22. instance = new MqttClient();
  23. }
  24. return instance;
  25. }
  26. MqttClient *MqttClient::createNewInstance() { return new MqttClient(); }
  27. void MqttClient::connectToMqttBroker() {
  28. mqClient->setHostname("114.55.233.194");
  29. mqClient->setPort(1883);
  30. mqClient->setKeepAlive(20);
  31. // // 设置账号和密码
  32. mqClient->setUsername("hxgc");
  33. mqClient->setPassword("hxgc123456");
  34. // 设置客户端 ID
  35. mqClient->setClientId("pc");
  36. mqClient->connectToHost();
  37. }
  38. void MqttClient::connectToMqttBroker(const QString &hostname, quint16 port, const QString &username,
  39. const QString &password, const QString &clientId,
  40. const QStringList &topicsToSubscribe) {
  41. mqClient->setHostname(hostname);
  42. mqClient->setPort(port);
  43. mqClient->setKeepAlive(20);
  44. // 设置账号和密码
  45. mqClient->setUsername(username);
  46. mqClient->setPassword(password);
  47. // 设置客户端 ID
  48. mqClient->setClientId(clientId);
  49. mqClient->connectToHost();
  50. // 保存要订阅的主题列表
  51. m_subscribeTopics = topicsToSubscribe;
  52. }
  53. void MqttClient::onConnected() {
  54. Logger::getInstance().debug("MQTT conncted");
  55. m_connectRetryCount = 0;
  56. subscribeToTopics(m_subscribeTopics);
  57. }
  58. void MqttClient::subscribeToTopics(const QStringList &topics) {
  59. for (const auto &topic : topics) {
  60. subscribeToTopic(topic);
  61. }
  62. }
  63. void MqttClient::disconnectFromMqttBroker() {
  64. Logger::getInstance().info("MQTT client disconnecting from broker" + mqClient->state());
  65. if (mqClient->state() == QMqttClient::Connected) {
  66. mqClient->disconnectFromHost();
  67. }
  68. }
  69. void MqttClient::subscribeToTopic(const QString &topic) { mqClient->subscribe(topic); }
  70. void MqttClient::sendMessage(const QString &topic, const QByteArray &message, quint8 qos, bool isRetainedMsg) {
  71. if (mqClient->state() == QMqttClient::Connected) {
  72. auto pub = mqClient->publish(QMqttTopicName(topic), message, qos, isRetainedMsg);
  73. if (pub == -1)
  74. Logger::getInstance().error(
  75. QString("MQTT client sent message to topic: %1, msg: %2, qos: %3, isRetainedMsg: %4")
  76. .arg(topic, QString(message), QString::number(qos), isRetainedMsg ? "true" : "false"));
  77. else
  78. Logger::getInstance().info(
  79. QString("MQTT client sent message to topic: %1, msg: %2, qos: %3, isRetainedMsg: %4")
  80. .arg(topic, QString(message), QString::number(qos), isRetainedMsg ? "true" : "false"));
  81. } else {
  82. qDebug() << "Not connected to MQTT server";
  83. Logger::getInstance().error(
  84. QString("MQTT client is not connected to the server. topic: %1, msg: %2").arg(topic, QString(message)));
  85. }
  86. }
  87. void MqttClient::onMessageReceived(const QByteArray &message, const QMqttTopicName &topic) {
  88. if (topic.name() == MQTT_TOPIC_COMPANY_PROJECTS) {
  89. emit proMessageReceived(message, topic);
  90. } else {
  91. emit messageReceived(message, topic);
  92. }
  93. }
  94. void MqttClient::onStateChanged(QMqttClient::ClientState state) {
  95. switch (state) {
  96. case QMqttClient::ClientState::Disconnected:
  97. m_connectRetryCount++;
  98. if (m_connectRetryCount < 3) {
  99. Logger::getInstance().info(QString("Mqtt reconnecting... (%1)").arg(m_connectRetryCount));
  100. connectToMqttBroker();
  101. } else {
  102. Logger::getInstance().error("Mqtt reconnect failed after 3 attempts");
  103. QMessageBox::warning(nullptr, "提示", "mqtt连接已断开,请重新登录");
  104. }
  105. break;
  106. case QMqttClient::ClientState::Connecting:
  107. qDebug() << "MQTT 客户端状态: 正在连接";
  108. break;
  109. case QMqttClient::ClientState::Connected:
  110. m_connectRetryCount = 0; // 重置连接重试计数
  111. qDebug() << "MQTT 客户端状态: 已连接";
  112. break;
  113. default:
  114. Logger::getInstance().info("Mqtt unkown state: " + QString::number(state));
  115. break;
  116. }
  117. }
  118. void MqttClient::onError(QMqttClient::ClientError error) {
  119. qDebug() << "MQTT 错误: " << error;
  120. Logger::getInstance().error(QString("MQTT client error: %1").arg(error));
  121. }