因为工作需要,了解了一下MQTT。顺便记下来,现在还不会用。

一、概述

MQTT(Message Queuing Telemetyr Transport  消息队列遥测传输协议):基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,该协议构建于TCP/IP协议之上。

MQTT运行于TCP之上,属于应用层协议。

二、MQTT消息格式

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

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

1、  固定报文头(Fixed Header)

最少有两个字节,第一个字节包含消息的类型(Message Type)和QoS级别等标志位。第二个字节开始是剩余长度字节,该长度是后面的可变报文头加消息负载的总长度,该字段最多允许四个字节。

剩余长度字段单个字节的最大值为0x7F. 也就是127个字节。MQTT协议规定,单个字节的最高位如果是1,表示后续还有字节存在,第八位起延续位的作用。

由于MQTT协议最多使用四个字节表示剩余长度,并且最后一个字节的最大值只能是0x7F,而不是0xFF。所以能发送的最大消息长度是256MB,而不是512MB。

2、  可变报文头(Variable Header)

主要包含协议名,协议版本,连接标志,心跳间隔时间,连接返回码,主题名等。

3、  有效负荷

实际上可以理解为消息的主体。当MQTT发送的消息类型是CONNECT(连接)、PUBLISH(发布)、SUBSCRIBE(订阅)、SUBACK(订阅确认)、UBSUNSCRIBE(取消订阅)时会带有负荷。

三、MQTT的主要特性

1、MQTT的消息类型

固定报文头中的第一个字节包含连接标志,连接标志用来区分MQTT的消息类型。MQTT协议拥有14中不同的消息类型。如下图:

可简单分为连接及终止、发布和订阅、Qos2消息的机制以及各种确认ACK。

2、消息质量(QoS)

MQTT消息质量有三个等级,QoS 0、Qos 1、Qos 2。

Qos 0:最多分发一次,消息的传递完全依赖底层的TCP/IP网络,协议里没有定义应答和重试。消息只会到达服务端一次,要么就没到达。

Qos 1:至少分发一次、服务器的消息接收由PUBACK消息进行确认,如果通信链路或设备异常,或指定时间内没有收到确认消息,发送端会重发这条在消息头中设置了Dup位的消息。

Qos 2:只分发一次。最高级别的消息传递,消息丢失和重复都是不可接受的,使用这个服务质量等级会有额外的开销。

3、遗愿标志(Will Flag)

在可变报文头的连接标志位字段(Connect Flags)里面有三个will标志位:Will Flag  Will Qos和Retain Flag。这些will字段用于监控客户端与服务器之间的连接状况。

遗愿消息:服务器与客户端通信时,当遇到异常或客户端心跳超时的情况,MQTT服务器会替客户端发布一个will消息。当然如果服务器收到来自客户端的DISCONNECT消息则不会触发wiwll消息的发送。因此will字段可以应用于设备掉线后通知用户的场景

4、  连接保活心跳机制(keep Alive Timer)

MQTT客户端可以设置一个心跳间隔时间(keep Alive Timer),表示在每个心跳检测时间内发送一条消息。如果在这个时间周期内,没有业务数据相关的消息,客户端会发送一个PINGREQ消息,相应的,服务器会返回一个PINGRESP消息进行确认。

如果服务器在一个半(1.5)个心跳间隔时间周期内没有收到来自客户端的消息,就会断开与客户端的连接。心跳间隔时间最大值可以设置为18个小时,8表示客户端不会断开。

四、MQTT其他特点

1、异步发布/订阅实现

发布/订阅模式解耦了发布消息的客户(发布者)和订阅消息的客户(订阅者)之间的关系。发布者与订阅者并不需要直接建立联系。

这个模式的好处有:

1)  发布者与订阅者只需要知道同一个消息代理即可。

2)  发布者与订阅者不需要直接交互,不需要同时在线。

2、二进制格式实现

MQTT基于二进制而不是字符串。固定报文头仅有两个字节,相比于其他协议(HTTPS 和XMPP都是基于字符串实现,有冗长的头部),发送一条消息更省流量

3、MQTT的安全

