mqtt 获取所有topic_MQTT协议解析
- 通用IM架構
- Go實現(xiàn)Mqtt broker
MQTT協(xié)議以其效率高,語義完善而著名,非常適合使用在移動設備中,可以大幅度的減少耗電量。相對于TCP,語義更加豐富,額外的overload小,最少只需要2byte;相對于其他的應用層協(xié)議Websocket等,頭部簡單,包體積更小。
相關術語
Client(客戶端)
客戶端通常是用戶手中的移動設備,傳感器等,客戶端在整個mqtt流程中既有publisher的作用,還有subscriber的作用,當作publisher的時候,客戶端可以進行數(shù)據的上報,作為subscriber的時候,可以接收服務端推送的消息。
Session
持久化的回話,一個session對應一個client,session會把還未來得及投遞的消息進行持久化,以便下次client連接時進行推送。
Broker
服務器端,client連接的對象,保存有所有的subscriber和publisher信息及其訂閱關系,同時也用作消息的分發(fā)功能。
Subscription
訂閱關系,client可以依據topic進行訂閱,可以接收發(fā)布到該topic的信息。
Topic
Topic用作訂閱關系的維系,類似于channel的概念。
Topic Filter
主題過濾器,在MQTT中,topic可以是精確訂閱,也可以是模糊訂閱,發(fā)布到一個topic的消息,通過主題過濾器獲取所有匹配的topic進行投遞。
Publisher
發(fā)布者,通常是客戶端,向broker發(fā)布消息,borker收到消息后依據topic進行投遞。
Subscriber
訂閱者,通常是客戶端,訂閱topic以接收broker分發(fā)的消息。
數(shù)據解包
MQTT數(shù)據包共分為三部分,FixedHeader, Variable Header 和 Payload, 其中只有FixedHeader是必須的,Variable Header和Payload部分是可選的。這部分著重介紹FixedHeader,可選部分將在下面的詳細介紹中涉及。
固定頭部的長度為2...5 byte,說到這里,可能有人迷糊了,既然說的是固定頭部,怎么長度還有不同的選項呢。其實固定頭部的意思并不是說長度固定,而是說每個數(shù)據包必須包含的意思,哪怕一個數(shù)據包什么內容都沒有,也要有一個長度為2的頭部數(shù)據。那么長度不固定的固定頭部又該如何解釋呢,因為不同的場景數(shù)據包的大小也不近相同,為了能讓服務端知曉如何解析,解析到何處,就必須要把數(shù)據包的大小給編碼到數(shù)據包中,數(shù)據包有大有小,如果用一個比較小的數(shù)字的話,就無法發(fā)送大于該數(shù)字的數(shù)據了,如果數(shù)據包比較小,但是編碼用的數(shù)字又比較大的話,就會造成浪費的現(xiàn)象,所以針對不同大小的數(shù)據,需要用不同的方式對長度進行編碼,這就是可變長度的由來。
在mqtt中,數(shù)據包的大小由第2個byte到第5個byte來決定,最小為1個字節(jié),最大為4個字節(jié),加上頭部固定的一個字節(jié),正好是2...5 byte.下面為FixedHeader的結構:
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Byte 1MsgTypeMsgTypeMsgTypeMsgTypeDupQosQosRetainedByte 2Has 3?Byte 3Has 4?Byte 4Has 5?Byte 5
第一個字節(jié)
第一個字節(jié)主要用做消息類型的控制,以及對應消息類型的額外的屬性。按照bit分割,共有8bit,前四個bit用來表示數(shù)據包的類型,是connect還是publish,除了0和15外(用作保留類型),其他的14中均有不同的定義,下方分別給出了14中類型的詳細的解釋。詳細解釋
剩下的4bit
- 第一個bit,是Duplicated的意思,用在publish中qos為1/2的情況,用來表明該消息是否為一條重復的消息。
- 第2/3個bit,聲明了qos的級別,可選的有(0b00, 0b01, 0b10),分別代表了(QOS0, QOS1, QOS2),不能有3,如果是3的話,會被認為成一個非法的數(shù)據包。
- 第四個bit,Retained,告知broker是否要將消息持久化,以供后來的訂閱者消費。
剩下的字節(jié)
這個部分用來表示剩下的數(shù)據的長度,前面說了,這個部分長度是可變的,范圍為1-4,那么如果來確定長度是1還是其他的呢,秘密就藏在字節(jié)的最高位(7bit),這部分的所有數(shù)據,最高位bit都表明有沒有后續(xù)的長度,如果這個值為0的話,表明沒有后續(xù)的數(shù)據了,如果是一的話,表明還需要繼續(xù)計算長度,因此能表明的數(shù)字最小為0,最大為128 * 128 * 128 * 128 = 268435456 byte = 256 Mb。
消息類型
連接與認證
Connect(1)
當客戶端建立好與服務器的連接后,客戶端發(fā)送的第一個報文必須是Connect,并且只能發(fā)送一次,服務端在收到第二個Connect的時候,會認為客戶端異常而斷開連接。·
Connack(2)
服務端響應,
心跳與保活
Pingreq(12)
客戶端發(fā)送,無Variable Header與Payload,
Pingresp(13)
服務端響應,無Variable Header與Payload,
訂閱
Subscribe(8)
Suback(9)
取消訂閱
Unsubscribe(10)
Unsuback(11)
發(fā)布消息
Publish(3)
Pubrel(6)
用在QOS2消息的第二階段,
接收消息
Puback(4)
用在QOS1的消息上,當收到QOS1的消息后,馬上回復Puback的消息,同時設置MessageId為Publish消息的MessageId,
Pubrec(5)
用在QOS2消息的第一階段
Pubcomp(7)
用在QOS2消息的第二階段
斷開連接
Disconnect(14)
當客戶端主動斷開連接時,主動發(fā)送Disconnect消息,該消息無Varibale Header與Payload。
服務質量保證
MQTT發(fā)布消息QoS保證不是端到端的,是客戶端與服務器之間的。訂閱者收到MQTT消息的QoS級別,最終取決于發(fā)布消息的QoS和主題訂閱的QoS。
發(fā)布者發(fā)布的Qos訂閱者訂閱的Qos最終的QOS000010020100111121200211222
總而言之,言而總之,最終的QOS級別為兩者中保證較弱的一方的QOS。即 qos = min(qos Publisher, qos Subscriber)Qos 0
Qos 0只會投遞一次,沒有任何到達的保證,數(shù)據從Publisher到Broker,再從Broker到Subscriber均為一次發(fā)送,適合一些不那么重要的數(shù)據。
sequenceDiagramparticipant Publisherparticipant Brokerparticipant SubscriberPublisher->>Broker: PublishPublisher->>Publisher: Delete(Msg)Broker->>Subscriber: PublishBroker->>Broker: Delete(Msg)Qos 1
相對于Qos 0,Qos 1多了一次Ack的機制,publish->ack,發(fā)布完一條消息后,本地并不會馬上刪除,而是存儲到一個inflight隊列中并等待ack的到來,peer收到qos 1的消息后,馬上進行ack操作,同時將消息提供給上游業(yè)務來處理,上游業(yè)務需要自行去重。后續(xù)的處理分為以下幾種情況:
- 及時收到ack,刪除本地inflight隊列中數(shù)據即可。
- 未能收到ack,分為以下幾種情況:
- publish失敗,只需重新發(fā)送即可。
- ack丟失,重新發(fā)送,服務端進行ack,上游業(yè)務去重。
Qos 2
Qos2,恰好一次是最理想的狀態(tài),然后現(xiàn)實中因為各種各樣的問題,是很難100%實現(xiàn)的,因此我們就需要各種協(xié)議來盡可能的保證恰好一次的語義,相對于Qos1,Qos2保證了恰好一次,Qos1只能保證至少一次,消息的去重需要上游業(yè)務處理,Qos2保證丟給上游業(yè)務的消息也是恰好一次的。
在Qos1中,客戶端需要根據不同的情況進行多次重試,Subscriber一旦收到任何消息后就會把消息傳遞給上游,在Qos2中,我們希望Publisher可以知道Subscriber已經收到消息了,但是先不要投遞給上游的業(yè)務(一旦投遞給上游后,但Publisher并不知道Subscriber已經收到消息了,可能會造成多次的投遞),因此當Subscriber收到消息后,回復一次我已經收到了(Pubrec),Publisher收到回復后,知道Subscriber已經收到消息,接下來告知Subscriber可以把消息提交給上游了(Pubrel),Subscriber收到Pubrel后,將消息提交到上游,并且告知Publisher完成投遞(Pubcomp),Publisher收到消息后,知道投遞完成,刪除本地的消息。
這個過程有沒有感覺和分布式事務中的2PC非常類似,第一階段(Prepare),第二階段(Commit)。
sequenceDiagramparticipant Publisherparticipant Brokerparticipant SubscriberPublisher->>Publisher: Store(Msg)Publisher->>Broker: PublishBroker->>Broker: Store(Msg)Broker->>Publisher: PubrecPublisher->>Broker: PubrelBroker->>Subscriber: PublishBroker->>Publisher: PubcompPublisher->>Publisher: Delete(Msg)Subscriber->>Subscriber: Store(Msg)Subscriber->>Broker: PubrecBroker->>Subscriber: PubrelSubscriber->>Subscriber: Notify(Msg)Subscriber->>Broker: PubcompBroker->>Broker: Delete(Msg)Subscriber->>Subscriber: Delete(Msg)總結
以上是生活随笔為你收集整理的mqtt 获取所有topic_MQTT协议解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机网络中什么叫总衰耗_1、什么是计算
- 下一篇: hpm1216nfh驱动程序_惠普HP