使用阿里物模型深入解释MQTT原理

使用阿里物模型深入解释MQTT原理

定义

MQTT(Message Queuing Telemetry Transport)消息队列遥测传输协议是一种轻量级的基于发布/订阅模型的消息传输协议,主要用于物联网(IoT)环境中设备间的通信。它被设计为简单、开放、易于实现,并且可以支持低带宽、高延迟或不可靠的网络环境。

特点

MQTT 的主要特点包括:

  1. 轻量级:协议本身非常简洁,消息体小,适合在资源受限的设备上使用。
  2. 发布/订阅模型:消息的发布者(发布者)将消息发送到一个主题(Topic),而订阅者(Subscriber)订阅感兴趣的主题并接收相应的消息。
  3. 可靠传输:支持消息的可靠传输,确保消息在网络不稳定的情况下也能被正确传递。
  4. 低功耗:适合在电池供电的设备上使用,因为它可以快速进入低功耗模式。
  5. 安全性:支持多种安全机制,如TLS/SSL加密传输和用户认证。
  6. 高扩展
  7. 协议简单
  8. 双向通信

工作流程

MQTT 的工作流程:

  1. 连接:客户端首先与服务器建立连接。
  2. 订阅:客户端订阅一个或多个主题。
  3. 发布:客户端或服务器发布消息到一个主题。
  4. 接收:订阅者接收到订阅主题的消息。
  5. 断开连接:客户端完成通信后断开与服务器的连接。
  • 而在物联网的应用中,MQTT协议消息的具体传输过程,以业务服务器向设备下发消息为例:
  1. 设备订阅相应的主题(Topic)。
  2. 服务器发送消息给物联网平台。
  3. 物联网平台接收消息,根据消息的主题(Topic)确定设备并发送消息。
  4. 业务服务器收到物联网平台的消息,确认消息已成功发送。

具体内容

1. 协议基础

  • 协议版本:主要有两个版本,MQTT 3.1和MQTT 3.1.1。阿里物联网平台还用MQTT5.0。
  • 协议端口:默认使用1883端口(非加密)和8883端口(加密)。
  • MQTT客户端(Client)MQTT代理者(Broker)

MQTT客户端(Client):阿里物模型中的客户端(Client)指接入物联网平台的设备。设备和用户的服务器不直接建立连接,而是通过代理者(Broker)进行通信。

MQTT代理者(Broker):阿里物模型中的MQTT代理者(Broker)指阿里云物联网平台。代理者(Broker)是设备和业务服务器消息通信的中介,解耦了设备和业务服务器,实现了设备和业务服务器之间的异步通信。

2. 消息类型

MQTT协议定义了多种消息类型,主要包括:

  • CONNECT:客户端向服务器发送连接请求。
  • CONNACK:服务器响应客户端的连接请求。
  • PUBLISH:发布消息到服务器,服务器再将消息分发给订阅者。
  • PUBACK:确认PUBLISH消息已被接收。
  • PUBREC:QoS 1消息的接收确认。
  • PUBREL:QoS 2消息的发布确认。
  • PUBCOMP:QoS 2消息的最终确认。
  • SUBSCRIBE:客户端订阅一个或多个主题。
  • SUBACK:服务器响应客户端的订阅请求。
  • UNSUBSCRIBE:客户端取消订阅一个或多个主题。
  • UNSUBACK:服务器响应客户端的取消订阅请求。
  • PINGREQ:客户端发送心跳包,检查连接状态。
  • PINGRESP:服务器响应心跳包。
  • DISCONNECT:客户端或服务器发送断开连接的请求。

3. 消息质量(QoS)(Quality of Service)

MQTT支持三种消息质量等级:

  • QoS 0:最多一次传输,消息可能丢失,但不保证送达。
  • QoS 1:至少一次传输,消息至少送达一次,可能重复。
  • QoS 2:只有一次传输,消息只送达一次,确保送达。
  • 在物模型中,QoS=0代表物联网平台只推送一次消息给订阅者。消息最多收到一次,消息不可靠传输,消息可能丢失。传感器数据传输使用Qos=0。
  • QoS=1代表订阅者收到消息后必须返回puback给发布者,否则会一直推送消息。消息最少收到一次,消息可靠传输,消息必达。远程控制指令使用Qos=1。
  • Qos=2在物联网平台中并不支持。
  • 对于MQTT 3.1.1版本协议,如果设备订阅了自己发布消息的Topic,则设备会接收到自己发布的消息。而使用MQTT 5.0版本协议,此场景下,设备在订阅Topic时,可以设置此选项为1,设备将不会接收到自己发布的消息。
  • MQTT协议消息的组成部分
  • 主题(Topic):使用正斜杠(/)作为分隔符构造字符串,例如/${productKey}/${deviceName}/user/update,订阅该Topic的所有设备都会收到消息。
  • 消息内容(Payload):消息的具体内容。

