请选择 进入手机版 | 继续访问电脑版
设为首页 收藏本站

QQ登录

只需一步,快速开始

扫一扫,访问微社区

微信扫一扫 分享朋友圈

已有 11827 人浏览分享

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

[复制链接]
  • TA的每日心情
    开心
    2021-4-10 11:31
  • 2

    主题

    5

    帖子

    109

    积分

    注册会员

    Rank: 2

    积分
    109
    发表于 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上报数据:


    MQTT.fx模拟异常的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报文数据包


    数据:
    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消息数据包内容。


    数据:
    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);
    复制代码

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-4-10 11:31
  • 2

    主题

    5

    帖子

    109

    积分

    注册会员

    Rank: 2

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

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

    答:已经解决了。哈哈!
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    3

    帖子

    26

    积分

    新手上路

    Rank: 1

    积分
    26
    发表于 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

    回复

    使用道具 举报

    该用户从未签到

    3

    主题

    35

    帖子

    582

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    582
    发表于 2021-3-25 08:58:57 | 显示全部楼层
    666
    回复

    使用道具 举报

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

    本版积分规则

    0

    关注

    1

    粉丝

    2

    主题

    安信可开源团队    

    GMT+8, 2023-6-3 02:24 , Processed in 0.025945 second(s), 21 queries , Redis On.

    Powered by Discuz! X3.3 Licensed

    © 2001-2020 Comsenz Inc.