美文网首页
对mqtt协议Qos2服务质量等级的理解

对mqtt协议Qos2服务质量等级的理解

作者: 大风过岗 | 来源:发表于2019-12-25 14:28 被阅读0次

    publish报文

    publish报文的发生方向

    发生的方向是:双向的,既可以从客户端发往服务器端,又可以从服务器端发往客户端。

    客户端使用 PUBLISH 报文发送应用消息给服务端, 目的是分发到其它订阅匹配的客户端。
    服务端使用 PUBLISH 报文发送应用消息给每一个订阅匹配的客户端。

    publish报文的结构

    固定报头:
       1、固定报头中的重发标志dup:
                  如果是第一次发送此报文,则置dup=0
                  如果是重发报文, 则置dup=1
      2、服务质量等级
                   Qos=0
                   Qos=1
                   Qos=2
      3、保留标志
             保留标志的可选值:  retain=1    retain=0
    
    
    可变报头:
      1、主题名 topicName
      2、报文标识符,只有当Qos=1或2时,pub报文中才有报文标识符
    有效载荷
          由应用指定的数据
    
    

    Qos1级别的publish报文

    服务质量Qos1会确保消息至少送达一次。Qos1的publish报文的可变报头中包含一个报文标识符,需要pubAck报文确认。

    对于Qos1的分发协议,发送者:

    - 每次发送新的应用消息都分配一个未使用的报文标识符
    
    - 发送的publish报文必须包含报文标识符且Qos等于1,dup等于0。
    
    - 必须将这个publish报文看作是未确认的,直到从接收者那里收到对应的pubAck报文
    

    对于Qos1的分发协议的接收者:

    • 响应的pubAck报文必须包含一个报文标识符,这个标识符来自接收到的,已经接收所有权的
      publish报文

    • 发送pubAck报文之后,接收者必须将任何包含相同报文标识符的入站publish报文当作一个新的
      消息,并忽略它的DUP标志的值

    Qos1的协议的交互流程图

    下面这张图是:Qos1的交互流程图:


    mqttQos1报文交互 (3).jpg

    Qos1级别的pub报文的缺陷

    消息重复的问题

    在上图中,我们可以看到,对于发送方来说,当它发送一个pub报文时,它会一直等待着来自对方(接收方)的消息确认报文pubAck。只有收到pubAck报文之后,它才认为该pub报文已经发送成功,否则,就会执行重试。
    即: 再次发送该pub报文给客户端直到收到pubAck确认已经发生成功为止。

    但是,这里有个问题,那就是: 如果接收方已经收到了pub报文,而且它也把pubAck报文发送出去了,但是由于网络状况太差或者其他原因,导致了这个pubAck报文丢失了,发送方接收不到来自接收方的pubAck确认报文。
    于是,发送方就会对此pub报文进行二次重发,这样的话,接收方就又收到了一条和原来一模一样的pub报文,实际上由于接收方之前就已经收到并处理过该报文了,所以这次报文对接收方来说,就是一条重复报文。

    可见,导致重复消息的原因就是: pubAck报文在网络传输中丢失造成的。

    Qos2解决Qos1的重复消息问题

    Qos2是最高的服务质量等级,消息丢失和重复都是不可接收的。但是使用这个服务质量等级会有额外的开销。

    两步确认过程

    Qos2的pub报文的接收者使用一个两步确认过程来确认收到。

    发送方和接收方的处理

    对于Qos2的发送方来说:

      . 必须要给要发送的新应用消息分配一个未使用的报文标识符。
    
      . 发送的pub报文必须包含报文标识符且报文的Qos等于2,dup等于0.
    
      . 必须将这个pub报文看作是未确认的,直到从接收者那收到pubRec报文。
    
      . 收到pubRec报文后必须发送一个pubRel报文,pubRel报文必须包含与原始的pub报文相同的报文标识符
    
      . 必须将这个pubRel报文看作是未确认的,直到从接收者那收到对应的pubComp报文
    
      . 一旦发送了对应的pubRel报文就不能重发这个publish报文了。
    

    对于Qos2的接收者来说:

    . 响应的pubRec报文必须包含报文标识符,这个标识符来自接收到的、已经接收所有权的publish报文。
    
    . 在收到对应的pubRel报文之前,接收者必须发送pubRec报文确认任何后续的具有相同标识符的pub报文。
    
    . 响应的pubRel报文的pubComp报文必须包含与pubRel报文相同的报文标识符
    
    . 发送pubComp报文之后,接收者必须将包含相同报文标识符的任何后续的pub报文当做一个新的发布。  
    

    Qos2的交互流程

    mqttQos2报文交互 .jpg

    我们知道,Qos1的消息重复问题的根源在于:pubAck报文的丢失导致。

    所以,如果我们要解决消息的重复问题,就必须致力于解决 pubAck报文的丢失问题,在Qos2中,对应的就是pubRec报文的丢失问题。
    即:确保发送方一定可以收到来自接收方的pubRec报文。所以这里就引出了:2步确认过程。

    step1:  第一次使用应答机制来对pub报文进行确认,从而确保接收方一定可以接收到pub报文。
    
    step2:  第二次使用应答机制来对pubRec报文进行确认,从而确保发送方一定可以接收到pubRec报文。
    

    可见:

    1、pubRec 是对pub的保证,确保pub不会丢失
    2、pubRel 是pubRec的保证,确保pubRec不会丢失
    3、pubComp是pubRel的保证,确保pubRel不会丢失


    如果sender没有收到pubRec,就要重发该pub。

    如果receiver没有收到pubRel,就会重发pubRec。

    如果sender没有接收到pubComp,就会重发pubRel。


    • 对于接收方来说,收到pubRel报文之后,它的使命就完成了。(即: 它不仅收到了pub消息,而且确信自己也已把pubRec报文送到了发送方。)

    • 对于发送方来说,收到了pubRec报文,就意味着,pub报文已经被接收方确定接收了。收到了pubComp报文,就意味着,pubRel报文已经确定被接收方接收了。

    相关文章

      网友评论

          本文标题:对mqtt协议Qos2服务质量等级的理解

          本文链接:https://www.haomeiwen.com/subject/wdqcoctx.html