由于MQTT运行于TCP层之上并且以明文传输,可以使用Wireshark看到MQTT发送的所有消息,消息指令一览无遗。这会带来一定的风险:

1)  设备可能会被盗用

2)  客户端和服务端的静态数据可能是可访问的(可能会被修改)

3)  协议行为可能有副作用(如计时器攻击)

4)  拒绝服务攻击

5)  通信可能会被拦截 修改 重定向或者泄露

6)  虚假控制报文注入

作为传输协议,MQTT只关注消息传输,提供安全功能是开发者的责任。

4、认证

支持两种层次的认证

1)  应用层:MQTT支持客户标识,用户名和密码认证

客户标识:MQTT客户端可以发送最多65535个字符作为客户标识,一般来说可以使用嵌入式芯片的MAC地址或芯片序列号。

用户名和密码:支持通过CONNECT消息的USERNAME和password字段发送用户名和密码。但是由于是用的明文传输,抓包工具很容易就获取。

2)  传输层:传输层可以使用TLS,除了加密通讯,还可以使用X509证书来认证设备。

在传输层认证是这样的:MQTT代理在TLS握手成功之后可以继续发送客户端的X509证书来认证设备,如果设备不合法就中断连接。

5、  选择用户数据格式

MQTT协议只实现了传送消息的格式,并没有限制用户协议需要按照特定风格。因此在MQTT协议之上,我们需要定义一套自己的通信协议。就可以有下面几种选择了、

1)  十六进制/二进制:

失去了可读性,可以将流量控制的比较小。单片开发可能会比较喜欢用这个。

2)  字符串:

这个会方便阅读。对于高级语言开发者来说,字符串依旧不是最佳选择。键值对(Key-value)才是最优形式。

3)  JSON:

在这门语言中,一切都是对象。因此任何支持的类型都可以通过JSON来表示。例如字符串、数字、对象、数组等、

语法规则是:对象表示键值对、数据用逗号分开、花括号保存对象、方括号保存数组。

JSON层次结构简洁清晰,便于阅读和编写,易于机器解析和生成,有效提升网络传输效率。

4)  XML:

综上,MQTT+JSON是最优解。

五、总结

MQTT基于异步发布/订阅的实现解耦了消息发布者和订阅者,基于二进制的实现节省了存储空间及流量,同时拥有更好的消息处理机制。

MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议

以上 参考https://blog.csdn.net/anxianfeng55555/article/details/80908795

参考:https://www.cnblogs.com/zhangyu1024/p/6141818.html

补充几个概念:

参考:https://www.jianshu.com/p/ecde412d2eeb

  • MQTT 客户端

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

    • 可以发布信息,其他客户端可以订阅该信息

    • 订阅其它客户端发布的消息

    • 退订或删除应用程序的消息

    • 断开与服务器连接

  • MQTT 服务器

    MQTT 服务器以称为 Broker(消息代理),以是一个应用程序或一台设备。它是位于消息发布者 和订阅者之间

    • 接受来自客户端的网络连接
    • 接受客户端发布的应用信息
    • 处理来自客户端的订阅和退订请求
    • 向订阅的客户转发应用程序消息
  • 主题(Topic)

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

    • 要订阅的主题。一个主题可以有多个级别,级别之间用斜杠字符分隔。例如,/worldemq/emqtt/emqx 是有效的主题。

    • 订阅者的Topic name支持通配符#和+ :

      • # 支持一个主题内任意级别话题
      • +只匹配一个主题级别的通配符
    • 客户端成功订阅某个主题后,代理会返回一条 SUBACK 消息,其中包含一个或多个 returnCode 参数

  • 主题筛选器(Topic Filter)

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

  • QoS(消息传递的服务质量水平)

    服务质量,标志表明此主题范围内的消息传送到客户端所需的一致程度。

    • 值 0:不可靠,消息基本上仅传送一次,如果当时客户端不可用,则会丢失该消息。
    • 值 1:消息应传送至少 1 次。
    • 值 2:消息仅传送一次。
  • 会话(Session)

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

  • 订阅(Subscription)

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

    • 客户端在成功建立TCP连接之后,发送CONNECT消息,在得到服务器端授权允许建立彼此连接的CONNACK消息之后,客户端会发送SUBSCRIBE消息,订阅感兴趣的Topic主题列表(至少一个主题)
    • 订阅的主题名称采用UTF-8编码,然后紧跟着对应的QoS值
  • 发布(publish)

    控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息,MQTT 客户端发送消息请求,发送完成后返回应用程序线程

    • 比如安卓的推送服务,还有一些即时通信软件如微信等也是采用的推送技术。
  • 负载(Payload)

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

