客户端/服务器的发布消息行为,与PUBLISH相关的消息类型:

PUBLISH

客户端发布消息经由服务器分发到所有对应的订阅者那里。一个订阅者可以订阅若干个主题(Topic name),但一个PUBLISH消息只能拥有一个主题。

消息架构一览:

  Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1   Message Type(3) DUP flag QoS level RETAIN
    0 0 1 1 0 0 1 0
byte 2 Remaining Length
Variable header/可变头部
Topic name
byte 1 Length MSB (0) 0 0 0 0 0 0 0 0
byte 2 Length LSB (3) 0 0 0 0 0 0 1 1
byte 3 'a' (0x61) 0 1 1 0 0 0 0 1
byte 4 '/' (0x2F) 0 0 1 0 1 1 1 1
byte 5 'b' (0x62) 0 1 1 0 0 0 1 0
Message Identifier
byte 6 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 7 Message ID LSB (10) 0 0 0 0 1 0 1 0
Playload/消息体
BLOB,二进制对象形式。二进制具体包含的内容和格式,可有应用程序自身定义。若消息体为空(0长度)也是可能的。

固定头部

DUP flag,设为0,表示当前为第一次发送。

RETAIN flag,只有在PUBLISH消息中才有效。

  • 1:表示发送的消息需要一直持久保存,不但要发送给当前的订阅者,并且以后新来的订阅了此Topic name的订阅者会马上得到推送。 备注:新来乍到的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送,不是所有。
  • 0:仅仅为当前订阅者推送此消息。

可变头部

Topic name,UTF-8编码字符串形式,不支持通配符!

消息体

一般作为UTF-8编码写入接口,但不排除自定义的消息格式。

空的消息体(zero-length)的PUBLISH消息也可以是合法的。

当服务器接收到空消息体(zero-length payload)、retain = 1、具有topic name的一个PUBLISH特殊消息,表示同时满足retain = 1、相同topic name的这两个特征的被持久化PUBLISH消息,可被删除。

Response/响应

固定头部QoS level决定了消息中间件针对发布者具体需要响应的内容:

QoS Level Expected response
QoS 0 None
QoS 1 PUBACK
QoS 2 PUBREC

备注:仅仅针对发布PUBLISH消息的发布者。

Actions:

无论是订阅者还是服务器接收到PUBLISH消息之后,需要根据QoS level执行不同动作。

QoS Level Expected Action
QoS 0 发送到所有感兴趣者
QoS 1 持久化记录下来,发送到所有感兴趣的参与者,返回一个PUBACK消息给发送者
QoS 2 持久化记录下来,暂时不发送所有感兴趣的参与者,返回一个PUBREC消息给发送者

如果服务器收到PUBLISH消息,参与者指的是订阅者。如果订阅者收到PUBLISH消息,参与者就是服务器。 需要注意:

  1. 发布者发布的PUBLISH消息发送到服务器,在payload/消息体处可能夹带有私货,可能含有自定义的数据 格式
  2. 若兼容MQTT客户端,经由服务器分发到所有对应订阅者处只能是规规矩矩的PUBLISH消息,并且固定头部的RETAIN标志不能被设置成有效值1

授权

未经授权的发布者提交的PUBLISH消息,服务器会忽略掉,客户端不会被通知。

PUBACK

作为订阅者/服务器接收(QoS level = 1)PUBLISH消息之后对发送者的响应,整个消息不复杂。

  Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1   Message type (4) DUP flag QoS flags RETAIN
    0 1 0 0 x x x x
byte 2   Remaining Length (2)
    0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

虽没有消息体,但可变头部附加一个16位的无符号short类型。

PUBREC

字面意思为Assured publish received,作为订阅者/服务器对QoS level = 2的发布PUBLISH消息的发送方的响应,确认已经收到,为QoS level = 2消息流的第二个消息。 和PUBACK相比,除了消息类型不同外,其它都是一样。

  Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1   Message type (5) DUP flag QoS flags RETAIN
    0 1 0 1 x x x x
