MQtt 学习笔记

前言

    在互联网时代http协议负责建立网络连接,到了物联网时代,由于智能硬件的差异,相比互联网终端,硬件配置要低得多,而且智能设备的环境也相当复杂,物联网中的数据传输会面临很多问题,如何保证数据不会重复发送,连接断开后如何进行重连。而HTTP协议太过重量级,不适合物联网。因此提出一种轻量级的MQTT协议,适合于低带宽、不可靠连接、嵌入式设备、CPU、内存资源紧张,适合于各种受限环境。
    TCP/IP参考模型可以分为四层:应用层、传输层、网络层、链路层。TCP和UDP属于传输层,应用层常见的协议有HTTP、FTP、ssh等。MQTT协议运行与TCP之上,属于应用层协议,因此只要是支持TCP/IP协议栈的地方,都可以使用MQTT。


协议特征
客户端/服务器模式 vs 发布/订阅模式

     传统的网络通信模式几乎都是基于客户端/服务器模式的:客户端直接和一个服务端建立连接,通信来获取数据,数据源和数据目的地双方直接连接。比如在Web应用程序中,浏览器直接和Web服务器通过HTTP协议通信,浏览器需要知道服务器的IP和端口号。
     而发布/订阅模式解耦了客户端,客户端分为2种角色:发布者(Publisher)和订阅者(Subscriber)。每一个发布者(Publisher)可以发送不同类型的消息,我们把消息的类型叫做主题(topic),MQTT通信中的消息都属于某一个主题 ,而只有订阅了这个主题的订阅者(Subscriber)才能收到属于这个主题的消息。发布者和订阅者不需要在意和知道对方的存在(不需要知道对方的IP和端口),也不需要直接与对方建立连接。因为通信中存在着一个叫代理(MQTT broker)的第三种角色,也可以叫MQTT服务器(MQTT server)。
     发布者、订阅者只需要知道MQTT 服务器的IP和端口即可,并和它直接建立连接通信。MQTT代理作为消息的中转,它过滤所有接受到的消息,并按照一定的机制(MQTT标准规定是基于主题的消息过滤派发方式,而具体的MQTT服务器软件也提供了其他的派发方式)分发它们,使得所有注册到MQTT代理的订阅者只接收到他们订阅了的消息,而不会收到他不关心的消息。
     当发布者发布一条消息的时候,他必须同时指定消息的主题和消息的负载。MQTT代理在收到发布者发过来的消息时,无需访问消息负载,他只是访问消息的主题信息,然后根据这主题派发给订阅者。需要注意的是,一个客户端可以同时既当发布者又当订阅者。比如一个开发板连接了一盏LED灯,它可以发布灯的暗/亮状态信息,也可以从其他节点订阅对灯的控制消息。

消息格式

    每条MQTT命令消息的消息头都包含一个固定的报头,有些消息会携带一个固定报文头和一个负荷。

固定报文头 | 可变报文头 | 负荷

固定报文头(Fixed Header)
    存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。
    MQTT固定报文头最少有2个字节,第一个字节包含消息类型(Message Type)和QoS等级标志位。第二字节开始是剩余长度字段,该长度是后面的可变报文头加消息负载的总长度,该字段最多允许4个字节。

可变报文头(Variable Header)
    存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
    包含协议名、协议版本、连接标志(Connect Flag)、心跳间隔时间(Keep Alive Timer)、连接返回码(Connect Return Code)、主题名(Topic Name)等。

有效负荷(Payload)
    存在于部分MQTT数据包中,标识客户端收到的具体内容。
    实际上可以理解为消息主体(body)。当MQTT发送的消息类型是connect(连接)、publish(发布)、subscribe(订阅)、suback(订阅确认)、ubsubscribe(取消订阅)时,则会带有负荷。

消息模型

    MQTT是一种基于代理发布/订阅消息协议。提供一对多的消息分发,解除应用程序耦合。一个发布者可以对应多个订阅者。这种模式提供了更大的网络拓展性和更动态的网络拓扑。
在这里插入图片描述

协议质量

MQTT提供三种质量的服务

QoS0 : 至多一次,可能会出现丢包现象。消息要么只会到达服务器一次,要么根本没有到达。
使用在对实时性不高的情况。这一级别可应用与如下场景,如环境传感器数据,
丢失一次读记录无所谓,很快下一次记录就会生成。

QoS1 : 至少一次,保证包会到达目的地,但可能出现重复包

QoS2 : 正好一次,保证包会到达目的地,且不会出现重复包现象。
这一级别可用于计费系统等场景,在计费系统中,消息丢失或重复可能会导致生成错误的费用。

    共享单车智能锁,智能锁可以定时使用QoS0质量消息请求服务器,发送单车当前位置,如果服务器没收到也没关系,过一段时间又会发送一次。之后用户可以通过APP查询周围单车位置,找到单车后需要进行解锁,这时候可以使用QoS1质量消息,手机APP不断发送解锁消息给单车锁,确保有一次消息能到达以解锁单车。最后用户用完单车后,需要提交付款表单,可以使用QoS2质量消息,确保只传递一次数据,避免重复付款。

