publish報(bào)文
publish報(bào)文的發(fā)生方向
發(fā)生的方向是:雙向的术徊,既可以從客戶端發(fā)往服務(wù)器端,又可以從服務(wù)器端發(fā)往客戶端棋凳。
客戶端使用 PUBLISH 報(bào)文發(fā)送應(yīng)用消息給服務(wù)端妥箕, 目的是分發(fā)到其它訂閱匹配的客戶端。
服務(wù)端使用 PUBLISH 報(bào)文發(fā)送應(yīng)用消息給每一個(gè)訂閱匹配的客戶端石景。
publish報(bào)文的結(jié)構(gòu)
固定報(bào)頭:
1劈猿、固定報(bào)頭中的重發(fā)標(biāo)志dup:
如果是第一次發(fā)送此報(bào)文,則置dup=0
如果是重發(fā)報(bào)文潮孽, 則置dup=1
2揪荣、服務(wù)質(zhì)量等級(jí)
Qos=0
Qos=1
Qos=2
3、保留標(biāo)志
保留標(biāo)志的可選值: retain=1 retain=0
可變報(bào)頭:
1往史、主題名 topicName
2仗颈、報(bào)文標(biāo)識(shí)符,只有當(dāng)Qos=1或2時(shí)椎例,pub報(bào)文中才有報(bào)文標(biāo)識(shí)符
有效載荷
由應(yīng)用指定的數(shù)據(jù)
Qos1級(jí)別的publish報(bào)文
服務(wù)質(zhì)量Qos1會(huì)確保消息至少送達(dá)一次挨决。Qos1的publish報(bào)文的可變報(bào)頭中包含一個(gè)報(bào)文標(biāo)識(shí)符,需要pubAck報(bào)文確認(rèn)订歪。
對(duì)于Qos1的分發(fā)協(xié)議脖祈,發(fā)送者:
- 每次發(fā)送新的應(yīng)用消息都分配一個(gè)未使用的報(bào)文標(biāo)識(shí)符
- 發(fā)送的publish報(bào)文必須包含報(bào)文標(biāo)識(shí)符且Qos等于1,dup等于0刷晋。
- 必須將這個(gè)publish報(bào)文看作是未確認(rèn)的盖高,直到從接收者那里收到對(duì)應(yīng)的pubAck報(bào)文
對(duì)于Qos1的分發(fā)協(xié)議的接收者:
響應(yīng)的pubAck報(bào)文必須包含一個(gè)報(bào)文標(biāo)識(shí)符,這個(gè)標(biāo)識(shí)符來自接收到的掏秩,已經(jīng)接收所有權(quán)的
publish報(bào)文發(fā)送pubAck報(bào)文之后或舞,接收者必須將任何包含相同報(bào)文標(biāo)識(shí)符的入站publish報(bào)文當(dāng)作一個(gè)新的
消息,并忽略它的DUP標(biāo)志的值
Qos1的協(xié)議的交互流程圖
下面這張圖是:Qos1的交互流程圖:
Qos1級(jí)別的pub報(bào)文的缺陷
消息重復(fù)的問題
在上圖中蒙幻,我們可以看到映凳,對(duì)于發(fā)送方來說,當(dāng)它發(fā)送一個(gè)pub報(bào)文時(shí)邮破,它會(huì)一直等待著來自對(duì)方(接收方)的消息確認(rèn)報(bào)文pubAck诈豌。只有收到pubAck報(bào)文之后,它才認(rèn)為該pub報(bào)文已經(jīng)發(fā)送成功抒和,否則矫渔,就會(huì)執(zhí)行重試。
即: 再次發(fā)送該pub報(bào)文給客戶端直到收到pubAck確認(rèn)已經(jīng)發(fā)生成功為止摧莽。
但是庙洼,這里有個(gè)問題,那就是: 如果接收方已經(jīng)收到了pub報(bào)文,而且它也把pubAck報(bào)文發(fā)送出去了油够,但是由于網(wǎng)絡(luò)狀況太差或者其他原因蚁袭,導(dǎo)致了這個(gè)pubAck報(bào)文丟失了,發(fā)送方接收不到來自接收方的pubAck確認(rèn)報(bào)文石咬。
于是揩悄,發(fā)送方就會(huì)對(duì)此pub報(bào)文進(jìn)行二次重發(fā),這樣的話鬼悠,接收方就又收到了一條和原來一模一樣的pub報(bào)文删性,實(shí)際上由于接收方之前就已經(jīng)收到并處理過該報(bào)文了,所以這次報(bào)文對(duì)接收方來說焕窝,就是一條重復(fù)報(bào)文蹬挺。
可見,導(dǎo)致重復(fù)消息的原因就是: pubAck報(bào)文在網(wǎng)絡(luò)傳輸中丟失造成的它掂。
Qos2解決Qos1的重復(fù)消息問題
Qos2是最高的服務(wù)質(zhì)量等級(jí)汗侵,消息丟失和重復(fù)都是不可接收的。但是使用這個(gè)服務(wù)質(zhì)量等級(jí)會(huì)有額外的開銷群发。
兩步確認(rèn)過程
Qos2的pub報(bào)文的接收者使用一個(gè)兩步確認(rèn)過程來確認(rèn)收到。
發(fā)送方和接收方的處理
對(duì)于Qos2的發(fā)送方來說:
. 必須要給要發(fā)送的新應(yīng)用消息分配一個(gè)未使用的報(bào)文標(biāo)識(shí)符发乔。
. 發(fā)送的pub報(bào)文必須包含報(bào)文標(biāo)識(shí)符且報(bào)文的Qos等于2熟妓,dup等于0.
. 必須將這個(gè)pub報(bào)文看作是未確認(rèn)的,直到從接收者那收到pubRec報(bào)文栏尚。
. 收到pubRec報(bào)文后必須發(fā)送一個(gè)pubRel報(bào)文起愈,pubRel報(bào)文必須包含與原始的pub報(bào)文相同的報(bào)文標(biāo)識(shí)符
. 必須將這個(gè)pubRel報(bào)文看作是未確認(rèn)的,直到從接收者那收到對(duì)應(yīng)的pubComp報(bào)文
. 一旦發(fā)送了對(duì)應(yīng)的pubRel報(bào)文就不能重發(fā)這個(gè)publish報(bào)文了译仗。
對(duì)于Qos2的接收者來說:
. 響應(yīng)的pubRec報(bào)文必須包含報(bào)文標(biāo)識(shí)符抬虽,這個(gè)標(biāo)識(shí)符來自接收到的、已經(jīng)接收所有權(quán)的publish報(bào)文纵菌。
. 在收到對(duì)應(yīng)的pubRel報(bào)文之前阐污,接收者必須發(fā)送pubRec報(bào)文確認(rèn)任何后續(xù)的具有相同標(biāo)識(shí)符的pub報(bào)文。
. 響應(yīng)的pubRel報(bào)文的pubComp報(bào)文必須包含與pubRel報(bào)文相同的報(bào)文標(biāo)識(shí)符
. 發(fā)送pubComp報(bào)文之后咱圆,接收者必須將包含相同報(bào)文標(biāo)識(shí)符的任何后續(xù)的pub報(bào)文當(dāng)做一個(gè)新的發(fā)布笛辟。
Qos2的交互流程
我們知道,Qos1的消息重復(fù)問題的根源在于:pubAck報(bào)文的丟失導(dǎo)致序苏。
所以手幢,如果我們要解決消息的重復(fù)問題,就必須致力于解決 pubAck報(bào)文的丟失問題忱详,在Qos2中围来,對(duì)應(yīng)的就是pubRec報(bào)文的丟失問題。
即:確保發(fā)送方一定可以收到來自接收方的pubRec報(bào)文。所以這里就引出了:2步確認(rèn)過程监透。
step1: 第一次使用應(yīng)答機(jī)制來對(duì)pub報(bào)文進(jìn)行確認(rèn)桶错,從而確保接收方一定可以接收到pub報(bào)文。
step2: 第二次使用應(yīng)答機(jī)制來對(duì)pubRec報(bào)文進(jìn)行確認(rèn)才漆,從而確保發(fā)送方一定可以接收到pubRec報(bào)文牛曹。
可見:
1、pubRec 是對(duì)pub的保證醇滥,確保pub不會(huì)丟失
2黎比、pubRel 是pubRec的保證,確保pubRec不會(huì)丟失
3鸳玩、pubComp是pubRel的保證阅虫,確保pubRel不會(huì)丟失
如果sender沒有收到pubRec,就要重發(fā)該pub不跟。
如果receiver沒有收到pubRel颓帝,就會(huì)重發(fā)pubRec。
如果sender沒有接收到pubComp窝革,就會(huì)重發(fā)pubRel购城。
對(duì)于接收方來說,收到pubRel報(bào)文之后虐译,它的使命就完成了瘪板。(即: 它不僅收到了pub消息,而且確信自己也已把pubRec報(bào)文送到了發(fā)送方漆诽。)
對(duì)于發(fā)送方來說侮攀,收到了pubRec報(bào)文,就意味著厢拭,pub報(bào)文已經(jīng)被接收方確定接收了兰英。收到了pubComp報(bào)文,就意味著供鸠,pubRel報(bào)文已經(jīng)確定被接收方接收了畦贸。