byte 2   Remaining Length (2)
    0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

无论是订阅者还是服务器,在消费PUBREC消息之后需要发送一个PUBREL消息给发送者(和PUBREC具有同样的消息ID),确认已收到。

PUBREL

Qos level = 2的协议流的第三个消息,有PUBLISH消息的发布者发送,参与方接收。完整示范如下:

  Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1   Message type (6) DUP flag QoS flags RETAIN
    0 1 1 0 0 0 1 x
byte 2   Remaining Length (2)
    0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

QoS level 1,PUBREL消息要求如此。

DUP flag 为0,表示消息第一次被发送。

毫无疑问,剩余长度为2个byte长度。

可变头部中,消息ID和发布者接收到的PUBREC所包含的消息ID是一致的。

动作:

  1. 服务器接收到发布者(a)的PUBREL消息,此时服务器让发布者(a)刚才发布PUBLISH消息可用,发送此PUBLISH消息给所有订阅此主题的订阅者,然后发送PUBCOMP消息给发布者(a)
  2. 可变头部包含消息ID和服务器接收的PUBREL消息ID是一致的。 一个订阅者接收到PUBREL消息,订阅者使PUBLISH消息可用,然后反馈一个PUBCOMP消息给服务器

PUBCOMP

作为QoS level = 2消息流第四个,也是最后一个消息,由收到PUBREL的一方向另一方做出的响应消息。

完整的消息一览,和PUBREL一致,除了消息类型。

  Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1   Message type (7) DUP flag QoS flags RETAIN
    0 1 1 1 x x x x
byte 2   Remaining Length (2)
    0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

当客户端接收一个PUBCOMP消息时,客户端摒弃原来的消息,因为它已经成功发送消息到服务器。

小结

消息的发布和确认等一些流程,主要是跟消息发布者所设定的QoS level有关;稍加整理,绘制了下面一张图,理解起来可能会更清晰些:

上图针对的是客户端发布消息到服务器端的方向。

为了确保消息已经成功传递过去,只有收到了确认,才会让人特别放心。

在QoS level = 2时,通信双方都需要知道各自的确认流程以及所处阶段等,交互很多,数据量大的情况下,可能会造成数据线路传递拥塞。服务器选择QoS = 0/1,大部分情况都是可以应对的。 比如重要消息,就要确保对方都要收到,然后彼此确认,OK,这个消息是真实、有效的。

无论Qos level为0、1,还是2,服务器(具备所有条件都满足之后)总要把收到的具体内容和topic组装成一个新的PUBLISH Message(也不一定要重新构造,但要求推送的PUBLISH消息,一定要具有明确的主题和内容,RETAIN标志不能设置为1)推送到所有感兴趣的订阅者。

嗯,消息的发布来源别忘记还有可能来自CONNECT消息中的Will Topic和Will Message,若是设置了Will flag标记的话。

