zoukankan      html  css  js  c++  java
  • MQTT协议笔记之发布流程(NO.3)

    1. 前言

      这次要讲到客户端/服务器的发布消息行为,与PUBLISH相关的消息类型,会在这里看到

    2. PUBLISH 消息

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

      消息架构一览

         

    2.1 固定头部

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

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

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

    2.2 可变头部

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

    2.3 消息体  

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

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

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

    2.4 Response/响应

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

      

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

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

      

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

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

    2.5 授权

      未经授权(连接时进行鉴权)的发布者提交的PUBLISH消息,服务器会忽略掉,客户端不会被通知

    3. PUBACK 消息

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

      

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

    4. PUBREC

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

      

      发送者在收到 PUBREC消息之后需要发送一个PUBREL消息给发送者(和PUBREC具有同样的消息ID),确认已收到

    5. PUBREL

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

      

      QoS level 1,PUBREL消息要求如此

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

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

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

      与 PUBLISH 消息类似,订阅者或服务端收到PUBREL消息之后 ,要有对应的行动:  

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

    6. PUBCOMP

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

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

      

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

    小结

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

      上图针对的是客户端发布消息到服务器端方向的情况,为了确保消息已经成功传递过去,只有收到了确认,才会让人特别放心。

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

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

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

    转自:http://www.blogjava.net/yongboy/archive/2014/04/12/412351.html

  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/yorkyang/p/6341286.html
Copyright © 2011-2022 走看看