实时通信协议是物联网技术中的一项根本性技术,在数据的有效传输、及时通信方面不可或缺,在物联网领域发挥着至关重要的作用,因此物联网通信协议的制定至关重要。目前物联网设备广泛使用的有四大实时协议XMPP、REST/HTTP、CoAP以及MQTT。XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性,但对于嵌入式设备来说,解析非常困难;REST (Representational State Transfe)是一种架构风格,即表述性状态传递,它基于HTTP定义了一组约束和属性,适用于web服务,在物联网方面主要被应用于基于HTTP web服务的转化,但对于嵌入式设备而言,目前很多物联网接入设备大多属于资源受限型设备,只拥有有限的计算能力和有限的存储空间,故相比较而言REST/HTTP属于重量级协议;由于物联网中的很多设备属于资源受限型,The Internet Engineering Task Force (IETF)提出了一种基于REST架构的CoAP协议,Constrained Application Protocol (CoAP) 是一种针对受限设备的专用Internet应用协议,CoAP是一种应用层协议,它运行于UDP协议之上,但是一对一的协议;MQTT(Message Queuing Telemetry Transport) 消息队列遥测传输,是由IBM公司主导开发的物联网及时通信协议。MQTT是为大量计算能力有限的设备所设计的,使得设备工作在低带宽、不可靠网络的环境时,能够有效地进行网络数据交互,进而使得远程传感器和控制设备能够与服务器及时通讯,故本文选作MQTT协议作为本次物联网平台的通讯协议。
MQTT协议阐述
MQTT协议由IBM主导开发的一种轻量级基于客户端-服务器的消息发布/订阅模式的消息传输协议,同时MQTT协议基于TCP协议,其运行在TCP长连接的基础上,为网络设备提供有序、可靠、双向连接的网络连接保障。作为广泛的使用物联网通讯协议,MQTT具有以下几项重要特性:
(1)轻量级
因为物联网设备的特殊性,为了保证数据在低带宽、不可靠的网络中传输有效的数据,故MQTT协议的设计原则是精简,不添加可有可无的功能,以保证协议的轻便性,因此MQTT协议头部协议字段2只有两字节,尽量保持轻量级的特性。
(2)支持发布(PUBLISH)/订阅(SUBSCRIBE)模式
使用发布/订阅模式解除了通信设备终端之间的耦合,解耦方式可以从多个方面进行加以区分,主要有空间解耦、时间解耦和同步解耦。空间解耦:支持一对多、多对一、多对多的消息传递,发布者设备与订阅者设备彼此相互独立,消息发布者与订阅者不知道彼此任何相关信息就可以实现数据交互,比如对方的IP地址和端口,方便了消息在设备之间的传递;时间解耦:发布者和订阅者无需同时运行;同步解耦:在设备消息发布或接收期间,消息发布者与订阅者的其他操作不会暂停。
(3)提供三种级别Qos消息传递类型
当Qos值为0时,为最多传输一次(At most once delivery),此种传输方式中,发送方不需要收到服务器回应,消息可能到达服务器一次,或可能根本不会到达此种传输方式属于允许消息丢失场景,性能最高;当Qos值为1时,发送放至少发送一次(At least once delivery),以确保消息到达接收方,接收方需要返回确认消息,在此情况下,接受方可能会接收到重复消息,即适合不允许消息丢失,但允许消息重复的场景,性能中等。当Qos值为2时,消息体只到达一次并且保证消息送达(Exactly once delivery)。为确保响应消息能够到达发送方,接收方必须等待发送方对接受方响应消息的响应,只有收到发送方的确认消息后,接收方才能对订阅者投递消息。
(4)提供遗嘱机制
遗嘱保留主要用于发布态(PUBLISH)的消息,当遗嘱标志(连接标志的第二位)被设置为1,并且遗嘱保留位(连接标志的第五位)被设置为1,服务器端会将此次发送的消息作为遗嘱消息保留发布,即当有新的订阅者出现,服务器会将此消息推送出去。
MQTT控制报文格式
使用MQTT协议,必须严格遵循MQTT控制报文格式来进行通信,MQTT预定义的控制报文格式较为精简,主要由三部分组成:固定报头(Fixed header)、可变报头(Variable header)、有效载荷(Payload)。控制报文结构如图所示。
固定报头
每个MQTT控制报文都必须携带一个固定报头,固定头部部分占两个字节,共16位。固定报头的控制报文格式如图所示。
MQTT控制报文类型有14种,依次为CONNECT(客户端请求连接到服务器)、CONACK(连接确认)、PUBLISH(发布消息)、PUBACK(发布确认)、PUBREC(发布初稿)、PUBREL(出版发行)、PUBCOMP(发布完整)、SUBSCRIBE(客户端订阅请求)、SUBACK(订阅确认)、UNSUBSCRIBE(退订请求)、UNSUBACK(退订确认)、PINGREQ(Ping 请求)、PINGRESP(Ping 响应)、DISCONNECT(客户端断开服务器连接)。如图所示。
控制报文类型的标志位只有在PUBLISH(发布消息)类型时有效,其他控制报文类型标志位现保留。控制报文类型的标志位重发标志DUP,在固定报头第一字节第3位,如果DUP标志为0,表示这是发送方第一次请求发送的PUBLISH报文,如果值为DUP标志位被设置为1,表示这可能是早期报文请求的重发。控制报文类型的标志位服务质量等级QoS,在固定报头第一字节2-1位,该字段表示消息传递类型。三种消息传递服务质量如图所示。
剩余长度字段是从报文段的第二个字节开始,剩余长度字段(Remaining Length)是除固定头部报文段以外的报文段,包括可变报头和负载数据。
可变报头
MQTT报文字段除了必须的固定报头,在某些MQTT控制报文中包含可变报头字段,该报文段根据各报文类型的不同而不同,具体可根据报文标识符识别。在PUBLISH控制报文、PUBACK控制报文、PUBREC控制报文、PUBREL控制报文、PUBCOMP控制报文、SUBSCRIBE控制报文、SUBACK控制报文,UNSUBSCIBE控制报文、UNSUBACK控制报文的可变头部部分都含有一个两字节的可变头部,报文标识符的作用是标识区别报文,当客户端每发送一个新的类型的报文段时,该客户端所发送的报文中必须重新分配新的报文标识符,且新的控制报文标识符必须是当前未使用的报文标识符,而当由于某种原因该客户端需要重新发送该控制报文时,重发的控制报文必须携带与原控制报文的标识符相同的报文标识符。当客户端收到该控制报文的确认信息后,才可释放该报文标识符,即下次发送控制报文时可重用该报文标识符。
有效载荷
有效载荷用于携带应用消息,位于固定首部和可变报头之后,即位于控制报文的最后部分,有效载荷不是每个控制报文必须携带的报文段,但是在CONNECT控制报文、SUBSCRIBE控制报文、SUBACK控制报文、UNSUBSCRIBE控制报文中需要携带,在PUBLISH控制报文中为可选字段,在其他控制报文中不需要携带。CONNECT控制报文段中有效载荷字段内容主要是客户端的ClientID、遗嘱主题,遗嘱消息以及用户名和密码,且必须按此顺序排列。SUBSCRIBE控制报文段中效载荷字段内容是要订阅的主题以及Qos。SUBACK控制报文段中效载荷字段内容是对SUBSCRIBE控制报文所订阅的主题的确认和回复。SUBACK控制报文段中消息体内容是要订阅的主题。
MQTT控制报文
MQTT客户端,即使用MQTT协议通讯的程序或设备,其必须依照MQTT控制报文格式发送MQTT控制报文到服务器端。MQTT共14种不同的控制报文的类型。
CONNECT报文是客户端连接到服务器端发送的第一个报文,并且,在一个网络连接上,客户端只能发送一次CONNECT控制报文,否则服务器将断开该连接,并将该报文做违规处理。CONNECT控制报文的固定报头如图所示。
客户端在成功建立TCP连接之后,发送CONNECT控制报文到服务器,服务器给出确认,客户端收到该确认消息后,会发送SUBSCRIBE控制报文到服务器订阅相应的主题列表,订阅过程中客户端设备至少订阅一个主题。SUBSCRIBE控制报文也会指定Qos服务质量等级,服务器根据该报文发送 PUBLISH报文给客户端。SUBSCRIBE控制报文固定报头格式如图所示。
PUBLISH控制报文是消息推送方推送消息到服务器,或由服务推送消息到相应主题订阅者的应用消息报文。PUBLISH报文固定报头如图2-7所示。第一个字节第三位DUP标志位为重发标志,如果DUP标志位被设置为0,表示这是客户端或服务器端第一次请求发送本报文,如果是重新发送的报文,则DUP标志应设置为1。