简介
mqtt有IBM公司开发,90年代的产物。
解决了如下问题:服务器必须要实现成千上万的接入:单词数据量小,不能出错;必须能够使用高延迟、偶尔断网等通信不可靠的风险;根据数据的重要程度和特性,设置不同等级的服务质量。
1.1.MQTT介绍
MQTT是一种针对移动终端设备基于TCP/IP的发布/订阅的协议;可大量连接远程传感器和控制设备,可保持长连接,具有一定实时性;云端向设备端发送消息,可在最短时间内接收并作出响应;适合实时控制场合,如:执行器;保持长连接,就绪不时发送心跳包,比较费电;低功耗不适用;长连接需要建立在TCP的基础上,TCP协议的复杂性决定了设备要求比UDP更高,所以MQTT协议更加可靠。
1.2.MQTT特性
使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序的耦合性。有三种发布服务质量(Qos0、Qos1、Qos2):“至多一次”,消息发布完成依赖底层TCP/IP网络,会发生消息丢失或重复,对采集数据不严格;“至少一次”,确保消息到达,但消息会重复发生;“只有一次”,确保消息只到达一次,用于严格要求如涉及计费系统的情况,消息重复或丢失都不被允许。
小型传输,开销小(固定长度的头部是2字节),协议交换最小化,降低网络流量;的hi用Last Will和Testament特性通知各方客户端异常中断的机制;允许用户动态创建主题,零运维成本;考虑到低带宽、高延迟、不稳定的网络等因素;如数据不可知,不强求传输数据类型与格式,保持灵活。官网:http://mqtt.org/
![](https://img-blog.csdnimg.cn/img_convert/4a2bc09a7613585002a76ffb4257cbc0.png)
用户可通过协议自己构建一个传感器网络,其中各种传感器都能以其独有的消息形式发布传感器值,订阅程序能订阅不同的消息,以此采取措施,MQTT代理将处理从发布程序到订阅程序的消息转发。MQTT服务器处理收集转发数据,还能进行数据的存储和处理,例如:实时存储共享单车的位置、电池用量、状态信息等数据,以及对总体车辆数据进行计算和统筹等关联,甚至为一些聊天工具提供平台服务。
![](https://img-blog.csdnimg.cn/img_convert/83a011d984eb7265b216a9655b1862b9.png)
MQTT主题模式:通过主题对消息进行分类:本质上是一个UTF—8的字符串;通过反斜杠表示多个层级关系;主题不需要创建,直接使用;主题可通过通配符过滤:+过滤一个层级;*只能出现在主题最后表示过滤任意层级,如:building-b/floor-5:代表B楼5层的设备,+/floor-5:代表任何一楼的5层设备,building-b/*:代表B楼所有的设备。
MQTT中三个角色:发布者Publisher、订阅者Subsctiber、代理Broker。这种结构代替了传统的客服端/服务器模型,可以实现如下解耦:空间解耦:发布者和订阅者不需要知道对方;时间解耦:发布者和订阅者不需要同时运行(离线消息);同步解耦:发布和接收都是异步进行,无需停止任何
2.MQTT协议
MQTT报文格式:固定控制报头、剩余数据长度、可变长度报头和有效数据载荷》
![](https://img-blog.csdnimg.cn/img_convert/e97830fe826597b107910c005402ce81.png)
固定报头,高4bit表示14种控制包类型。固定报头格式:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
byte 1 | MQTT控制报文类型 | 用于指定控制报文类型标志位 | ||||||
byte 2 | 剩余长度 |
控制报文类型 | |||
名字 | 值 | 报文流动方向 | 描述 |
Reserved | 0 | 禁止 | 保留 |
CONNECT | 1 | 客户端到服务端 | 客户端请求连接服务器 |
CONNACK | 2 | 服务端到客户端 | 连接报文确认 |
PUBLISH | 3 | 两个方向都允许 | 发布消息 |
PUBACK | 4 | 两个方向都允许 | QoS1消息发布收到确认 |
PUBREC | 5 | 两个方向都允许 | 发布收到(保证交付第一步) |
PUBTRL | 6 | 两个方向都允许 | 发布释放(保证交付第二步) |
PUBCOMP | 7 | 两个方向都允许 | QoS2消息发布完成(保证第三步) |
SUBSCRIBE | 8 | 客户端到服务端 | 客户端订阅请求 |
SUBACK | 9 | 服务端到客户端 | 订阅请求报文确认 |
UNSUBSCRIBE | 10 | 客户端到服务端 | 客户端取消订阅请求 |
UNDUBACK | 11 | 服务端到客户端 | 取消订阅报文确认 |
PINGREQ | 12 | 客户端到服务端 | 心跳请求 |
PINGRESP | 13 | 服务端到客户端 | 心跳响应 |
DISCONNECT | 14 | 客户端到服务端 | 客户端断开连接 |
Reserved | 15 | 禁止 | 保留 |
剩余数据长度:剩余数据长度=可变长度报头+有效数据载荷;剩余长度采用可变长编码方案。
可变长度报头:根据报文类型不同,会有不同的报文标识;协议名称(Protocol Name);协议级别(Protocol Level);连接标志(Connect Flags);保活时间(Keep Alive);连接标识(Packet Identifier).
![](https://img-blog.csdnimg.cn/img_convert/f0094060d567939b066b0da012639519.png)
![](https://img-blog.csdnimg.cn/img_convert/0441cb11b34b427cbf4f559fa45ea977.png)
![](https://img-blog.csdnimg.cn/img_convert/f7c63c47860977c629e941a5a961b50d.png)
有效数据载荷:并不是所有的类型的报文都是有有效载荷;对于PUBLISH说有效载荷就是应用信息。
服务器:一个程序或设备,客户端总是通过完了连接到服务器的;发布应用消息给其他相关的客户端;订阅一请求接收相关的应用信息;取消订阅可移除接收应用消息的请求;从服务端端口连接。
![](https://img-blog.csdnimg.cn/img_convert/492c65a6ee7f1eb29322f5d2f9391d3f.png)
3.MQTT应用
MQTT代理服务器很多,支持丰富的开发环境和开发语言。
mosquitto在ubuntu16.04环境安装:
sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa:下载安装包
sudo apt-get update:更新安装库列表
sudo apt-get install mosquitto:服务器下载安装
sudo apt-get install mosquitto-clients:客户端下载安装
mosquitto基本操作:
mosquitto -c /etc/mosquitto/mosquitto.conf -p 1883:加载配置文件路径及端口号
mosquitto_sub -t "temp":订阅指令主题为temp
mosquitto_pub -t "temp" -m "hello:发布一个temp的主题,内容为hello
更多参数选择操作:
mosquitto_sub -d -v -t temp -h 192.168.1.13 -p 1883 -q 2:-v展示更多内容,-h指定主机,-p指定端口,最后2位mqtt的请求方式。
mosquitto_pub -d -t temp -h 192.168.1.13 -p 1883 -m hello -q 2。
mosquitto非匿名登录配置
修改配置sudo vim /etc/mosquitto/mosquitto.conf
allow_anonymous false #true表示允许匿名登录,false表示启动用户验证
password_file /etc/mosquitto/passwd.conf #用户账号信息文件存放位置
服务端创建用户:sudo mosquitto _passwd -c
/etc/mosquitto/passwd.conf hg #隐藏密码创建
sudo mosquitto _passwd -b
/etc/mosquitto/passwd.conf zs 111111 #明文密码创建
mosquitto通过用户密码登录测试:
mosquitto -c /etc/mosquitto/mosquitto.conf
moqsquitto_sub -t "temp" -u hg -P 111111
mosquitto_pub -t "temp" -m "hello" -u zs -P 111111
mosquitto安全通信
应用层:通过用户名密码验证客户端;传输层:通过TLS加密,不仅可以实现身份证还可以保证数据安全;网络层:采用VPN专线。
openssl安装
查看系统是否安装ssl:which openssl
找不到安装:sodu apt-get install openssl
sudo apt-get install libssl-dev
生成证书和密钥
拷make_ssl.sh到自己目录下如:/home/edu/debug/mqtt/ssl
修改make_ssl.sh中两处IP地址位实际mosquitto服务器IP地址;执行脚本生成证书:./make_ssl.sh(从网上搜到make_ssl.sh和rm_ssl.sh).
修改配置sudo vim /etc/mosquitto/mosquitto.conf
cafile /home/edu/debug/mqtt/ssl/ca/ca.crt
certfile /home/edu/debug/mqtt/ssl/server/server.crt
keyfile /home/edu/debug/mqtt/ssl/server/server.key
单项验证输入
mosquitto -c /etc/mosquitto/mosquitto.conf
moqsquitto_sub -t "temp" -u hg -P 111111 --cafile /home/edu/debug/mqtt/ssl/ca/ca.crt -h 192.168.1.13 -p 1883
mosquitto_pub -t "temp" -m "hello" -u hg -P 111111 --cafile /home/edu/debug/mqtt/ssl/ca/ca.crt -h 192.168.1.13 -p 1883
双向验证测试
修改配置sudo vim /etc/mosquitto/mosquitto.conf
require_certificate true
use_identity_as_usernamme true
mosquitto -c /etc/mosquitto/mosquitto.conf
moqsquitto_sub -t "temp" -u hg -P 111111 --cafile /home/edu/debug/mqtt/ssl/ca/ca.crt --cert /home/edu/debug/mqtt/ssl/client/client.crt --key /home/edu/debug/mqtt/ssl/client/client.key -h 192.168.1.13 -p 1883
moqsquitto_sub -t "temp" -m "hello" -u hg -P 111111 --cafile /home/edu/debug/mqtt/ssl/ca/ca.crt --cert /home/edu/debug/mqtt/ssl/client/client.crt --key /home/edu/debug/mqtt/ssl/client/client.key -h 192.168.1.13 -p 1883
4.moqsquitto移植
4.1.环境搭建
下载mqtt源码(mosquitto-1.5.4.tar.gz):
http://mosquitto.org/download/
或:git clone
git://eclipse.org/gitttot/mosquitto/org.eclipse.mosquitto.git
下载openssl源码:(openssl-1.0.le.tar);
https://www.openssl.org/source/
或:https://gitrhub.com/openssl/openssl.git
编译openssl
mkdir /home/user/mqtt/pc/openssl_install
解压并进入openssl-1.0.le目录
./config no-asm -shared -- prefix=/home/user/mqtt/pc/openssl_install
make
make install
编译mosquitto:
mkdir /home/user/mqtt/pc/mqtt_install
sudo apt-get install uuid-dev
解压并进入mosquitto-1.5.4目录
修改配置文件config.mk
注意:其中user指的是你自己家的目录名