4. 主题(Topic)

MQTT使用主题来组织消息。主题是一个字符串,通常采用层次结构,如“home/livingroom/temperature”。客户端可以订阅一个或多个主题,接收这些主题的消息。

  • 在物联网中,有Topic相关、设备接入、连接通信等使用限制, 使用限制
  • 物联网中,有更详细的Topic划分,

基础通信Topic:设备使用物联网平台的物模型通信、OTA升级、任务管理等功能,必须使用的Topic。

物模型Topic:物模型是对设备实际功能的抽象,从属性服务事件三个维度,分别描述了该实体是什么、能做什么、能提供什么信息。例如智能风扇的开关状态是属性,开关的操作是服务,报警是事件。什么是物模型

自定义Topic:如果物模型不能满足业务需求,可以使用自定义Topic,自定义Topic的前三个类目/ProductKey/${deviceName}/user已固定。使用自定义Topic通信

基础通信Topic和物模型Topic由物联网平台定义,以/sys、/ota或/shadow开头。使用物模型Topic通信,需要先在产品下创建物模型。

物联网中的预定义Topic:

  1. 基础通信Topic,以OTA升级为例:

设备上报OTA模块版本,数据上行。

Topic:/ota/device/inform/${productKey}/${deviceName}。

物联网平台推送OTA升级包信息,数据下行。

Topic:/ota/device/upgrade/${productKey}/${deviceName}。

设备上报升级进度,数据上行。

Topic:/ota/device/progress/${productKey}/${deviceName}。

设备请求OTA升级包信息,数据上行。

请求Topic:/sys/${productKey}/${deviceName}/thing/ota/firmware/get。

响应Topic:/sys/${productKey}/${deviceName}/thing/ota/firmware/get_reply。

设备请求下载文件分片,升级包下载协议为MQTT时,设备端获取OTA升级包信息后,可通过以下Topic分片下载OTA升级包文件。

请求Topic:/sys/${productKey}/${deviceName}/thing/file/download

响应Topic:/sys/${productKey}/${deviceName}/thing/file/download_reply

与物模型的结合

物模型通信Topic:

设备上报属性:

Topic和数据格式(上行,透传格式数据):

  • 请求Topic:/sys/${productKey}/${deviceName}/thing/model/up_raw
  • 响应Topic:/sys/${productKey}/${deviceName}/thing/model/up_raw_reply

Topic和数据格式(上行,非透传格式数据,Alink JSON):

  • 请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/post
  • 响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply

设置设备属性:下发指令到设备

Topic和数据格式(下行):

透传:

  • 请求Topic:/sys/${productKey}/${deviceName}/thing/model/down_raw
  • 响应Topic:/sys/${productKey}/${deviceName}/thing/model/down_raw_reply

Alink JSON:

  • 请求Topic:/sys/${productKey}/${deviceName}/thing/service/property/set
  • 响应Topic:/sys/${productKey}/${deviceName}/thing/service/property/set_reply

设备上报事件:(上行)

透传:

  • 请求Topic:/sys/${productKey}/${deviceName}/thing/model/up_raw
  • 响应Topic:/sys/${productKey}/${deviceName}/thing/model/up_raw_reply

Alink JSON:

默认模块:

请求Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post

响应Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply

自定义:

Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.functionBlockId}:${tsl.event.identifier}/post(请求)

Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.functionBlockId}:${tsl.event.identifier}/post_reply(响应)

设备服务调用(异步调用):

Topic和数据格式(下行):

透传:

请求Topic:/sys/${productKey}/${deviceName}/thing/model/down_raw

响应Topic:/sys/${productKey}/${deviceName}/thing/model/down_raw_reply

