您好,欢迎访问三七文档
MQTT(MessageQueuingTelemetryTransport,消息队列遥测传输)是一个Client(订阅)与Server(发布)之间的消息传输协议。轻量、开源、简单的特性使其能适应各种应用场景,比如M2M的通讯以及物联网通讯,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT的传输格式非常精小,最小的数据包只有2个比特(bit),且无应用消息头。MQTT可以保证消息的可靠性,它包括三种不同的服务质量:“至多一次”,消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。“至少一次”,确保消息到达,但消息重复可能会发生。“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。MQTT在物联网以及移动应用中的优势有:可靠传输:MQTT可以保证消息可靠安全的传输,并可以与企业应用简易集成。消息推送:支持消息实时通知、丰富的推送内容、灵活的Pub-Sub以及消息存储和过滤。低带宽、低耗能、低成本:占用移动应用程序带宽小,并且带宽利用率高,耗电量较少。1、概述2.1、Client•连接到Server。•发布消息以供其他client订阅。•订阅其他Client的消息。•取消订阅。•与Server断开连接。2.2、Server•接收各Client的连接请求。•接收各Client发布的消息。•处理各Client的订阅/取消订阅请求。•推送与订阅相匹配的消息到对应Client。2.3、ApplicationMessage•通过MQTT协议传输的消息数据。•当消息传输时每个消息有一个与之关联的QualityofService和TopicName。2.4、Subscription(订阅)•订阅由TopicFilter和maximumQoS组成。•一个session可以包含多个Subscription。•同一个session中的每个Subscription都有不同的TopicFilter。2.5、TopicName•消息的标签。•Server推送消息到Client的时候用TopicName进行匹配推送。2.6、TopicFilter•前面说到Subscription由TopicFilter和maximumQoS组成,TopicFilter是一个表达式,指出一个或多个感兴趣的话题。•一个TopicFilter可以包含多个通配符。2.7、Session•Client与Server之间的一个有状态的连接交互(会话)。•某些session存活时间与网络连接有关,一旦连接断开,session失效;某些session能跨越多个连贯的网络连接(我理解的是类似session自动报活)。3、Datarepresentations•1word=2byte1byte=8bit。•由于字节存储次序,一个16-bit的字符在网络传输中呈现的格式为MostSignificantByte(MSB)+LeastSignificantByte(LSB)。•UTF-8encodedstring结构:•所有UTF-8encodedstrings长度范围为0到65535bytes4、MQTTControlPacketformat•1个MQTT数据包由3部分组成。4.1、FixedHeader•每个MQTT数据包都有一个固定的头部,格式如下:4.1.1、MQTTControlPackettype•MQTTControlPackettype占header里面第一个字节的高位4个bit,除去0和15位置属于保留待用,共14种消息事件类型:4.1.2、FlagsspecifictoeachMQTTControlPackettype•MQTTControlPackettype(决定数据包类型)对应一个flag(多数情况是保留待用,只有Publish的时候有一些参数),占header里面第一个字节的bits[3-0]DUP1=DuplicatedeliveryofaPUBLISHControlPacketQoS2=PUBLISHQualityofServiceRETAIN3=PUBLISHRetainflag4.1.3、RemainingLength•RemainingLength表示当前数据包剩余字节数,包括Variableheader和Payload,单个字节最大值:01111111,16进制:0x7F,10进制为127。单个字节为什么不能是11111111(0xFF)呢?因为MQTT协议规定,第八位(最高位)若为1,则表示还有后续字节存在。同时MQTT协议最多允许4个字节表示剩余长度。那么最大长度为:0xFF,0xFF,0xFF,0x7F,二进制表示为:11111111,11111111,11111111,01111111,十进制:268435455byte=261120KB=256MB=0.25GB四个字节之间值的范围:4.2、Variableheader•固定头部仅定义了消息类型和一些标志位。•一些消息的元数据,需要放入可变头部中。可变头部的内容根据Packettype的不同而不同,一般包含了ProtocolName,ProtocolLevel,ConnectFlags,KeepAlive.等内容。•某些情况下,可变头部包含了数据包ID。•第5节见详细数据格式。4.2.1、PacketIdentifier4.3、Payload•消息体主要是为配合固定/可变头部命令(比如CONNECT可变头部Username标记若为1则需要在消息体中附加用户名称字符串)而存在。•CONNECT/SUBSCRIBE/SUBACK/PUBLISH等消息有消息体。PUBLISH的消息体以二进制形式表示。5、CONNECTPackets•当Client与Server成功建立连接,Client给Server发的第一个包必须是CONNECT包。•一个Client只能发送一次CONNECT包,如果发送第二次,Server就会认为此Client违法协议,断开此Client的连接。5.1、CONNECTPackets的Fixedheader•参考前面第4.1节提到的固定头部,此为CONNECTPackets的固定头部。5.2、CONNECTPackets的Variableheader•前面第4.2节说到可变头部的内容根据Packettype的不同而不同,CONNECT包按顺序由4部分组成:协议名称ProtocolName,ProtocolLevel,ConnectFlags,KeepAlive.5.2.1、CONNECTPackets的Variableheader的ProtocolName•协议名称固定为“MQTT”的UTF-8编码字符串对应二进制码。•防火墙或其他网络监测工具根据ProtocolName监测MQTT流量。5.2.2、CONNECTPackets的Variableheader的ProtocolLevel•用8位无符号二进制码表示协议版本号,版本3.1.1用4表示,以此类推。•如果Server不支持当前接收到的包协议版本,则需要返回给Client一个CONNACK包(内容为错误码0x01表示unacceptableprotocollevel),随后断开此client的连接。5.2.3、CONNECTPackets的Variableheader的ConnectFlags•ConnectFlags包含一系列参数,可以指明payload有没有东西。•Server必须验证低位的Reservedflag是否为0,如过不为0则断开连接。5.2.3.1、CONNECTPackets的Variableheader的ConnectFlags的UserNameFlag•位于ConnectFlags的最高位(bit7)。•如果UserNameFlag被设为0,Payload不能有username值。•如果UserNameFlag被设为1,Payload必须有username值。5.2.3.2、CONNECTPackets的Variableheader的ConnectFlags的PasswordFlag•如果PasswordFlag被设为0,Payload不能有Password值。•如果PasswordFlag被设为1,Payload必须有Password值。•如果UserNameFlag被设为0,PasswordFlag必须设为0。5.2.3.3、CONNECTPackets的Variableheader的ConnectFlags的WillFlag•如果WillFlag被设为1,则表明如果连接请求被接收,一个与此连接对应的WillMessage必须被保存在Server,而且当连接被偶然关闭时这个WillMessage必须被发布除非这个WillMessage被Server收到DISCONNECT包时删掉了。•连接被偶然关闭,该message被发布的几种情况:I/O错误或者网络错误Client在KeepAliveTime之内与Server通讯失败。Client主动关闭连接并且未给Server发DISCONNECT包。Server因为协议错误关闭连接。•如过WillFlag被设为1,WillQoS和WillRetain被Server读取并处理,Payload必须包含willTopic和WillMessage。•一旦WillMessage被发布或者Server收到Client发来的DISCONNECT包时,WillMessage必须被删除(存储与Server的SessionState)•如过WillFlag被设为0,WillQoS和WillRetain被Server必须设为0,Payload必须不包含willTopic和WillMessage。•如过WillFlag被设为0,当网络连接结束时WillMessage不能被发布。5.2.3.4、CONNECTPackets的Variableheader的ConnectFlags的WillRetain•指定当消息publish的时候是否需要被保留。•如果WillFlag被设为0,WillRetainFlag必须设为0。•如果WillFlag被设为1,且WillRetain被设为0,则Server发布message的时候必须以非保留的形式发布•如果WillFlag被设为1,且WillRetain被设为1,则Server发布message的时候必须以保留的形式发布(不光发给现有的订阅者,同时保存着,如果有新来的订阅者,也要发送。)5.2.3.5、CONNECTPackets的Variableheader的ConnectFlags的WillQoS•指定当消息publish的时候的服务质量,是至多发一次还是至少发一次还是仅发一次。•如果WillFlag被设为0,WillQoS必须设为0。•如果WillFlag被设为1,WillQoS可以被设为0,1,2但不能为3。5.2.3.6、CONNECTPackets的Variableheader的ConnectFlags的CleanSession•指定当SessionState的处理方式,控制SessionState的寿命。•如果CleanSession被设为0,Server必须以当前sessionstate为基础与Client持续通讯,若与对应Client没有session则Server必须重新建一个session,Client与Server断开后各自都要存储该session。•如果CleanSession被设为1,Client和Server都必须丢弃之前的session重新建立session以通讯,Session的寿命对应连接的寿命,当前session的任何state数据都不应该被后来的session重新使用。•Server里的SessionState的组成:Sessi
本文标题:MQTT
链接地址:https://www.777doc.com/doc-5210737 .html