MQTT学习笔记的更多相关文章

  1. MQTT学习笔记——Yeelink MQTT维修 采用mqtt.js和paho-mqtt

    0 前言     2014年8月yeelink推出基于MQTT协议的开关类型设备控制API.相比于基于HTTP RESTful的轮训方式,通过订阅相关主题消息,能够远程控制类应用实时性更好. 本文使用 ...

  2. 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用

    http://blog.csdn.net/xukai871105/article/details/39252653 0 前言     MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...

  3. MQTT 学习笔记

    MQTT特点 MQTT协议是为大量计算能力有限,且工作在低带宽.不可靠的网络的远程传感器和控制设备通讯而设计的协议. 1.使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合 2.对负载内容 ...

  4. 物联网学习笔记三:物联网网关协议比较:MQTT 和 Modbus

    物联网学习笔记三:物联网网关协议比较:MQTT 和 Modbus 物联网 (IoT) 不只是新技术,还是与旧技术的集成,其关键在于通信.可用的通信方法各不相同,但是,各种不同的协议在将海量“事物”连接 ...

  5. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  6. Nodejs学习笔记(十六)—Pomelo介绍&入门

    前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...

  7. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  8. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  9. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

随机推荐

  1. 用c#查询各快递物流信息

    前面介绍过<用快递100接口查询各快递物流信息>,里面用的是API接口,但有些快递不支持这种方式,本文介绍的HtmlAPI支持所有快递公司. 支持包括EMS.邮政.顺丰和申通在内的所有公司 ...

  2. [NOI2005]月下柠檬树(计算几何+积分)

    题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔 地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思 索着人生的哲理. 李哲是一个喜爱思考的孩子,当他看 ...

  3. Java复习总结——注解

    注解 概念及作用 概念 注解即元数据,就是源代码的元数据 注解在代码中添加信息提供了一种形式化的方法,可以在后续中更方便的 使用这些数据 Annotation是一种应用于类.方法.参数.变量.构造器及 ...

  4. 【洛谷P1483】序列变换

    题目大意:给定一个长度为 N 的序列,有 M 个操作,支持将下标为 x 的倍数的数都加上 y,查询下标为 i 的元素的值. 题解:由于查询操作很少,相对的,修改操作很多.若直接模拟修改操作,即:枚举倍 ...

  5. 模块---hashlib、configparse、logging

    一.hashlib模块 hashlib模块介绍:hashlib这个模块提供了摘要算法,例如 MD5.hsa1 摘要算法又称为哈希算法,它是通过一个函数,把任意长度的数据转换为一个长度固定的数据串,这个 ...

  6. Mybatis 中获得 connection

    转: Mybatis 中获得 connection 2012年07月30日 19:02:21 dqsweet 阅读数:13861   @Autowired private SqlSession sql ...

  7. Codeforces Gym 191033 E. Explosion Exploit (记忆化搜索+状压)

    E. Explosion Exploit time limit per test 2.0 s memory limit per test 256 MB input standard input out ...

  8. springboot 修改页面不重启

    shifr+alt+commond+/ <!-- 热部署模块 --><dependency> <groupId>org.springframework.boot&l ...

  9. qml:: QVariant转为自定义类型

    QVariant可以实现C++与qml之间的自定义类型的传递: 以QObject类型为例: 1.  QObject转为QVariant QVariant var = QVariant::fromVal ...

  10. eclipse新建maven项目默认jre为1.5的问题

    在maven的settings.xml中添加如下内容解决 <profiles> <profile> <id>jdk-1.8</id> <activ ...