Alink JSON:

默认:

请求Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}

响应Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}_reply

自定义:

/sys/${productKey}/${deviceName}/thing/service/${tsl.functionBlockId}:${tsl.service.identifier}

/sys/${productKey}/${deviceName}/thing/service/${tsl.functionBlockId}:${tsl.service.identifier}_reply

网关批量上报数据:网关类型的设备可以批量上报属性和事件,也可以代其子设备批量上报属性和事件。

  • 一次最多可上报200个属性,20个事件。
  • 一次最多可为20个子设备上报数据。

Topic和数据格式(上行):

透传:

请求Topic:/sys/${productKey}/${deviceName}/thing/model/up_raw

响应Topic:/sys/${productKey}/${deviceName}/thing/model/up_raw_reply

Alink JSON:

请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/pack/post

响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/pack/post_reply

物模型历史数据上报:

Topic和数据格式(上行):

请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/history/post

响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/history/post_reply

设备批量上报属性、事件:

Topic和数据格式(上行):

请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/batch/post

响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/batch/post_reply

5. 保留消息(Retained Message)

MQTT允许发送者指定消息是否为保留消息。如果一个消息被标记为保留,那么当新的订阅者订阅该主题时,他们将立即接收到这个保留消息,而不需要等待下一个消息发布。

6. 遗嘱消息(Will Message)

客户端在连接时可以指定一个遗嘱消息。如果客户端意外断开连接,服务器将自动向客户端订阅的主题发送这个遗嘱消息。

7. 安全机制

  • 保活时间:当设备发起连接时会向物联网平台发送CONNECT消息,物联网平台使用CONNACK消息进行响应并保持连接,设备在保活时间间隔内至少需要发送一次报文,否则物联网平台会断开与设备的连接。

MQTT支持多种安全机制,包括:

  • TLS/SSL:加密传输,保护数据安全。
  • 用户认证:通过用户名和密码进行认证。
  • 访问控制:限制客户端对特定主题的访问权限。

8. 会话管理

MQTT支持会话管理,允许客户端在断开连接后重新连接时,恢复之前的状态。会话可以存储订阅信息和未确认的消息。

  • 在物联网平台上使用MQTT5.0时,会引入一个会话过期的概念:

设备与物联网平台保持连接时会形成会话状态,会话状态包括订阅的Topic、保留消息、遗嘱消息、平台缓存的QoS1消息等。会话过期是指当设备和物联网平台断开连接,过期后会话会被删除。

  • 在MQTT 3.1.1版本中,没有明确的会话过期概念,只有cleanSession决定设备重新连接时是否继续之前的会话状态信息。一个会话要么在断开连接时被清除,要么会一直保留直到设备重新连接物联网平台。
    • cleanSession = true:建连时删除会话,设备需要重新订阅topic,也不会收到物联网平台缓存的QoS1消息。
    • cleanSession = false:建连时保留会话,设备不需要重新订阅topic,会收到物联网平台缓存的QoS1消息。
  • 在MQTT 5.0中,明确引入会话过期的概念,用cleanStart替换cleanSession,增加会话过期间隔属性Session Expiry Interval。这两个参数提供了比MQTT 3.1.1 中的 cleanSession 更精细的会话控制,可以在设备断开连接后的一段时间内保留会话状态,也可以在不需要会话时删除会话,节约云端的资源开发,避免收到不符预期的消息。

  • cleanStart是二进制标志位,在设备重新连接物联网平台时,是否开始一个新的会话,并清除任何现有的会话状态信息。
  • cleanStart=true:建连时删除之前的会话,设备端需要重新订阅topic,也不会收到物联网平台缓存的QoS1消息。
  • cleanStart=false:如果会话没被删除,则继续使用之前的会话。在设备断开连接后,会话被保留的时长为Session Expiry Interval。如果设备在保留时长内重新连接物联网平台,则不需要重新订阅topic,会收到物联网平台缓存的QoS1消息。如果设备没有在保留时长内重新连接,则会话被删除,设备需要重新订阅Topic,不会收到物联网平台缓存的QoS1消息。

  • Session Expiry Interval代表时间间隔,单位为秒。在这个时间间隔内,设备断开连接后,物联网平台会保留会话状态。如果不设置,时间间隔默认为0。如果设置为0xFFFFFFFF,时间间隔为无限长。
  • 根据会话过期间隔属性Session Expiry Interval和cleanStart的不同取值,会出现以下四种情况:
  1. cleanStart=true且Session Expiry Interval=0。设备断开连接时立即清理会话,设备重新连接时需要建立新的会话。
  2. cleanStart=true且Session Expiry Interval=∞,与情况一的结果相同。只要cleanStart=true,设备就会在重新连接时建立新的会话,无论Session Expiry Interval取值多少。
  3. cleanStart=false,Session Expiry Interval>0但小于设备断开的时间间隔。会话保留的时间较短,在设备重新连接前物联网平台,会话已被删除。
  4. cleanStart=false,Session Expiry Interval=∞。会话保留的时间无限长,设备重新连接后继续使用之前的会话。

