上一章节中已经知道了MQTT中报文的基本结构:

总结:

  • 固定报头:类似于人的名字,是一个代号信息
  • 可变报头:特异性信息
  • 负载:报文中的特异性信息的载体

本文对控制报文的研究不涉及到socket编程,只研究报文大概的工作模式以理解MQTT的工作方式。Socket编程

本章中主要介绍几个重点的报文格式,具体的socket实现可以参考文章。其他报文的格式大同小异,可以查阅官方文档


CONNECT报文

CONNECT报文有且只有一个,并且是客户端到服务端 建立连接 后的第一个报文,服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接。

1.固定头部

固定头部同前面说明的一样,包含报文类型和保留字段。具体格式如下:

CONNECT报文固定头部
2.可变头部

CONNECT报文的可变报头按下列次序包含四个字段:

  • 协议名(Protocol Name)
  • 协议级别(Protocol Level)
  • 连接标志(Connect Flags)
  • 保持连接(Keep Alive)。
2.1 协议名

协议名是表示协议名 MQTT 的UTF-8编码的字符串。MQTT规范的后续版本不会改变这个字符串的偏移和长度。如果协议名不正确,服务端需要断开客户端的连接。

协议名格式如下:

CONNECT中的协议名
2.2 协议级别

协议级别通俗来讲就是协议的版本。

客户端用8位的无符号值表示协议的修订版本。对于3.1.1版协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。

MQTT3.1.1的协议级别格式如下:

协议级别
2.3 连接标志

连接标志字节包含一些用于指定MQTT连接行为的参数。它还指出playload字段是否存在。

连接标志的结构:

连接标志

备注
1.有效负载(playload)字段的存在与否并不是reserved字段来指定,而是will flag、user Name等字段。比如:如果will flag为1,则负载中需要包含will tpoic、will message等字段。如果需要用户名密码,则负载中需要包含这些信息。
2.服务端必须验证CONNECT控制报文的保留标志位(第0位reserved)是否为0,如果不为0必须断开客户端连接

所有连接标志的意义:

标志明 位置 意义
Clean Session 连接标志字节的第1位 告诉服务端是否需要基于客户端标识符,在对应的会话(session)中保存连接断开过程中收到的级别为Qos1和Qos2的消息并在连接恢复后想客户端进行分发
Will Flag 连接标志的第2位 是否开启遗嘱消息模式,如果为YES,则服务端需要存储负载中客户端发送的will topic和will message
Will Qos 连接标志的第4和第3位 遗嘱消息的安全级别,占用2byte,值为0、1、2
Will Retain 连接标志的第5位 遗嘱消息是否需要作为保留消息发布
Password Flag 连接标志的第6位。 是否需要密码
User Name Flag 连接标志的第7位 是否需要用户名
2.4 Keep alive

是一个以秒为单位的最大时间间隔,表示为一个16位的字。
其格式如下:

keep alive

备注:
MSB表示最大有效为,LSB表示最小有效位。这里没有什么特殊含义,也不MSB也不表示正负,这里只是表示两个字节来描述Keep alive。至于官方文档中说明Keep Alive允许的最大值是18小时12分15秒,这是从2^16/3600=18.2044得出的

Keep Alive说明:

  • 客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。不管保持连接的值是多少,客户端任何时候都可以发送PINGREQ报文,并且使用PINGRESP报文判断网络和服务端的活动状态。

  • 如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。

  • 客户端发送了PINGREQ报文之后,如果在合理的时间内仍没有收到PINGRESP报文,它应该关闭到服务端的网络连接。

  • 保持连接的值为零表示关闭保持连接功能。这意味着客户端不断开连接。

备注:
不管保持连接的值是多少,任何时候,只要服务端认为客户端是不活跃或无响应的,可以断开客户端的连接。

至此,CONNECT报文的所有内容已经学习,最后用官方文档的CONNECT结构图来总结:

CONNECT报文

CONNACK报文

CONNACK报文内容固定如下:

CONNACK

安全级别(Qos)

安全级别主要应用在消息发布中,三种安全级别的消息发送机制如下:

Qos

Will Message

MQTT中的遗嘱模式是什么:
服务端或者客户端异常断开时,服务端需要将特定主题(will topic)的消息(will message)发送给订阅过该主题的客户端。

遗嘱消息发布的条件,包括但不限于:

  • 服务端检测到了一个I/O错误或者网络故障。
  • 客户端在保持连接(Keep Alive)的时间内未能通讯。
  • 客户端没有先发送DISCONNECT报文直接关闭了网络连接。
  • 由于协议错误服务端关闭了网络连接。

客户端正常的使用DISCONNECT报文断开连接的情况下,will message不会被发送。will message只用于客户端异常断开连接时,服务端发送一组特定主题(topic)的消息(message)


RETAIN(保留消息)

什么是保留机制:
简而言之就是客户端告诉这条消息是否需要分发给之后建立连接的新客户

保留消息的工作机制:

RETAIN消息的工作机制

注意:

  • 图中retain=1,qos=0的情况,此时服务端需要清空该topic的所有消息
  • retain后的qos为0的消息仍然会发送,只是发送机制不同于Qos1和Qos2,具体见下一章节。
  • 保留消息不是服务端会话状态的一部分,会话终止时不能删除保留消息,服务端应该保留那种消息直到客户端删除它。(如何删除:客户端发送RETAIN=1 Qos=0的消息)

