1. 程式人生 > >EMQ 學習---MQTT消息QoS

EMQ 學習---MQTT消息QoS

之間 ssa sock 傳輸 class soc 學習 png ==

MQTT發布消息QoS保證不是端到端的,是客戶端與服務器之間的。訂閱者收到MQTT消息的QoS級別,最終取決於發布消息的QoS和主題訂閱的QoS。

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

客戶端連接:

客戶端完成TCP三次握手之後,還需要發起CONNECT命令

註意:如果客戶端三次握手之後,不發起MQTT的CONNECT命令,30s之後會被服務器斷掉。

emqttd.config文件有定義這個時間間隔:

 %% Client
        {client, [
            %% Socket is connected, but no ‘CONNECT‘ packet received
            {idle_timeout, 30} %% seconds
        ]},

只有QoS==1,2時候,才有Store(Msg)之說;QoS==0時沒有。

我們以第一種action為例(註意這裏第一種action存儲的是message,第二種action存儲的是message ID):
1 若client沒收到來自sever的pubcomp:那麽client將重發pubrel,意思是sever將收到兩次pubrel;但是sever並不會將消息發送兩次,因為在第一次將消息發送給訂閱者之後,server將刪除這條消息的內容(delete message),而消息的內容是在publish中傳輸的,而不是在pubrel中傳輸的;
2 若client沒收到來自server的pubrec,那麽client將重發publish,意思是sever將收到兩次publish,但是這裏sever只是存儲了信息,而且後面在pubrec中會有消息的ID,而client可以根據兩次ID是否相同來判斷server收到了幾次同樣的消息。
綜上所述,這就保證了server不會將消息重發。

對於QoS2,增加了一個PUBREL及PUBCOM的過程,這樣可以保證server端只publish一條message給他的subscriber。但是QoS1是只要sever接收到message就會publish給他的subscriber,網絡不好的時候sender是會重復發送相同的message的,server也就會重復publish相同的message給他的。

QoS2的server端處理邏輯有點特別:

如果sender沒收到server的PUBRECV, sender 是會重發,但是對於頭上一條message,server有兩種處理方式:1, message存在本地,先不publish給subscriber;2,存下message ID,把message publish 給他的subscriber。

對於第一種處理方式,如果sender繼續重發,且被收到(ID相同),那在server端只算一條message,繼續等sender發PUBREL,這樣server就保證只publish了一條message,而不是多條。

對於第二種處理方式,如果sender繼續重發,且被收到,sever會檢查它的message ID,如果重發過來的message ID是之前存過的,server就不會publish給他的subscriber,因為之前已經publish了。直接刪除。

總之,QoS==1,2時候,有Store(Msg)和唯一的MessageID來保證消息不會重復接收和發送!

EMQ 學習---MQTT消息QoS