关于ESP8266使用mqtt发布信息给腾讯云问题及解决方案!

[复制链接]
查看15085 | 回复8 | 2021-3-1 20:59:22 | 显示全部楼层 |阅读模式
本帖最后由 Jack_tang 于 2021-3-5 11:20 编辑

最近在学习ESP8266的MQTT事,我通过MQTT连接到腾讯云MQTT服务器。现在ESP8266可以订阅并接收来自腾讯云MQTT的信息,但是在使用mqtt发布上报信息给腾讯云时出现了问题。
上报信息的JOSN格式:"{\"method\":\"report\",\"clientToken\":\"xxxxx-8gauvcWJrb\",\"params\":{\"switch_1\": 1}}"
但是腾讯云无法接收到完成的上报信息,因为我使用在线调试只能看到report_reply消息,但是无法查看到report消息。而我用MQTT.fx软件模拟时,当我只发送{"method": "report"}时会出现这样的现在。但是当我发送完整的JOSN上报信息时就不会只有report_reply消息。

MQTT.fx模拟正常的JOSN上报数据:
捕获.PNG

MQTT.fx模拟异常的JOSN上报数据:

异常JOSN数据

异常JOSN数据


目前ESP8266使用以下代码,将JOSN数据上报给腾讯云会出现和MQTT.fx模拟异常的JOSN上报数据现象。
  1. #define TEST_SW1_REPORT_OFF "{"method":"report","clientToken":"MBN7N5MMO8-8gauvcWJrb","params":{"switch_1": 0}}"
复制代码
  1. void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len)
  2. {
  3.     char *topicBuf = (char*)os_zalloc(topic_len+1),
  4.             *dataBuf = (char*)os_zalloc(data_len+1);

  5.     uint8_t res = 0;
  6.     static uint8_t flag = 0;

  7.     MQTT_Client* client = (MQTT_Client*)args;
  8. //===========如果数据接收出现丢失,应该使用环形缓冲区来保存没有来得及处理的数据================
  9.     os_memcpy(topicBuf, topic, topic_len);
  10.     topicBuf[topic_len] = 0;

  11.     os_memcpy(dataBuf, data, data_len);
  12.     dataBuf[data_len] = 0;

  13.     INFO("Receive topic: %s, data: %s \r\n", topicBuf, dataBuf);

  14.     //===解析JOSN数据====
  15.     res = Parse_Josn_data(dataBuf,&sw_status);
  16.     if(res == JOSN_OK)        //成功获取到腾讯云发的“智能插座”MQTT的JOSN并解析
  17.     {
  18.         //====执行命令========
  19.         smartSW_action.Control(sw_status);
  20.         if(flag == 1)
  21.         {
  22.                 flag = 0;
  23.                 MQTT_Publish(client, MQTT_UP_TOPIC, TEST_SW2_REPORT_OFF, os_strlen(TEST_SW2_REPORT_OFF) + 1, 0, 0);
  24.                 INFO("flag = 1\n");
  25.                 INFO(TEST_SW2_REPORT_OFF)
  26.                 INFO("\n");
  27.         }
  28.         else
  29.         {
  30.                 flag = 1;
  31.                 MQTT_Publish(client, MQTT_UP_TOPIC, TEST_SW2_REPORT_ON, os_strlen(TEST_SW2_REPORT_ON) + 1, 0, 0);
  32.                 INFO("flag = 0\n");
  33.                 INFO(TEST_SW2_REPORT_ON)
  34.                 INFO("\n");
  35.         }

  36.     }

  37.     os_free(topicBuf);
  38.     os_free(dataBuf);
  39. }
复制代码


解决方法及分析过程:
原因:多发了一个字节的00数据。其实就是在发送JOSN字符串时,考虑了字符串的结束标志'\0'

1. 通过WireShark抓包工具抓取MQTT的PUBLISH报文数据包

WireShark抓包PUBLISH消息

WireShark抓包PUBLISH消息


数据:
30 57 00 29 24 74 68 69 6e 67

2f 75 70 2f 70 72 6f 70 65 72 74 79 2f 4d 42 4e