疑问:
如果will message的retain标志位1。当客户端正常disconnect时,服务端删除的是服务端存储的will message还是session中的will message?也就是说,正常断开连接后,如果另外一个client建立了一个新的连接并订阅了那个will topic,此时该client是否能收到will message?
初步结论:通过retain和will的设计目的来讲,当正常DISCONNECT时,服务端会删除服务端保存的will message,也就是新进的client不会收到这个已删除的will message

MQTT教程(二):MQTT中的可变报头相关推荐

  1. STM32物联网实战教程(二)—MQTT协议简介

    Author:果果小师弟 电子信息专业在读研究生 有一点思考,有一点想法,有一点理性! 定个小小目标,努力成为习惯!在最美的年华遇见更好的自己! CSDN@果果小师弟,CSDN首发,果果原创 个人主页 ...

  2. Unittest自动化测试框架教程(二)——Python中Fixture测试夹具的使用和setUp方法相关参数传递

    "此文基于系列作品 Unittest自动化测试框架教程(一)--测试用例基本框架介绍 基础上编写,初学者访问此文建议快速浏览链接文章熟悉测试用例基本框架,高手可直接上手阅读 ~ " ...

  3. lsdyna如何设置set中的node_list_Redis 系列教程(二)Redis中的五种数据类型

    上篇文章我们介绍了如何在Linux中安装Redis,本文我们来了解下Redis中的五种数据类型. 五大数据类型介绍 redis 中的数据都是以 key/value 的形式存储的,五大数据类型主要是指 ...

  4. 图文手把手教程--ESP32 MQTT对接EMQX本地服务器(VSCODE+ESP-IDF)

    本文内容 1)使用MQTT_TCP例程,ESP32通过MQTT协议与MQTT本地服务器(EMQX)进行通信. 2)如何搭建EMQX MQTT本地服务器. 3)如何使用MQTT.fx客户端调试工具或MQ ...

  5. (翻译)开始iOS 7中自动布局教程(二)

     (翻译)开始iOS 7中自动布局教程(二) 这篇教程的前半部分被翻译出来很久了,我也是通过这个教程学会的IOS自动布局.但是后半部分(即本篇)一直未有翻译,正好最近跳坑翻译,就寻来这篇教程,进行 ...

  6. 学习太极创客 — MQTT(二)MQTT 基本原理

    视频教程链接: https://www.bilibili.com/video/BV1pv411r7Cv?spm_id_from=333.999.0.0&vd_source=b91967c499 ...

  7. 太极创客ESP8266 - NodeMCU、JSON、MQTT教程(基于Arduino)

    太极创客ESP8266视频教程:https://www.bilibili.com/video/BV1L7411c7jw?from=search&seid=4858784806004995732 ...

  8. 大学英语综合教程二 Unit 5 课文内容英译中 中英翻译

    大学英语综合教程二 Unit 5 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文 ...

  9. 大学英语综合教程二 Unit 4 课文内容英译中 中英翻译

    大学英语综合教程二 Unit 4 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文 ...

  10. 大学英语综合教程二 Unit 3 课文内容英译中 中英翻译

    大学英语综合教程二 Unit 3 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文 ...

最新文章

  1. Java项目:药店信息管理系统(java+SSM+JSP+layui+maven+mysql)
  2. 极速发展的饿了么订单系统架构演进
  3. c:forEach items=${list} var=tt varStatus=status 的相关大小长度
  4. iOS9 Search API 之 Spotlight
  5. python中常见的运行时错误_17个常见的Python运行时错误
  6. php云和骑士哪家好,PHP云人才系统与骑士cms人才系统对比点评
  7. 远程访问CENTOS的MYSQL数据库设置
  8. 使用 ssh 命令来访问(登录/连接)远程服务器主机
  9. 网络、通信术语及概念
  10. 英特尔携手ATT和爱立信进行DIRECTV NOW流媒体直播服务的5G试验
  11. leetcode第26题:删除排序数组的重复项
  12. 利用反射获取程序集下所有符合条件的类及其属性
  13. swf文件的反编译入门
  14. 北京自贸区国际商务服务片区挂牌 总面积48平方公里
  15. html实现背景图片自动更换,HTML实现背景图片的替换
  16. 全国法院名录json
  17. matlab中complex的详细用法,Matlab基本函数-complex函数
  18. 闲鱼怎么用快手做引流,快手怎么找痛点引流
  19. Google Play Console beta 版全新发布
  20. 如何将css文件引入到项目当中

热门文章

  1. MyCat基于MySQL实现读写分离
  2. 在java开发中关于class.getResourceAsStream(String name)与 class.getClassLoader().getResourceAsStream(String
  3. Linux重定向和管道的基础学习
  4. ORACLE 包内的存储过程的动态sql
  5. MOSS2007匿名调查列表使用分页符导致的错误分析
  6. WinServer2003秘笈放送
  7. CLion开发,运行报错后问题排查
  8. [2018.10.25 T3] 旅程
  9. dialog的二次封装
  10. bootstrap学习笔记-(1-初识bootstrap)