前面讨论了MQTT协议的控制报文的格式,下面分别举例探讨各个控制报文的详细内容。

01、CONNECT – 连接服务端

  客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文。客户端在连接成功后,不能再次发送这个报文,否则服务端应按照违规处理,断开当前网络连接。一个完整的CONNECT报文见下图:

  清理会话--Clean Session(1号位)
  这个标志位是代表对会话状态的处理方式。
  如果设置为0,则服务端必须使用客户端ID找到该客户端的会话恢复通信。如果找不到这个会话则创建一个新会话,然后在断开时,必须保存这个会话信息。
  如果设置为1,则客户端和服务端都必须丢弃之前的任何会话,全新开始一个会话。会话持续时间与网络连接时间同样长。这个会话关联的状态数据不能被任何之后的会话重用。
  客户端会话关联的状态数据:
  ◆已经发送给服务端,但是还没有完成确认的QoS 1和QoS 2级别的消息
  ◆已从服务端接收,但是还没有完成确认的QoS 2级别的消息。
  服务端会话关联的状态数据:
  ◆会话是否存在,即使会话状态的其它部分都是空。
  ◆客户端的订阅信息。
  ◆已经发送给客户端,但是还没有完成确认的QoS 1和QoS 2级别的消息。
  ◆即将传输给客户端的QoS 1和QoS 2级别的消息。
  ◆已从客户端接收,但是还没有完成确认的QoS 2级别的消息。
  ◆可选,准备发送给客户端的QoS 0级别的消息。

  遗嘱标志(是否有遗嘱)--Will Flag(2号位)
  如果设置为0,本次连接没有遗嘱。
  如果设置为1,本次连接带有遗嘱,服务端必须保存遗嘱消息并与这个连接关联。本条报文中也必须包含遗嘱消息。

  遗嘱服务质量等级--Will QoS(3、4号位)
  指定遗嘱消息的服务质量等级,具体可参看前面的QoS说明。
  如果遗嘱标志为0,那么这个等级必须设置为0。如果遗嘱标志为1,这个等级可以设置0、1、2中的任何一种。

  遗嘱保留--Will Retain(5号位)
  如果设置为0,遗嘱消息作为非保留消息发布,在遗嘱标志设置为0时,这里也必须设置为0。
  如果设置为1,遗嘱消息作为非保留消息发布。

  保持连接--Keep Alive(11、12字节)
  是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。
  保持连接的值为零表示关闭保持连接功能。这意味着,服务端不需要因为客户端不活跃而断开连接。注意:不管保持连接的值是多少,任何时候,只要服务端认为客户端是不活跃或无响应的,可以断开客户端的连接。

  响应 Response
  本报文的响应报文是:CONNACK

02、CONNACK – 确认连接请求

  每次连接建立后服务端发送给客户端的第一个报文,是响应CONNECT报文的,一个完整的CONNACK报文见下图:

  当前会话--Session Present(0号位)
  如果服务端收到的连接请求中清理会话(CleanSession)标志为1,除了将本报文中的返回码设置为0外,还必须将当前会话(Session Present)标志设置为0 。
  如果服务端收到一个CleanSession为0的连接,当前会话标志的值取决于服务端是否已经保存了ClientId对应客户端的会话状态。如果服务端已经保存了会话状态,它必须将本报文中的当前会话标志设置为1 。如果服务端没有已保存的会话状态,则必须将本报文中的当前会话设置为0。还需将返回码设置为0 。
当前会话标志使服务端和客户端在是否有已存储的会话状态上保持一致。
如果服务端发送了一个包含非零返回码的CONNACK报文,它必须将当前会话标志设置为0。

03、PUBLISH – 发布消息

  是指从客户端向服务端或者服务端向客户端传输一个应用消息。一个完整的PUBLISH报文见下图:

  保留标志--RETAIN(0号位)
  如果设置为1,服务端必须存储这个应用消息和它的服务质量等级(QoS),以便它可以被分发给后期订阅匹配的订阅者。如果同时QoS=0,它必须用新的消息替换掉之前为那个主题保留的所有消息。
  服务端发送PUBLISH报文给客户端时,如果消息是作为客户端一个新订阅的结果发送,它必须将报文的保留标志设为1。当一个PUBLISH报文发送给客户端是因为匹配一个已建立的订阅时,服务端必须将保留标志设为0,不管它收到的这个消息中保留标志的值是多少。
  如果设置为0,服务端不能存储这个消息也不能移除或替换任何现存的保留消息。

  响应 Response
  本报文的响应报文是:QoS=0时不需要响应;QoS=1时是PUBACK;QoS=2时是PUBREC。

