,目前物联网的最主要的协议,基本所有收费的云平台都是基于 MQTT 协议,比如机智云,和所有的开放云平台比如中国移动的 oneNet 、百度的云平台也都支持 MQTT 的接入。虽然 MQTT 很火,但是目前对 MQTT 的很少,尤其是在如何移植到嵌入式上来。大部分的平台商的做法都是跟模块商合作把 MQTT 协议集成到 WiFi 模块跟 GPRS 模块里面,捆绑一销售,不让用户过多的了解物联网最核心的东西。
在还没有深入去了解MQTT 协议之前,总以为是非常复杂的东西,毕竟之前一直想深入,但无奈在浩淼的网络里居然找不到太多实质的资料。随时自己对物联网的不断探索,越来越了解整个物联网的架构,对 MQTT 了解越来越深入。在这篇文章中将带大家先了解 MQTT 的协议,在后面的文章,再带大家怎么移植 MQTT 到 STM32 上,再到怎么搭建自己的 MQTT 服务器。
的基础知识这些大家通过百度知道都可以了解到,这里主要深入去剖析 MQTT 协议的整个通信流程。整个 MQTT 的知识大家可以去附件里的《 MQTT OneNET 实现 .docx 》,这个文档已经写的非常详细,但是如果只是看文字话,大家很难理解。因此我们借助 Windows 下的 MQTT 客户端 MQTT.fx 跟网络抓包工具 Wireshark 来一步步分析 MQTT 。
名字 | 值 | 流向 | 描述 |
CONNECT | 1 | C->S | 客户端请求与服务端建立连接 |
CONNACK | 2 | S->C | 服务端确认连接建立 |
PUBLISH | 3 | óS | 发布消息 |
PUBACK | 4 | óS | 收到发布消息确认 |
PUBREC | 5 | óS | 发布消息收到 |
PUBREL | 6 | óS | 发布消息释放 |
PUBCOMP | 7 | óS | 发布消息完成 |
SUBSCRIBE | 8 | C->S | |
SUBACK | 9 | S->C | 订阅确认 |
UNSUBSCRIBE | 10 | C->S | 取消订阅 |
UNSUBACK | 11 | S->C | 取消订阅确认 |
PING | 12 | C->S | PING( 连接保活 ) 命令 |
PINGRSP | 13 | S->C | 命令回复 |
DISCONNECT | 14 | C->S | 断开连接 |
上面是MQTT 的主要的通信协议, MQTT 是基于 TCP 长连接,首先是先跟 MQTT 服务器建立 TCP 连接,然后发送登录请求,要保持长连接,还要定时发心跳包跟服务保持连接。我们先用 MQTT.fx 来登录开源的 MQTT 服务看看。
安装好MQTT.fx( 注意 MQTT.fx 是 java 开发的,电脑要安装 JDK 才能安装打开) , 一打开里面就默认有一个开源的 MQTT 服务 M2M Eclipse 。点开旁边的齿轮(设置按钮)可以看服务器的域名 m2m.eclipse.org ,端口号 1833 ( MQTT 的默认端口号),下面还有个 Keep Alive Interval 就是心跳的时间。再打开 Wireshark ,选择要捕获的网络接口, 然后再过滤器输入tcp.port==1883 后回车,只捕获 1883 这个端口号的数据包。再点下 MQTT.fx 的 Connect 连接服务器,就可以看到 Wireshark 捕到的数据
可以看到MQTT 协议中本地给服务器发送了一个 Connect 登录请求,然后,服务器回应一个 ACK ,表示登录成功。再双击 Connect Command 这条数据包,我们可以看到详细的数据包数据
上面的解析出来的MQTT 协议包的内部,下面是对应的二进制数据,这里我们可以对照附件上资料去了解协议的内容。看这里,大家想是不是如果自己用 TCP ,再封装发送下面的二进制数据就可以完成 MQTT 的登录了呢?拿出网络调试助手来, ping 下 m2m.eclipse.org 得到 IP 地址,用端口号 1883 连接,然后发送 Wireshark 捕到的 MQTT 登录协议的二进制数据,可以看到到服务器回应了 20 02 00 00 表示登录成功。
再往下Wireshark 捕到的数据包,可以看到每隔一定的时间,本地向服务器发送 Ping Request 心跳包,相应的服务器也会回应 Ping Response 。
接下来看MQTT 最核心的传输协议 Subcribe (定阅)和 Publish (推送)。简单来说就是客户端口(比如物联网硬件) Subcribe 一个 topic (主题 ) 后,其它的客户端(比如手机)向服务器往这个 topic 推送 Payload( 有效数据),服务器就会把Payload 转发给定阅这个 topic 的客户端(硬件)。这样就实现了客户端(手机)通过服务器( MQTT )远程发送数据给客户端(物联网硬件)。一样用 MQTT.fx 来实验。先点 Subscribe 然后面下面输入 led 再点旁边的 Subscribe 按钮来定阅 led 这个 topic 。然后回到 Publish ,一样在输入框输入 led 这个 topic ,下面大框就是输入要推送的数据,输入 on ,再点 Publish 按钮,就把数据推送出去了。再回到 Subcribe 界面来可以看到右边已经收到有推送过来的数据。如果这是硬件收到这个指令,就可以去控制点亮 LED ,我们就实现远程控制 LED 灯。
想深入了解MQTT 这一个过程的话,我们再回到 Wireshark ,来看看捕获到的数据
具体的就不详细的分析了,大家看附件的文档来对照就可以很容易了解到。
最后来了解下QoS (定阅等级),分 0 、 1 、 2 三个等级,简单来说是等级越高越可靠。 QoS0, 就是推送之后就完事了,至于对方有没有收到,收到是什么,数据有没有丢失,都不管。 QoS1 的话就
是你收到推送后,你还得返回一个puback 给对方,告诉对方收到了,不然对方会以为你没收到,隔一段时间后重新给你推送,直到你给对方返回一个 Puback 为止。
好了,基本的就写到这,剩下的大家可以根据这个方法对照文档去消化MQTT 。后面的文章再教大家移植 MQTT 到单片机上,大家就可以实现远程的控制了,期待吧。