对于车辆等持续移动的设备,如果经常清除会话,会导致频繁的订阅。这种情况适用于上图的情况3,如果设备在一定时间内重连就复用会话,当设备长时间不能连接时清除会话,避免接收处理过期的消息。对于POS机、播报音箱等金融设备,对消息的到达率要求非常高,适用于上图的情况4。会话从创建到结束保持一致,不会丢失订阅关系和消息。对于广告屏设备,持续更新播放新的广告内容,不需要接收过期消息,适用于上图的情况1。不保留会话,可以避免收到无效过期的内容,也可以节约云端的资源消耗。

9. 网络优化

MQTT协议设计考虑了网络的不稳定性。它通过减少消息大小和优化重传机制,适应低带宽和高延迟的网络环境。

MQTT因其灵活性和高效性,成为物联网和移动应用中广泛使用的一种通信协议。

接入物联网平台进行模拟

  • 可以使用MQTT.fx接入物联网平台进行模拟

获取mqtt的连接参数

定义物模型:

设置参数

Profile Name

输入您的自定义名称iot connection。

Profile Type

MQTT服务器连接,选择MQTT Broker

Broker Address

MQTT接入域名,对应《前提条件》中已获取的mqttHostUrl值:a1***.iot-as-mqtt.cn-shanghai.aliyuncs.com。

  • a1***为本示例产品的ProductKey
  • cn-shanghai为本示例所在地域。

此处仅输入域名,无需携带端口号。

Broker Port

设置为1883。

Client ID

MQTT的协议字段。

固定格式:${ClientId}|securemode=${Mode},signmethod=${SignMethod}|timestamp=${timestamp}|。

输入clientId值:a1***.device1|securemode=2,signmethod=hmacsha256,timestamp=2524608000000|。

参数说明:

  • ${ClientId}:设备、App或Web等场景下的Client ID信息。

重要

该值需自定义,长度在64个字符以内。若为设备的ID信息,建议使用您设备的MAC地址或SN码,方便您识别区分不同的设备。

  • ${Mode}:安全模式。可选值有2(TLS直连模式,需要设置SSL/TLS信息)和3(TCP直连模式,无需设置SSL/TLS信息)。
  • ${SignMethod}:算法类型,支持hmacsha256、hmacmd5和hmacsha1。
  • ${timestamp}:表示当前时间毫秒值,可以不传递timestamp

物联网平台提供的连接参数中${ClientId}默认为${ProductKey} + '.' + ${DeviceName}组成的字符串,${Mode}默认为2,${SignMethod}默认为hmacsha256,您可根据需要修改。

重要

  • MQTT.fx的Client ID和设备的${ClientId},切勿混淆。
  • 不要遗漏参数之间及最后的竖线(|)。
  • 设置参数时,请确保参数值中或参数值的前后均没有空格。
  • 输入Client ID信息后,请勿单击Generate

General

使用默认值。

单击User Credentials,选中Use Username/Password复选框,设置User NamePassword

TLS直连模式(即securemode=2)下,单击SSL/TLS,选中Enable SSL/TLS,设置ProtocolTLSv1.2

设置完成后,单击右下角的OK

单击Connect。右侧亮绿灯,表示连接成功。

使用自定义Topic通信:

上行通信:设备向物联网发信息:

在MQTT.fx上,单击Publish,在Publish文本框中,输入具有发布权限的Topic:/a1***/device1/user/update/error。

在文本编辑页面,输入要发送的消息内容,然后单击Publish

