使用qmqtt连接ONENet的MQTT服务端失败的解决方法

编译环境

问题背景

使用Qt结合第三方MQTT客户端库(emqx/qmqtt)编写MQTT客户端,使用该客户端连接部署于OneNet平台的MQTT服务端时,出现了连接失败的问题。连接客户端所使用的代码如下:

QMQTT::Client *m_client = new QMQTT::Client(QHostAddress(address), port);
m_client->setClientId(client_id);
m_client->setUsername(usrname);
m_client->setPassword(password);
m_client->setKeepAlive(60);
m_client->connectToHost();

问题定位与解决

遇到上述问题后,分别做了如下测试:

  • 通过第三方MQTT客户端MQTT X访问OneNet平台的目标MQTT服务端 ---- PASS
  • 通过qmqtt客户端访问虚拟机内的mosquitto服务端 ---- PASS
  • 绑定qmqtt库的error(QMQTT::ClientError)信号,打印qmqtt库的报错 ---- QMQTT::SocketUnsupportedSocketOperationError
  • 改用Qt官方的MQTT库连接OneNet平台的目标MQTT服务端 ---- FAIL
  • 通过wireshark在客户端尝试连接服务端时进行抓包 ---- 没有捕获到相关数据

通过上述测试,可以发现在客户端尝试连接时,没有向服务端发送相关请求,所以问题可能是客户端的网络部分存在问题,检查了qmake.pro文件已经配置了QT += network后,仍存在该问题,最后在Qt官方论坛中找到了类似问题的解决方法:QTcpSocket/QMQTT - Strange Error Codes,在这篇帖子的回复中给出了解决方法:禁用代理服务器或在代码的开头部分加上:

/* call before connecting to network. Easiest way is, just call somewhere at the beginning of the program */
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);

进行了相应的修改后(顺便把我的v2ray关掉…),再次进行尝试,还是连接不上OneNet的MQTT服务端,重新进行以下测试:

  • 绑定qmqtt库的error(QMQTT::ClientError)信号,打印qmqtt库的报错 ---- QMQTT::MqttUnacceptableProtocolVersionError
  • 改用Qt官方的MQTT库连接OneNet平台的目标MQTT服务端 ---- PASS
  • 通过wireshark在客户端尝试连接服务端时进行抓包 ---- 捕获到了相关请求报文

可以发现相比之前的结果,有了巨大的进展,如果不是实在无聊出于好奇心,我甚至可以直接用Qt官方的MQTT库进行该应用的开发,通过将qmqtt库连接OneNet失败的抓包记录与MQTT X连接OneNet成功的抓包记录进行对比,可以发现在向服务端发送连接的请求中,qmqtt库发送的一段报文数据为“MQIsdp”,而MQTT X发送的该段报文数据为“MQTT”。

在这里插入图片描述

经过参考相关资料可知:“MQIsdp”为MQTT3.1.0的CONNECT消息中的可变头部协议名称,在MQTT3.1.1版本中,该字段被修改为“MQTT”。所以尝试在原来qmqtt库的客户端配置中加入:

//使用V3.1.1的MQTT版本的客户端
m_client->setVersion(QMQTT::MQTTVersion::V3_1_1);

加入这行配置后再次进行测试,可以成功连接到OneNet平台的MQTT服务端。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 要连接OneNet MQTT,您需要使用ESP8266的MQTT库,并在代码中设置正确的OneNet MQTT服务器地址和端口。您还需要在OneNet平台上创建一个设备,并获取设备的API密钥。然后,您可以使用ESP8266的MQTT库将设备连接OneNet MQTT服务器,并使用API密钥进行身份验证。一旦连接成功,您可以使用MQTT协议发布和订阅OneNet平台上的数据。 ### 回答2: ESP8266是一款广泛使用的物联网芯片,它能够通过Wi-Fi实现与云端数据交换、控制等功能。而OneNet是其中一款常用的云平台,也支持MQTT协议,可用于连接ESP8266。 要连接ESP8266和OneNet MQTT,需要以下步骤: 1. 注册OneNet账户并创建设备和数据流 先在OneNet平台注册账户并新建设备,为该设备添加数据流。每个数据流都有自己的Topic,后面需要用到。同时,该设备要能够接收和发送MQTT消息。 2. 安装MQTT库和ESP8266库 要连接ESP8266和OneNet MQTT,需要使用MQTT库和ESP8266库。其中MQTT库可以通过Arduino IDE中的库管理器下载,而ESP8266库需要手动下载并导入IDE中。 3. 编写代码 在Arduino IDE中编写代码,包括导入库、定义Wi-Fi接入点、MQTT连接信息等,最后通过mqttClient.publish方法发布消息。 4. 部署代码 将编写好的代码上传到ESP8266开发板,通过串口或OTA方式部署即可。 以上就是连接ESP8266和OneNet MQTT的步骤。需要注意的是,连接过程中可能会遇到一些问题,比如Wi-Fi连接MQTT认证等问题。这时可以参考OneNet平台提供的开发文档,或者在论坛上寻求帮助。同时,建议将消息结构化,以方便在OneNet平台上展示和处理。 ### 回答3: ESP8266是一种高度集成的Wi-Fi芯片,可以方便地连接到云平台,例如OneNetOneNet是一个基于云平台的物联网综合服务平台,提供物联网数据的连接、存储、管理和应用等多项服务,为IoT应用提供最全面的技术支持和服务。 MQTT(Message Queuing Telemetry Transport)是一种基于轻量级的发布订阅消息传送协议。在ESP8266中,我们可以使用MQTT异步通信协议进行与OneNet连接和通信。 在进行ESP8266连接OneNet MQTT之前,我们需要先在OneNet平台上创建我们的设备以及设备所需的数据流,以便后续ESP8266连接OneNet MQTT以及进行数据传输。同时,在网页端可得到我们设备的ID、APIkey等认证信息。 接下来,我们需要在ESP8266上安装MQTT库和WiFi连接库,并编写代码实现ESP8266与OneNet MQTT连接和数据传输过程。 下面是一个ESP8266连接OneNet MQTT的示例代码: #include <ESP8266WiFi.h> #include <PubSubClient.h> // WiFi认证信息 const char* ssid = "your_wifi_ssid"; const char* password = "your_wifi_password"; // OneNet认证信息 const char* mqtt_server = "mqtt.heclouds.com"; const int mqtt_port = 6002; const char* mqtt_user = "your_mqtt_username"; const char* mqtt_password = "your_mqtt_password"; const char* pub_topic = "your_device_topic"; IPAddress server(183, 230, 40, 39); // OneNet服务器IP地址 WiFiClient espClient; PubSubClient mqtt_client(espClient); void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); Serial.begin(115200); WiFi.begin(ssid, password); Serial.println(); Serial.print("Connecting"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("WiFi connected. IP address: "); Serial.println(WiFi.localIP()); mqtt_client.setServer(server, mqtt_port); mqtt_client.setCallback(callback); } void loop() { if (!mqtt_client.connected()) { Serial.print("Attempting MQTT connection..."); if (mqtt_client.connect("ESP8266Client", mqtt_user, mqtt_password)) { Serial.println("connected"); mqtt_client.subscribe(pub_topic); } else { Serial.print("failed, rc="); Serial.print(mqtt_client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } mqtt_client.loop(); } void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); if (strcmp(topic,pub_topic)==0) { if ((char)payload[0] == '1') { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } } } 以上是一个简单的ESP8266连接OneNet MQTT的实现步骤和示例代码供参考。在实际应用中,还需要根据需求进行调整以及安全性的考虑,例如加入SSL加密传输等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值