主题名称(Topic name)

    用来标识已发布消息的信息的渠道。订阅者用他来接收到所关心的信息。
    主题名称是一个分层的结构,用斜线“/”作为分隔符。有两种通配符可以在主题发布/订阅时使用——“#”和“+”。“#” 通配多层结构,“+”通配一层结构

一个topic:“a/b/c”,则“a/+/c”和“a/#”都可以和他相同

    发布不支持模糊匹配,必须是确定的主题。

遗嘱(Will Flag)

    当一个客户端断开连接的时候,它希望客户端能发送它指定的消息。该消息和普通消息结构相同。通过设置该位并填入和信息相关的内容即可。

消息类型 (Message Type)

    固定报文头中的第一个字节包含连接标志(Connect Flag),连接标志用来区分MQTT的消息类型。

类型名称类型值报文说明
Reserved0保留
Connect1客户端对服务端的连接请求
ConnACK2服务端对连接请求的响应
Publish3发布消息
puback4对发布消息的回应 QoS1消息确认
pubRec5收到发布消息 QoS2消息回执(保证交付第一步)
pubRel6释放发布消息 QoS2消息释放(保证交付第二步)
pubComp7完成发布消息 QoS2消息完成(保证交付第三步)
subcribe8客户端订阅请求
subBack9订阅请求回应
unsubscribe10停止订阅请求
unsubBack11停止订阅请求响应
pingReq12ping请求(保持连接)
pingResp13ping响应
disconnect14客户端正在断开
reserved15保留

开发一个MQTT库需要提供如下命令

Connect:当一个TCP/IP套接字在服务器端和客户端建立连接时需要使用的命令

publish:由客户端向服务端发送,告诉服务端自己感兴趣的Topic。
         每一个publishMessage都是与一个Topic的名字联系在一起。
         
pubRec:是publish命令的响应,使用了QoS2,是QoS2的第二条消息

pubRel:是QoS2协议的第三条消息

pubComp:是QoS2协议的第四条消息

subscribe:允许一个客户端注册自己感兴趣的Topic名字,发布到这些Topic的消息会
           以Publish Message的形式由服务器发送给客户端

unsubscribe:从客户端到服务端,退订一个Topic

ping:由客户端向服务端发送“are you alive”的消息

disconnect:断开这个TCP/IP协议

MQTT协议原理
MQTT协议实现方式

    实现MQTT协议需要客户端与服务端通讯完成,在通讯过程中,MQTT协议中有3中身份:发布者(Publish)代理(Broker)(服务器)订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者也可以同时是订阅者。
    MQTT传输的消息分为:主题(Topic)负载(payload)

主题:可以理解为消息的类型,订阅者订阅(subscribe)后,就会收到该主题的消息内容(payload)
负载:可以理解为消息的内容,是指订阅者具体要使用的内容。
网络传输与应用消息

    MQTT会构建底层网络传输。将建立客户端到服务器的连接,提供两者之间的一个无序的、无损的、基于字节流的双向传输。当应用数据通过MQTT网络发送时,MQTT会把与之相关的服务质量(QoS)和主题名(Topic)相关联。

MQTT客户端

    一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。

客户端可以:
    发布其他客户端可能会订阅的信息;
    订阅其他客户端发布的消息;
    退订或删除应用程序的消息;
    断开与服务器的连接。
MQTT服务器

    称为“消息代理(Broker)”,可以是一个应用程序或一台设备,位于消息发布者与订阅者之间。

服务器可以:
    接受来自客户的网络连接;
    接收客户发布的应用信息;
    处理来自客户端的订阅和退订请求;
    向订阅的客户转发应用程序消息。
MQTT协议中的订阅、主题、会话

订阅(Subscription)

    订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每个会话中的每个订阅都有一个不同的主题筛选器。

会话(Session)

    每个客户端与服务器建立连接后就是一个会话,客户端与服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端与服务器之间跨越多个连续的网络连接。

主题名(Topic Name)

    连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。

主题筛选器(Topic Filter)

    一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。

负载(Payload)

    消息订阅者所具体接收的内容。

MQTT协议中的方法

    MQTT协议中定义了一些方法(动作),来用于表示对确定资源所进行的操作。这个资源可以代表预先存在的数据或动态生成的数据,这取决与服务器的实现。通常来说,资源指服务器上的文件或输出。

Connect:等待与服务器建立连接
Disconnect:等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话
Subscribe:等待完成订阅
UnSubcribe:等待服务器取消客户端的一个或多个topics订阅
Publish:MQTT客户端发送消息请求,发送完成后返回应用程序线程
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值