37 4e 35 4d 4d 4f 38 2f 53 6d 61 72 74 5f 53 57

30 30 31 7b 22 6d 65 74 68 6f 64 22 3a 22 72 65

70 6f 72 74 22 2c 22 70 61 72 61 6d 73 22 3a 7b

22 73 77 69 74 63 68 5f 32 22 3a 20 30 7d 7d

2. 在ESP8266的SDK开发源代码中获取到的PUBLISH消息数据包内容。

串口打印PUBLISH消息

串口打印PUBLISH消息


数据:
30 58 00 29 24 74 68 69 6e 67 2f 75 70 2f 70 72 6f 70 65 72 74 79 2f 4d 42 4e 37 4e 35 4d 4d 4f 38 2f 53 6d 61 72 74 5f 53 57 30 30 31 7b 22 6d 65 74 68 6f 64 22 3a 22 72 65 70 6f 72 74 22 2c 22 70 61 72 61 6d 73 22 3a 7b 22 73 77 69 74 63 68 5f 32 22 3a 20 31 7d 7d 00

总结:
通过比较两个数据包的内容很容易发现,在串口输出的信息中多了一个字节的00数据。再结合ESP8266 SDK开发中的源代码,在调用MQTT_Publish()函数中发送的时多了一个字节(考虑到了字符串结束标志....)。

即将以下代码
  1. MQTT_Publish(client, MQTT_UP_TOPIC, TEST_SW2_REPORT_ON, os_strlen(TEST_SW2_REPORT_ON) + 1, 0, 0);
复制代码

修改为正确的代码
  1. MQTT_Publish(client, MQTT_UP_TOPIC, TEST_SW2_REPORT_ON,os_strlen(TEST_SW2_REPORT_ON),0,0);
复制代码

回复

使用道具 举报

Jack_tang | 2021-3-1 21:00:33 | 显示全部楼层
本帖最后由 Jack_tang 于 2021-3-5 11:19 编辑

大神帮忙看下,为什么会这样?MQTT发送report报文给腾讯服务器会收不到?
用的是ESP8266_NONOS_SDK-3.0.4下的mqtt例程。

答:已经解决了。哈哈!
回复 支持 反对

使用道具 举报

Kiwi2021 | 2021-3-19 14:05:22 | 显示全部楼层
最近在学习ESP8266的MQTT事,我通过MQTT连接到腾讯云MQTT服务器。现在ESP8266可以订阅并接收来自腾讯云MQTT的信息,但是在使用mqtt发布上报信息给腾讯云时出现了问题。
[天津快乐十分]https://www.1680380.com/view/klsf_tianjin/klsf_index.html
上报信息的JOSN格式:"{\"method\":\"report\",\"clientToken\":\"xxxxx-8gauvcWJrb\",\"params\":{\"switch_1\": 1}}"
但是腾讯云无法接收到完成的上报信息,因为我使用在线调试只能看到report_reply消息,但是无法查看到report消息。
[幸运飞艇]https://www.1680380.com/view/xingyft/pk10kai.html
而我用MQTT.fx软件模拟时,当我只发送{"method": "report"}时会出现这样的现在。但是当我发送完整的JOSN上报信息时就不会只有report_reply消息。
[福彩双色球]https://1680380.com/view/fcssq/index.html

回复 支持 反对

使用道具 举报

666
回复

使用道具 举报

王乐乐 | 2023-8-30 23:06:38 | 显示全部楼层
打卡e
回复

使用道具 举报

夜樱99 | 2023-9-2 21:33:59 | 显示全部楼层
小安派上腾讯云的帖子来一个?
回复 支持 反对

使用道具 举报

WangChong | 2023-9-18 23:54:16 | 显示全部楼层
学习
回复

使用道具 举报

496199544 | 2023-9-19 08:43:38 来自手机 | 显示全部楼层
学习
回复

使用道具 举报

AuroraTea | 2023-11-13 18:02:00 | 显示全部楼层
21年年初到23年年底到底发生了啥xs
回复 支持 反对

使用道具 举报

相遇不识君 | 2023-11-24 10:18:32 | 显示全部楼层
你token暴露了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则