实战:软件架构网络系列之【物联网中MQTT协议报文序列化/ 载荷(Payload)设计】

 概叙

科普文:软件架构网络系列之【应用层协议:MQTT(消息队列遥测传输)详解】-CSDN博客

实战:软件架构网络系列之【 MQTT V3工具类:MqttClientV3Util】-CSDN博客

实战:软件架构网络系列之【 MQTT V5工具类:MqttClientV5Util】-CSDN博客

实战:软件架构网络系列之【 MQTT V5基础功能:MQTT 5.0 发布和订阅 】-CSDN博客

实战:软件架构网络系列之【 MQTT基层功能:发布/订阅】-CSDN博客

实战:软件架构网络系列之【 MQTT基础功能:MQTT over SSL/TLS 安全通信(安全传输)】-CSDN博客

实战:软件架构网络系列之【 MQTT基层功能:带遗嘱消息的智能家居温度传感器(可靠传输保障)】-CSDN博客

实战:软件架构网络系列之【MQTT基础功能:MQTT多主题订阅】-CSDN博客

实战:软件架构网络系列之【物联网中MQTT应用相关问题梳理】-CSDN博客

实战:软件架构网络系列之【物联网中MQTT协议报文设计梳理】-CSDN博客

摘要:MQTT协议是一种轻量级的发布/订阅消息传输协议,特别适合物联网(IoT)应用。

本文介绍了MQTT协议的核心特点、报文设计要点和不同序列化方案的对比。

MQTT协议具有低带宽、低功耗、低开销的优势,其报文设计需要考虑精简报头、主题设计、QoS级别选择等要素。

在载荷序列化方面,文章详细比较了JSON、CBOR、Protobuf和自定义字节码四种方案,分析了各自的优缺点和适用场景,并给出了具体实现示例。

文章还提供了MQTT在实际应用中的注意事项和优化建议,帮助开发者在物联网场景中合理选择和使用MQTT协议。

MQTT协议是一种轻量级的发布/订阅消息传输协议,非常适合物联网(IoT)应用,因为它具有低带宽、低功耗、低开销的特点。

MQTT 协议报文设计需紧密贴合物联网(IoT)场景的核心需求——低带宽、不稳定网络、海量设备连接、低功耗、实时性与可靠性平衡

设计符合物联网需求的MQTT协议报文时,应考虑报文结构、主题设计、QoS级别选择、遗嘱消息、保持连接、报文压缩与优化以及安全性等方面。通过合理设计MQTT协议报文,可以确保物联网应用的实时性、可靠性和安全性。

为了设计符合物联网需求的MQTT协议报文,需要考虑以下几个方面:

总结:符合物联网需求的 MQTT 报文设计要点

需求 MQTT 设计方案
低带宽 精简固定头部(2字节)、支持二进制/JSON 轻量化 Payload
不稳定网络 长连接+心跳(KeepAlive)、QoS 分级保障可靠性
海量设备 轻量级连接(低握手开销)、主题通配符简化订阅
低功耗 QoS 0 模式、离线队列减少重传
实时性 QoS 1/2 确保关键数据送达,短心跳间隔(如 30 秒)
安全性 TLS 加密、ACL 主题权限控制、设备级认证
可扩展性 MQTT 5.0 用户属性、共享订阅、消息过期等高级特性

通过以上设计,MQTT 协议能够高效支撑物联网场景中 传感器数据采集、设备远程控制、实时监控告警、大规模设备管理等核心需求,成为物联网通信的事实标准协议。

符合物联网需求的MQTT报文设计需遵循 “极简报头 + 智能主题 + QoS分级 + 安全扩展” 原则:

  1. 轻量化:固定报头≤2字节,可变长度编码适应不同负载。

  2. <