MQTT V3.1----publish解读的更多相关文章

  1. MQTT V3.1----flow

    该文章转自:聂永的博客(http://www.blogjava.net/yongboy/archive/2014/02/15/409893.html) 网络故障 在任何网络环境下,都会出现一方连接失败 ...

  2. MQTT V3.1--我的理解

    最近因为工作需要,需要对推送消息了解,因此对MQTT进行了整理,这里更多的是对MQTT英文版的翻译和理解. MQTT(Message Queue Telemetry Transport),遥测传输协议 ...

  3. storj白皮书v3最全面解读,Docker创始人的加入能否扳倒AWS S3

    Storj新发了白皮书v3,地址是:https://storj.io/storjv3.pdf. 这次白皮书一共有90页,看完还真要费不少时间.如果你没有时间看,可以看一下我这篇快速技术解读. 上次St ...

  4. 小程序入门 MQTT物联网协议 publish 和订阅subscribe onenet 阿里云 百度云 基于GPRS模块(SIM800C/SIM900A/SIM868等)和STM32主控芯片

    本文基本公开了如何移植MQTT物联网协议到STM32平台上,并结合GPRS模块(SIM800C/SIM900A/SIM868等)实现publish和订阅topic从onenet,阿里云,百度云等.如果 ...

  5. MQTT(二)推送

    MQTT V3.1----publish解读 - leeying - 博客园 http://www.cnblogs.com/leeying/p/3791341.html MQTT - 聂永的博客 - ...

  6. MQTT协议(一)

    MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约.轻量,易于使用,针对受限环境(带宽低.网络延迟高.网络通信不稳定),可以简单 ...

  7. emqtt 试用(三)mqtt 知识

    一.概念 MQTT 协议客户端库: https://github.com/mqtt/mqtt.github.io/wiki/libraries 例如,mosquitto_sub/pub 命令行发布订阅 ...

  8. 物联网 MQTT 服务质量级别

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 翻译人:Tnecesoc,该成员来自云+社区翻译社 消息队列遥测传输(MQTT)是一种客户端服务器发布 / 订阅消息传输协议.它轻量,开放, ...

  9. Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上

    前言 诞生及优势 MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿越沙漠的石油管道.目标 ...

随机推荐

  1. 数据库操作事务IsolationLevel 枚举

      成员名称 说明   Chaos 无法覆盖隔离级别更高的事务中的挂起的更改.   ReadCommitted 在正在读取数据时保持共享锁,以避免脏读,但是在事务结束之前可以更改数据,从而导致不可重复 ...

  2. C# 向IQueryable添加一个Include扩展方法

    using System; using System.Data.Objects; using System.Linq; namespace OutOfMemory.Codes { /// <su ...

  3. nanosleep() -- 更精确的延迟 -----一个使用用例

    [常规] nanosleep() -- 更精确的延迟 [复制链接]     beyes 4220 主题 5152 帖子 3万 积分 GROAD 曲径通幽,安觅芳踪. 积分 30607 发消息 电梯直达 ...

  4. NIOS ii 流水灯

    为了做项目的前期验证工作,实验室购买了某开发板,下面是基于该板子的实现过程.作为笔记记录,供入门者参考. 1:创建一个Quartus II的工程 next选择器件,然后finish.我的器件是cycl ...

  5. RTX二次开发(二)(基于ASP.NET)

    上一篇,我们讲到我开发环境的配置,还没配置好开发环境或再看一遍开发环境配置?接下来,我们开始coding...... 在coding之前,我们先添加引用. 我们在SDK的安装目录中引用这个文件. 引用 ...

  6. [设计模式] javascript 之 享元模式;

    享元模式说明 定义:用于解决一个系统大量细粒度对象的共享问题: 关健词:分离跟共享: 说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分:单纯享元模式,只包含共享的 ...

  7. R中的par()函数的参数

    把R中par()函数的主要参数整理了一下(另外本来还整理了每个参数的帮助文档中文解释,但是太长,就分类之后,整理为图表,excel不便放上来,就放了这些表的截图)

  8. windows2003最详细的安装操作步骤.(最详细)

    以下为windows2003的安装操作步骤,由于安装操作步骤较多,安装可能需要一定的实际安装经验.安装时请参照此文档一步步完成安装. 一.首先准备好Windows2003安装光盘CD1,将CD1光盘放 ...

  9. 扁平化设计五大原则(转自CSDN翻译)

    Cousins表示他虽然对扁平化设计的感觉非常强烈,但并没有特别热爱或者特别讨厌扁平化设计.他认为好的设计不应当局限于某种设计风格,而需要更注重可用性.有用性.如果因为时尚的缘故,那就顺其自然吧.但该 ...

  10. 第三天 moyax

    struct Blog { static let BaseURL = NSURL(string: "http://192.168.1.103/blog")! } extension ...