04、PUBACK –发布确认

  是对QoS 1等级的PUBLISH报文的响应。一个完整的PUBACK报文见下图:

05、PUBREC – 发布收到(QoS=2,第一步)

  是对QoS等级2的PUBLISH报文的响应。它是QoS=2等级协议交换的第二个报文。一个完整的PUBREC报文见下图:

  响应 Response
  本报文的响应报文是:PUBREL。

06、PUBREL – 发布释放(QoS 2,第二步)

  是对PUBREC报文的响应。它是QoS 2等级协议交换的第三个报文。一个完整的PUBREL报文见下图:

  响应 Response
  本报文的响应报文是:PUBCOMP。

07、PUBCOMP – 发布完成(QoS 2,第三步)

  是对PUBREL报文的响应。它是QoS 2等级协议交换的第四个(也是最后一个)报文。一个完整的PUBCOMP报文见下图:

08、SUBSCRIBE - 订阅主题

  由客户端向服务端发送的,用于创建一个或多个订阅。每个订阅是该客户端关注的一个或多个主题。服务端依据客户端的订阅来匹配主题,然后将对应的PUBLISH报文发送给客户端。本报文也(为每个订阅)指定了最大的QoS等级,服务端根据这个决定如何发送应用消息给客户端。一个完整的SUBSCRIBE报文见下图:

  响应 Response
  本报文的响应报文是:SUBACK。

09、SUBACK – 订阅确认

  服务端发送本报文给客户端,用于确认它已收到并且正在处理SUBSCRIBE报文。
  本报文包含一个返回码清单,它们指定了SUBSCRIBE请求的每个订阅被授予的最大QoS等级。一个完整的SUBACK报文见下图:

10、UNSUBSCRIBE –取消订阅

  客户端发送本报文给服务端,用于取消订阅主题。一个完整的UNSUBSCRIBE报文见下图:

  响应 Response
  本报文的响应报文是:UNSUBACK。

11、UNSUBACK – 取消订阅确认

  服务端发送本报文给客户端用于确认收到UNSUBSCRIBE报文。一个完整的UNSUBACK报文见下图:

12、PINGREQ – 心跳请求

  客户端发送本报文给服务端的。用于:
  ◆在没有任何其它控制报文从客户端发给服务的时,告知服务端客户端还活着。
  ◆请求服务端发送 响应确认它还活着。
  ◆使用网络以确认网络连接没有断开。
  保持连接(Keep Alive)处理中用到这个报文。一个完整的PINGREQ报文见下图:

  响应 Response
  本报文的响应报文是:PINGRESP。

13、PINGRESP – 心跳响应

  服务端发送本报文响应客户端的PINGREQ报文。表示服务端还活着。
  保持连接(Keep Alive)处理中用到这个报文。一个完整的PINGREQ报文见下图:

14、DISCONNECT –断开连接

  是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。一个完整的DISCONNECT报文见下图:

  关于MQTT控制报文的例说就到这里,希望对进一步理解MQTT协议能有很好的帮助。后面会继续其他内容。

  本节完,待续…