/* * 阿里云物联网平台连接管理函数 * 功能:实现WiFi连接、MQTT协议通信、消息处理、保活功能 */ void Aliyun_Iot(char *redata) { char qos, dup, retain; int id; char return_buff[RETURN_BUFF_SIZE]; int result; static IOT_state state = STATE_MQTT_CONNECT; // 状态 static int count; // 计数器 count++; printf("\n计数器 %d \n", count); switch (state) { case STATE_WIFI_CONNECT: // 连接WiFi printf("\n正在连接 WIFI \n"); if (0 == WIFI_Connect()) { TIM4_Init(10 - 1, 7200 - 1); // 启动重传队列 wifi_state = 1; state = STATE_MQTT_CONNECT; printf("\nWIFI 连接成功 \n"); printf("\n发送 MQTT 连接报文 \n"); } break; case STATE_MQTT_CONNECT: // 发送连接报文 if (0 == MQTT_Connect(clientid, // clientid username, // username password, // password WILL_TOPIC, // will_topic WILL_MESSAGE, // will_message USER_NAME_FLAG, // user_name_flag PASS_WORD_FLAG, // pass_word_flag WILL_RETAIN, // will_retain WILL_QOS, // will_qos WILL_FLAG, // will_flag CLEAN_SESSION, // clean_session KEEP_ALIVE)) // keep_alive { state = STATE_MQTT_CONNACK; printf("\n等待连接响应 \n"); } break; case STATE_MQTT_CONNACK: // 等待连接响应 if(TIME_OUT == count) // 超时返回上一个状态 count->1000ms, { state = STATE_MQTT_CONNECT; count = 0; break; } if (MQTT_ConnAck(redata) == 1) // 连接成功 { state = STATE_MQTT_SUBSCRIBE; printf("\n订阅主题 \n"); } break; case STATE_MQTT_SUBSCRIBE: // 发送订阅报文 if (0 == MQTT_Subscribe(SET_TOPIC, SUBSCRIBE_ID, 0, 1)) { count = 0; state = STATE_MQTT_SUBACK; // 转到消息接收状态 printf("\n等待订阅确认 \n"); } break; case STATE_MQTT_SUBACK: // 等待订阅确认 if(TIME_OUT == count) // 超时返回上一个状态 TIMx_count->1ms, { state = STATE_MQTT_CONNECT; count = 0; break; } if (1 == MQTT_SubAck(redata)) state = STATE_RECEIVE_MSG; // 转到消息接收状态 break; case STATE_RECEIVE_MSG: // 消息接收与处理 switch (redata[0] >> 4) { case 3: // 接收PUBLISH消息 if (MQTT_ReceivelPublish(&dup, &qos, &retain, &id, redata, return_buff, RETURN_BUFF_SIZE) == 0) { printf("\n* 解析 0x%02x 报文: dup = %d, qos = %d, retain = %d, id = %02X *\n", redata[0], dup, qos, retain, id); Iot_Control(return_buff); // 调用 Iot_Control 控制硬件 if (qos == 1) { MQTT_SendPubAck(id); // QoS1需要回复PubAck } else if (qos == 2) { MQTT_SendPubRec(id); // QoS2需要回复PubRec } // 收到消息时重置保活计数器并禁用保活发送 count = 0; // 重置计数器 } break; case 4: // 接收PUBACK消息 id = MQTT_ReceivePubAck(redata); if (id != 0) { remove_from_retry_list(id); // 移除重传链表中的QoS1报文 count = 0; // 重置计数器 } break; case 5: // 接收PUBREC消息 id = MQTT_ReceivePubRec(redata); if (id != 0) { remove_from_retry_list(id); // 移除重传链表中的QoS2报文 MQTT_SendPubRel(id); // 回复PUBREL count = 0; // 重置计数器 } break; case 6: // 接收PUBREL消息 id = MQTT_ReceivePubRel(redata); if (id != 0) { MQTT_SendPubComp(id); // 回复PUBCOMP count = 0; // 重置计数器 } break; case 7: // 接收PUBCOMP消息 id = MQTT_ReceivePubComp(redata); if (id != 0) { remove_from_retry_list(id); // 移除重传链表中的PUBREL报文 count = 0; // 重置计数器 } break; case 11: // 接收UNSUBACK消息 if (MQTT_UnSubAck(redata, SUBSCRIBE_ID) == 1) { state = STATE_KEEP_ALIVE; // 转到保活状态 } else { MQTT_Subscribe(SET_TOPIC, SUBSCRIBE_ID, 0, 0); // 重新尝试取消订阅 count = 0; // 重置计数器 } break; case 13: // 接收PINGRESP消息 if (MQTT_PingResp(redata) == 1) { printf("\n心跳响应已接收。正在重置保活计数器。\n"); count = 0; // 收到响应重置计数器 } break; case 14: // 断开连接 break; default: break; } break; case STATE_KEEP_ALIVE: // 保活状态 if(KEEP_ALIVE == count) { MQTT_PingREQ(); } break; default: break; } } /* */ 分析这段代码
最新发布
08-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

01Byte空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值