物联网核心之MQTT(一)
MQTT
,目前物联网的最主要的协议,基本所有收费的云平台都是基于
MQTT
协议,比如机智云,和所有的开放云平台比如中国移动的
oneNet
、百度的云平台也都支持
MQTT
的接入。虽然
MQTT
很火,但是目前对
MQTT
的很少,尤其是在如何移植到嵌入式上来。大部分的平台商的做法都是跟模块商合作把
MQTT
协议集成到
WiFi
模块跟
GPRS
模块里面,捆绑一销售,不让用户过多的了解物联网最核心的东西。
在还没有深入去了解MQTT
协议之前,总以为是非常复杂的东西,毕竟之前一直想深入,但无奈在浩淼的网络里居然找不到太多实质的资料。随时自己对物联网的不断探索,越来越了解整个物联网的架构,对
MQTT
了解越来越深入。在这篇文章中将带大家先了解
MQTT
的协议,在后面的文章,再带大家怎么移植
MQTT
到
STM32
上,再到怎么搭建自己的
MQTT
服务器。
MQTT
的基础知识这些大家通过百度知道都可以了解到,这里主要深入去剖析
MQTT
协议的整个通信流程。整个
MQTT
的知识大家可以去附件里的《
MQTT OneNET
实现
.docx
》,这个文档已经写的非常详细,但是如果只是看文字话,大家很难理解。因此我们借助
Windows
下的
MQTT
客户端
MQTT.fx
跟网络抓包工具
Wireshark
来一步步分析
MQTT
。
上面是MQTT
的主要的通信协议,
MQTT
是基于
TCP
长连接,首先是先跟
MQTT
服务器建立
TCP
连接,然后发送登录请求,要保持长连接,还要定时发心跳包跟服务保持连接。我们先用
MQTT.fx
来登录开源的
MQTT
服务看看。
![](https://i-blog.csdnimg.cn/blog_migrate/f9df964dbc18543e1f4733355afe2573.jpeg)
安装好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
捕到的数据
![](https://i-blog.csdnimg.cn/blog_migrate/a6e4e454b3537032f51a6934d2f0c870.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/2dac7908a22a8301f674a706a7c172f8.jpeg)
可以看到MQTT
协议中本地给服务器发送了一个
Connect
登录请求,然后,服务器回应一个
ACK
,表示登录成功。再双击
Connect Command
这条数据包,我们可以看到详细的数据包数据
![](https://i-blog.csdnimg.cn/blog_migrate/8935890d23aa192e88b9eb22f7ee366d.jpeg)
上面的解析出来的MQTT
协议包的内部,下面是对应的二进制数据,这里我们可以对照附件上资料去了解协议的内容。看这里,大家想是不是如果自己用
TCP
,再封装发送下面的二进制数据就可以完成
MQTT
的登录了呢?拿出网络调试助手来,
ping
下
m2m.eclipse.org
得到
IP
地址,用端口号
1883
连接,然后发送
Wireshark
捕到的
MQTT
登录协议的二进制数据,可以看到到服务器回应了
20 02 00 00
表示登录成功。
![](https://i-blog.csdnimg.cn/blog_migrate/e2ae6fe6ab889f297ac8e8b6f72f2bfb.jpeg)
再往下Wireshark
捕到的数据包,可以看到每隔一定的时间,本地向服务器发送
Ping Request
心跳包,相应的服务器也会回应
Ping Response
。
![](https://i-blog.csdnimg.cn/blog_migrate/13869924e76f089f77a3486602ecf4b5.jpeg)
接下来看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
灯。
![](https://i-blog.csdnimg.cn/blog_migrate/d497f2dfdb3f9383fa21742322f029eb.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/80e2e200ff40eb16d6fc8b10cb0cd420.jpeg)
想深入了解MQTT
这一个过程的话,我们再回到
Wireshark
,来看看捕获到的数据
![](https://i-blog.csdnimg.cn/blog_migrate/53ad00bc1cde4fc4658c007e9728cfb0.jpeg)
具体的就不详细的分析了,大家看附件的文档来对照就可以很容易了解到。
最后来了解下QoS
(定阅等级),分
0
、
1
、
2
三个等级,简单来说是等级越高越可靠。
QoS0,
就是推送之后就完事了,至于对方有没有收到,收到是什么,数据有没有丢失,都不管。
QoS1
的话就
是你收到推送后,你还得返回一个puback
给对方,告诉对方收到了,不然对方会以为你没收到,隔一段时间后重新给你推送,直到你给对方返回一个
Puback
为止。
![](https://i-blog.csdnimg.cn/blog_migrate/9901dae384e8cd61f96dc5e6e77d8b19.jpeg)
好了,基本的就写到这,剩下的大家可以根据这个方法对照文档去消化MQTT
。后面的文章再教大家移植
MQTT
到单片机上,大家就可以实现远程的控制了,期待吧。