登录物联网平台控制台,在对应实例下的日志服务页面,查看设备到云消息日志消息。

下行通信:设备通过订阅获取到物联网平台下发的消息

在MQTT.fx上单击Subscribe,在Subscribe文本框中,输入具有订阅权限的Topic:/a1***/device1/user/get

单击Subscribe。订阅成功后,该Topic会显示在列表中。

登录物联网平台控制台,在对应实例下,选择设备管理 > 设备

单击设备对应操作列的查看,进入设备详情页面。

单击Topic列表页签,单击已订阅Topic对应操作列的发布消息

输入消息内容,例如This is a test .,单击确认

回到MQTT.fx上,查看接收到的消息。

  • 使用物模型通信Topic通信:

设备上报属性:(需要有发布权限,上行)

在MQTT.fx上单击Subscribe,在Subscribe文本框中,输入具有订阅权限的Topic:/sys/a1****/device1/thing/event/property/post_reply。

在MQTT.fx上单击Publish,在Publish文本框中,输入具有发布权限的Topic:/sys/a1****/device1/thing/event/property/post。

在文本编辑页面,输入要上报的属性数据,然后单击Publish

设备上报属性数据的格式,需符合标准Alink JSON格式。设备上报属性。上报属性LightCurrentLightSwitch数据。

在MQTT.fx上单击Subscribe,查看物联网平台返回给设备的响应消息。

如下图所示,设备上报属性成功。

登录物联网平台控制台,在对应实例下,选择设备管理 > 设备

单击设备对应操作列的查看,在设备详情页面单击物模型数据,查看设备数据。

设置设备属性:(需要模拟设备有订阅权限,下行)

在MQTT.fx上单击Subscribe,在Subscribe文本框中,输入具有订阅权限的Topic:/sys/a1****/device1/thing/service/property/set。

登录物联网平台控制台,在对应实例下,选择监控运维 > 在线调试

选择要调试的设备,然后在属性调试页签下,设置主灯开关关闭-0

单击设置,发送指令。

在MQTT.fx上的Subscribe页签下,查看设备接收的消息。

可以通过查看日志对模拟设备的上行和下行操作进行查看。可以看到错误信息。

### 通过串口上报数据至阿里云联网平台 #### 设备端配置与初始化 为了使设备能够通过串口接收来自传感器的数据并将其上传到阿里云IoT平台,需先完成硬件连接以及软件环境搭建工作。对于采用STM32MP1系列微控制器作为核心处理单元的情况,在Linux环境下可以利用标准输入输出接口来读取外部传感装置传来的信息。 ```c #include <stdio.h> int main() { char buffer[1024]; while (fgets(buffer, sizeof(buffer), stdin)) { // 从串口读取一行数据 printf("%s", buffer); // 打印接收到的内容用于调试目的 } } ``` 上述代码展示了如何简单地从串口中获取字符串形式的信息[^1]。然而实际项目中还需要考虑更多因素比如错误检测、超时机制等。 #### 构建模型并与云端交互 当准备好要发送给服务器的有效载荷之后,就需要按照阿里云定义的消息协议格式化这些数据,并调用相应的API函数向指定的主题发布消息。这通常涉及到创建产品实例下的具体设备,并设置其属性结构即所谓的“模型”。 ```json { "id": "unique_id", "version": "1.0", "params": [ {"identifier":"temperature","value":25}, {"identifier":"humidity","value":60} ], "method": "thing.event.property.post" } ``` 此JSON对象表示一次事件触发请求,其中包含了温度和湿度两个参数及其当前测量值。注意`method`字段指定了操作类型为属性更新报告。 #### 发送HTTP POST 请求 最后一步就是构建完整的URL路径加上必要的认证信息(如ProductKey、DeviceName 和 DeviceSecret),并通过HTTPS方式提交携带了之前准备好的body体的POST请求: ```bash curl -X POST \ 'https://<region>.iot.aliyun.com/api/cloudapi/post' \ -H 'Content-Type: application/json' \ -d '{"id":"unique_id","version":"1.0","params":[{"identifier":"temperature","value":25},{"identifier":"humidity","value":60}],"method":"thing.event.property.post"}' ``` 以上命令行脚本实现了将本地采集到的数据推送到远程数据中心的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值