由于工做须要,了解了一下MQTT。顺便记下来,如今还不会用。html
MQTT(Message Queuing Telemetyr Transport 消息队列遥测传输协议):基于发布/订阅(Publish/Subscribe)模式的轻量级通信协议,该协议构建于TCP/IP协议之上。数组
MQTT运行于TCP之上,属于应用层协议。安全
每条MQTT命令消息的消息头都包含一个固定的报头,有些消息会携带一个可变报文头和一个负荷。消息格式以下:服务器
固定报文头|可变报文头|负荷微信
最少有两个字节,第一个字节包含消息的类型(Message Type)和QoS级别等标志位。第二个字节开始是剩余长度字节,该长度是后面的可变报文头加消息负载的总长度,该字段最多容许四个字节。网络
剩余长度字段单个字节的最大值为0x7F. 也就是127个字节。MQTT协议规定,单个字节的最高位若是是1,表示后续还有字节存在,第八位起延续位的做用。异步
因为MQTT协议最多使用四个字节表示剩余长度,而且最后一个字节的最大值只能是0x7F,而不是0xFF。因此能发送的最大消息长度是256MB,而不是512MB。工具
主要包含协议名,协议版本,链接标志,心跳间隔时间,链接返回码,主题名等。ui
实际上能够理解为消息的主体。当MQTT发送的消息类型是CONNECT(链接)、PUBLISH(发布)、SUBSCRIBE(订阅)、SUBACK(订阅确认)、UBSUNSCRIBE(取消订阅)时会带有负荷。编码
固定报文头中的第一个字节包含链接标志,链接标志用来区分MQTT的消息类型。MQTT协议拥有14中不一样的消息类型。以下图:
可简单分为链接及终止、发布和订阅、Qos2消息的机制以及各类确认ACK。
MQTT消息质量有三个等级,QoS 0、Qos 一、Qos 2。
Qos 0:最多分发一次,消息的传递彻底依赖底层的TCP/IP网络,协议里没有定义应答和重试。消息只会到达服务端一次,要么就没到达。
Qos 1:至少分发一次、服务器的消息接收由PUBACK消息进行确认,若是通讯链路或设备异常,或指定时间内没有收到确认消息,发送端会重发这条在消息头中设置了Dup位的消息。
Qos 2:只分发一次。最高级别的消息传递,消息丢失和重复都是不可接受的,使用这个服务质量等级会有额外的开销。
在可变报文头的链接标志位字段(Connect Flags)里面有三个will标志位:Will Flag Will Qos和Retain Flag。这些will字段用于监控客户端与服务器之间的链接情况。
遗愿消息:服务器与客户端通讯时,当遇到异常或客户端心跳超时的状况,MQTT服务器会替客户端发布一个will消息。固然若是服务器收到来自客户端的DISCONNECT消息则不会触发wiwll消息的发送。所以will字段能够应用于设备掉线后通知用户的场景
MQTT客户端能够设置一个心跳间隔时间(keep Alive Timer),表示在每一个心跳检测时间内发送一条消息。若是在这个时间周期内,没有业务数据相关的消息,客户端会发送一个PINGREQ消息,相应的,服务器会返回一个PINGRESP消息进行确认。
若是服务器在一个半(1.5)个心跳间隔时间周期内没有收到来自客户端的消息,就会断开与客户端的链接。心跳间隔时间最大值能够设置为18个小时,8表示客户端不会断开。
发布/订阅模式解耦了发布消息的客户(发布者)和订阅消息的客户(订阅者)之间的关系。发布者与订阅者并不须要直接创建联系。
这个模式的好处有:
1) 发布者与订阅者只须要知道同一个消息代理便可。
2) 发布者与订阅者不须要直接交互,不须要同时在线。
MQTT基于二进制而不是字符串。固定报文头仅有两个字节,相比于其余协议(HTTPS 和XMPP都是基于字符串实现,有冗长的头部),发送一条消息更省流量
因为MQTT运行于TCP层之上而且以明文传输,可使用Wireshark看到MQTT发送的全部消息,消息指令一览无遗。这会带来必定的风险:
1) 设备可能会被盗用
2) 客户端和服务端的静态数据多是可访问的(可能会被修改)
3) 协议行为可能有反作用(如计时器攻击)
4) 拒绝服务攻击
5) 通讯可能会被拦截 修改 重定向或者泄露
6) 虚假控制报文注入
做为传输协议,MQTT只关注消息传输,提供安全功能是开发者的责任。
支持两种层次的认证
1) 应用层:MQTT支持客户标识,用户名和密码认证
客户标识:MQTT客户端能够发送最多65535个字符做为客户标识,通常来讲可使用嵌入式芯片的MAC地址或芯片序列号。
用户名和密码:支持经过CONNECT消息的USERNAME和password字段发送用户名和密码。可是因为是用的明文传输,抓包工具很容易就获取。
2) 传输层:传输层可使用TLS,除了加密通信,还可使用X509证书来认证设备。
在传输层认证是这样的:MQTT代理在TLS握手成功以后能够继续发送客户端的X509证书来认证设备,若是设备不合法就中断链接。
MQTT协议只实现了传送消息的格式,并无限制用户协议须要按照特定风格。所以在MQTT协议之上,咱们须要定义一套本身的通讯协议。就能够有下面几种选择了、
失去了可读性,能够将流量控制的比较小。单片开发可能会比较喜欢用这个。
这个会方便阅读。对于高级语言开发者来讲,字符串依旧不是最佳选择。键值对(Key-value)才是最优形式。
在这门语言中,一切都是对象。所以任何支持的类型均可以经过JSON来表示。例如字符串、数字、对象、数组等、
语法规则是:对象表示键值对、数据用逗号分开、花括号保存对象、方括号保存数组。
JSON层次结构简洁清晰,便于阅读和编写,易于机器解析和生成,有效提高网络传输效率。
综上,MQTT+JSON是最优解。
MQTT基于异步发布/订阅的实现解耦了消息发布者和订阅者,基于二进制的实现节省了存储空间及流量,同时拥有更好的消息处理机制。
MQTT协议是为大量计算能力有限,且工做在低带宽、不可靠的网络的远程传感器和控制设备通信而设计的协议
以上 参考http://www.javashuo.com/article/p-waijxhik-kr.html
参考:http://www.javashuo.com/article/p-mscjejon-ge.html
补充几个概念:
参考:https://www.jianshu.com/p/ecde412d2eeb
MQTT 客户端
一个使用 MQTT 协议的设备、应用程序等,它老是创建到服务器的网络链接。
能够发布信息,其余客户端能够订阅该信息
订阅其它客户端发布的消息
退订或删除应用程序的消息
断开与服务器链接
MQTT 服务器
MQTT 服务器以称为 Broker(消息代理),以是一个应用程序或一台设备。它是位于消息发布者 和订阅者之间
主题(Topic)
链接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每一个客户端。
要订阅的主题。一个主题能够有多个级别,级别之间用斜杠字符分隔。例如,/world
和 emq/emqtt/emqx
是有效的主题。
订阅者的Topic name支持通配符#和+ :
客户端成功订阅某个主题后,代理会返回一条 SUBACK 消息,其中包含一个或多个 returnCode 参数
主题筛选器(Topic Filter)
一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。
QoS(消息传递的服务质量水平)
服务质量,标志代表此主题范围内的消息传送到客户端所需的一致程度。
会话(Session)
每一个客户端与服务器创建链接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络链接。
订阅(Subscription)
订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话能够包含多个订阅。每个会话中的每一个订阅都有一个不一样的主题筛选器。
发布(publish)
控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息,MQTT 客户端发送消息请求,发送完成后返回应用程序线程
负载(Payload)
消息订阅者所具体接收的内容