转战物联网·基础篇08-例说MQTT协议各控制报文的更多相关文章

  1. 转战物联网·基础篇07-深入理解MQTT协议之控制报文(数据包)格式

      在MQTT协议中,一个控制报文(数据包)的结构按照前后顺序分如下三部分: 结构名 中文名 解释说明 Fixed header 固定报头 报文的最开始部分,所有报文都包含这个部分 Variable ...

  2. 转战物联网·基础篇05-通俗理解MQTT协议的实现原理和异步方式

      网络上搜索MQTT协议,会出现太多的解释,这里就不做官方标准释义的复制了.这一节我们从实战理解角度,通俗的将MQTT协议的作用及实现原理说一下,旨在可以快速理解MQTT协议.所以可能会出现很多看似 ...

  3. 转战物联网·基础篇06-深入理解MQTT协议之基本术语

      通过上一节我们对MQTT协议已经有了初步的印象,这一节我们开始深入的理解一下MQTT协议,介绍常用的MQTT 3.1.1版本,5.0版本后面指介绍新增部分即可.这一节我们先介绍MQTT里常用的术语 ...

  4. 转战物联网·基础篇09-选择MQTT协议还是CoAP协议

      前面章节介绍过,MQTT协议和CoAP协议都是物联网中比较流行的协议,都对传输量做了很大的精简,传输开销小,以适应物理网的网络环境.   XMPP协议也有人说是适合物联网通信的,但它是基于XML, ...

  5. 转战物联网·基础篇03-从JSON数据到短指令谈思维的转变

      了解了物联网项目的大体结构之后,我们先从物联网的联网相关部分说起,这也是物联网项目中的关键环节.在联网环节中,不仅要考虑如何连接上,还要考虑连接后如何传输数据.换句话说数据是以什么格式进行传输,对 ...

  6. iOS系列 基础篇 08 文本与键盘

    iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...

  7. 物联网防火墙himqtt源码之MQTT协议分析

    物联网防火墙himqtt源码之MQTT协议分析 himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWall,C语言编写,采用epoll模式支持数十万 ...

  8. Java多线程系列--“基础篇”08之 join()

    概要 本章,会对Thread中join()方法进行介绍.涉及到的内容包括:1. join()介绍2. join()源码分析(基于JDK1.7.0_40)3. join()示例 转载请注明出处:http ...

  9. 【物联网云端对接-3】通过MQTT协议与微软Azure IoT Hub进行云端通信

    在上一篇文章<通过MQTT协议与阿里云物联网套件进行云端通信>中,我们介绍了通过MQTT对接阿里云的物联网套件.其实同样的代码,稍加调整也可以对接到微软Azure IoT hub上,不过需 ...

随机推荐

  1. CODING 敏捷看板全新上线,助力研发管理可视化升级

    在服务企业研发团队的过程中,我们发现不少团队碰到了类似的问题: 团队成员声称完成了自己的大部分任务,但团队实际交付的需求却寥寥无几? 由于某些问题导致工序一直处于等待状态,怎么识别和处理这些延迟? 成 ...

  2. Elon Mask 写作常见的三种错误

    (其实非常的文不对题,这篇文章和写作的并没有多大的关系,如果是想看关于写作的技巧,可以直接离开,节省您的时间) 这是原文 写作就是在把你自身的想法用正确,合适的方式表达出来,但是不正确的表达可能会导致 ...

  3. IT兄弟连 HTML5教程 CSS3属性特效 新增颜色模式

    对于设计人员和开发人员来说,CSS一直是web设计过程中重要的一部分.网页外观主要由CSS控制,编写CSS代码可以任意改变我们的网页布局以及网页内容的样式.随着CSS3的出现以及越来越多的浏览器对它的 ...

  4. SpringAOP中切入点的高级使用

    上一篇 SpringAOP之使用切入点创建通知 SpringAOP中切点的高级使用 一.使用控制流切入点(ControlFlowPointcut) 什么是控制流切入点呢?看下面的代码(为了方便,就写进 ...

  5. Python中Pyyaml模块的使用

    一.YAML是什么 YAML是专门用来写配置文件的语言,远比JSON格式方便. YAML语言的设计目标,就是方便人类读写. YAML是一种比XML和JSON更轻的文件格式,也更简单更强大,它可以通过缩 ...

  6. 一个diango项目的结构

    一个项目的结构 day43项目 .idea 配置 pycharm自动帮配的配置,打开别人的diango项目时要先删了此项 app01 方便在一个大的Django项目中,管理实现不同的业务功能 migr ...

  7. Data Guard Physical Standby - RAC Primary to RAC Standby 使用第二个网络 (Doc ID 1349977.1)

    Data Guard Physical Standby - RAC Primary to RAC Standby using a second network (Doc ID 1349977.1) A ...

  8. MATLAB实例:绘制条形图

    MATLAB实例:绘制条形图 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 用MATLAB绘制条形图,自定义条形图的颜色.图例位置.横坐标名称.显示条 ...

  9. 【2期】JVM必知必会

    JVM之内存结构图文详解 Java8 JVM内存结构变了,永久代到元空间 Java GC垃圾回收机制 不要再问我“Java 垃圾收集器”了 Java虚拟机类加载机制 Java虚拟机类加载器及双亲委派机 ...

  10. ubuntu18.04因java路径原因启动jenkins失败

    我的云服务器ubuntu18.04上本来装了jenkins,今天安装完tomcat后,将原有的openjdk卸载了,安装了jdk8u192, 此时浏览器访问8080端口显示的就是tomcat安装成功的 ...