MQTT-SN的一個(gè)重要設(shè)計(jì)原則是盡可能與MQTT相近。因此,所有的協(xié)議語義應(yīng)保持盡可能與MQTT中定義的一致。接下來我們將聚焦于那些新的或偏離MQTT的地方。
6.1 網(wǎng)關(guān)通告與發(fā)現(xiàn)
這是一個(gè)全新的流程,MQTT中沒有此流程。
網(wǎng)關(guān)通過周期性發(fā)送ADVERTISE消息來向當(dāng)前網(wǎng)絡(luò)中所有設(shè)備宣告自身的存在。網(wǎng)關(guān)應(yīng)該只當(dāng)自身連接到服務(wù)端時(shí)(或本身就是服務(wù)端時(shí))才通告自身的存在。
同一網(wǎng)絡(luò)中,同時(shí)可能激活多個(gè)網(wǎng)關(guān)。在這種情況下,它們將會有不同的網(wǎng)關(guān)ID。此時(shí),將由客戶端決定連接到哪個(gè)網(wǎng)關(guān)。但是,在任何時(shí)候,一個(gè)客戶端只能允許連接到一個(gè)網(wǎng)關(guān)。
客戶端應(yīng)將網(wǎng)關(guān)與其網(wǎng)絡(luò)地址維護(hù)在一個(gè)活動網(wǎng)關(guān)列表內(nèi)。通過接收ADVERTISE消息和GWINFO消息來將新活動網(wǎng)關(guān)添加到列表中。
網(wǎng)關(guān)下一次發(fā)送ADVERTISE消息的持續(xù)時(shí)長TADV已在ADVERTISE消息中的Duration字段指定。客戶端可以使用此信息來監(jiān)控網(wǎng)關(guān)是否可用。例如,當(dāng)連續(xù)NADV次未收到網(wǎng)關(guān)發(fā)來的ADVERTISE消息時(shí),可以假定網(wǎng)關(guān)已經(jīng)離線,并將其移出活動網(wǎng)關(guān)列表。同理,處于備用模式的網(wǎng)關(guān)將會激活,當(dāng)它們幾次丟失某一網(wǎng)關(guān)的通告時(shí)。
因?yàn)锳DVERTISE消息將會在整個(gè)無線網(wǎng)絡(luò)中廣播,所以兩次ADVERTISE消息間隔TADV應(yīng)該足夠長(例如大于15分鐘),以避免造成網(wǎng)絡(luò)帶寬擁堵。
大的TADV值會導(dǎo)致新客戶端在查找網(wǎng)關(guān)時(shí)花費(fèi)較長時(shí)間等待網(wǎng)關(guān)廣播??蛻舳丝梢酝ㄟ^廣播SEARCHGW消息來縮短等待時(shí)間。為了防止多個(gè)客戶端同時(shí)查找網(wǎng)關(guān)引起的廣播風(fēng)暴,SEARCHGW消息需要隨機(jī)延遲0到TSEARCHGW發(fā)送。在延遲過程中,如果客戶端接收到其它客戶端發(fā)出的和它相同的SEARCHGW消息時(shí),客戶端應(yīng)該取消自身SEARCHGW消息的發(fā)送,因?yàn)樵揝EARCHGW消息無論誰發(fā)送產(chǎn)生的效果都是相同的。
SEARCHGW消息的廣播半徑Rb是受限的,如假設(shè)在MQTT-SN客戶端密集部署情況下,只會有一跳。
根據(jù)收到的SEARCHGW消息,網(wǎng)關(guān)回復(fù)一包含自身網(wǎng)關(guān)ID信息的GWINFO消息。類似的,客戶端在其活動網(wǎng)關(guān)列表中至少有一個(gè)活動網(wǎng)關(guān)時(shí),回復(fù)一GWINFO消息??蛻舳说牧斜碇腥绻卸鄠€(gè)活動網(wǎng)關(guān),則選擇其中一個(gè)的信息放到GWINFO消息中。
和SEARCHGW消息一樣,GWINFO消息以SEARCHGW消息中的廣播半徑Rb廣播。當(dāng)這兩種消息傳輸時(shí),廣播半徑Rb同時(shí)也傳給底層網(wǎng)絡(luò)。
為了使網(wǎng)關(guān)優(yōu)先,客戶端將會隨機(jī)延遲TGWINFO再發(fā)送GWINFO消息。如果在延遲過程中,客戶端收到了GWINFO消息,則取消自身GWINFO消息的發(fā)送。
假如沒有回應(yīng),則SEARCHGW消息將會重發(fā)。連續(xù)重發(fā)間隔以指數(shù)形式增長。
6.2 客戶端連接的建立
和MQTT一樣,在MQTT-SN客戶端可以同網(wǎng)關(guān)交換信息前,客戶端必須與網(wǎng)關(guān)建立連接。同網(wǎng)關(guān)建立連接的流程如圖3所示。圖3流程假定客戶端要求網(wǎng)關(guān)發(fā)起遺囑功能流程。通過置位CONNECT消息中的標(biāo)志位的遺囑功能指明??蛻舳烁鶕?jù)接收到的相應(yīng)WILLTOPICREQ、WILLMSGREQ消息發(fā)送這兩段信息給網(wǎng)關(guān)。建立連接流程止于收到網(wǎng)關(guān)發(fā)送的CONNACK消息。
如果遺囑功能標(biāo)志未置位,網(wǎng)關(guān)將直接回復(fù)CONNACK消息。

萬一網(wǎng)關(guān)無法接受連接請求(比如擁塞或不支持CONNECT消息中指定的特性),網(wǎng)關(guān)將會返回包含拒絕原因在內(nèi)的CONNACK消息。
6.3 清理會話
在MQTT中,當(dāng)客戶端斷開連接時(shí),其在服務(wù)端的訂閱信息不會被刪除。它們會被持久化并在重連時(shí)可用,除非客戶端顯式退訂或客戶端以“clean session”標(biāo)志符置位方式建立連接。
在MQTT-SN中,“clean session”的范圍被擴(kuò)展到遺囑功能中,如,不僅訂閱信息被保存,遺囑主題及遺囑內(nèi)容也被保存。CONNECT消息中的“CleanSession”“Will”標(biāo)志符意義如下:
- CleanSession=true, Will=true:網(wǎng)關(guān)將會刪除客戶端關(guān)聯(lián)的訂閱信息和遺囑信息,然后發(fā)起遺囑功能流程;
- CleanSession=true, Will=false:網(wǎng)關(guān)將會刪除客戶端關(guān)聯(lián)的訂閱信息和遺囑信息,然后回復(fù)CONNACK消息(不會發(fā)起遺囑功能流程);
- CleanSession=false, Will=true:網(wǎng)關(guān)將會保存客戶端的所有數(shù)據(jù),然后發(fā)起遺囑功能流程,新的遺囑數(shù)據(jù)將會覆蓋已存儲的數(shù)據(jù);
- CleanSession=false, Will=false:網(wǎng)關(guān)將會保存客戶端的所有數(shù)據(jù),然后回復(fù)CONNACK消息(不會發(fā)起遺囑功能流程)。
注意,當(dāng)客戶端在建立連接時(shí)僅想刪除遺囑數(shù)據(jù),它可以發(fā)送一個(gè)“CleanSession=false, Will=true”的CONNECT消息,然后當(dāng)網(wǎng)關(guān)要求遺囑主題時(shí)發(fā)送空的WILLTOPIC消息給網(wǎng)關(guān)。也可以發(fā)送“CleanSession=false, Will=false”的CONNECT消息,然后使用6.4節(jié)介紹的流程來刪除或修改遺囑數(shù)據(jù)。
6.4 遺囑數(shù)據(jù)更新流程
在連接生命期內(nèi),客戶端隨時(shí)可通過發(fā)送WILLTOPICUPD或WILLMSGUPD消息來更新存儲在網(wǎng)關(guān)的遺囑數(shù)據(jù)。這兩種消息內(nèi)的數(shù)據(jù)將會覆蓋網(wǎng)關(guān)中存儲的相應(yīng)數(shù)據(jù)。網(wǎng)關(guān)都會響應(yīng)這兩消息。這兩種消息可以單獨(dú)使用。
注意,空的WILLTOPICUPD消息將會同時(shí)刪除存儲在網(wǎng)關(guān)的遺囑主題和遺囑消息。
6.5 主題名注冊流程
由于無線傳感網(wǎng)絡(luò)帶寬有限、消息載荷小,數(shù)據(jù)無法像MQTT一樣和主題名一起分發(fā)。注冊流程被引入來在開始使用短主題ID發(fā)送PUBLISH消息前,允許客戶端和網(wǎng)關(guān)互相告知短主題ID和對應(yīng)的主題名。
客戶端向網(wǎng)關(guān)發(fā)送REGISTER消息來注冊主題名。如果注冊請求能接受,網(wǎng)關(guān)會為收到的主題名生成topicId,并放到REGACK消息內(nèi)返回給客戶端。如果不能處理注冊請求,失敗原因會放入REGACK的ReturnCode字段并返回給客戶端。
當(dāng)收到ReturnCode=“accepted”的REGACK消息后,客戶端應(yīng)該使用消息內(nèi)的topicId來發(fā)布對應(yīng)主題名的數(shù)據(jù)。如果REGACK消息包含有拒絕碼,客戶端可以稍候再嘗試注冊。如果返回碼是“rejected: congestion”,客戶端在開始注冊流程前應(yīng)等待TWAIT。
在任何時(shí)候,客戶端只能有一個(gè)處理中的REGISTER消息,例如,在開始注冊另一個(gè)主題名之前,客戶端必須等待本次注冊的REGACK消息。
網(wǎng)關(guān)發(fā)送REGISTER消息來告知客戶端主題名和相應(yīng)的主題ID,網(wǎng)關(guān)接下來將使用該主題ID發(fā)送PUBLISH消息。這會發(fā)生在客戶端以未設(shè)置“CleanSession”標(biāo)志位形式重連或客戶端訂閱的主題名包含通配符(#、+等)的情況下。
6.6 客戶端發(fā)布流程
當(dāng)成功向網(wǎng)關(guān)注冊主題名后,客戶端可以開始通過向網(wǎng)關(guān)發(fā)送PUBLISH消息來發(fā)布該主題相關(guān)的數(shù)據(jù)。PUBLISH消息內(nèi)包含相應(yīng)的主題ID。
MQTT-SN支持MQTT中定義的所有三種質(zhì)量等級及相應(yīng)的消息流程。唯一的不同點(diǎn)是MQTT-SN使用主題ID替代PUBLISH消息中的主題名。
無論何種質(zhì)量等級的PUBLISH消息請求,客戶端都可能收到包含下列值的PUBACK回復(fù)消息:
- ReturnCode=“Rejection: invalid topic Id”:此種情況下,客戶需要再次注冊該主題名;
- ReturnCode=“Rejection: congestion”:此種情況下,客戶需要停止至少TWAIT再向網(wǎng)關(guān)發(fā)送消息。
在任何時(shí)候,客戶端只能有一個(gè)處理中的質(zhì)量等級為1或2的PUBLISH消息,例如,在開始新的質(zhì)量等級為1或2的傳輸前,客戶端必須等待本次PUBLISH消息交換完成。
6.7 預(yù)定義主題ID和短主題名
如6.5節(jié)所述,主題ID為2字節(jié)長,用于替換字符串形式的主題名??蛻舳隧氁褂米粤鞒虂砀嬷W(wǎng)關(guān)它想要使用的主題名,并從網(wǎng)關(guān)得到相應(yīng)的主題ID。然后,客戶端將會使用該主題ID來向網(wǎng)關(guān)發(fā)送PUBLISH消息。反過來,網(wǎng)關(guān)發(fā)送的PUBLISH消息同樣也包含一個(gè)2字節(jié)的主題ID(替代字符串形式的主題名)。訂閱流程和網(wǎng)關(guān)發(fā)起的注冊流程會告知客戶端主題ID和主題名間的關(guān)系。
“預(yù)定義”主題ID是一種客戶端應(yīng)用和網(wǎng)關(guān)都知道對應(yīng)主題名的主題ID。使用PUBLISH消息的Flags字段來標(biāo)明它。當(dāng)使用預(yù)定義主題ID時(shí),雙方可以立即開始發(fā)送PUBLISH消息,而無須像“普通”主題ID一樣需要執(zhí)行注冊流程。當(dāng)接收到PUBLISH消息包含的預(yù)定義主題ID對應(yīng)的主題名未知時(shí),接收方應(yīng)該返回ReturnCode=“Rejection: invalid topic Id”的PUBACK消息。注意,此錯(cuò)誤無法像普通主題ID一樣通過重新注冊來修復(fù)。
客戶端如果想接收預(yù)定義主題ID相關(guān)的PUBLISH消息,仍需訂閱該主題ID。為了避免混淆預(yù)定義主題ID和2字節(jié)長的短主題名,SUBSCRIBE消息包含一個(gè)標(biāo)志符來表明是訂閱短主題名還是預(yù)定義主題ID。
短主題名是一種固定2字節(jié)長度的主題名。它可以和數(shù)據(jù)一起放到PUBLISH消息中,因此,短主題名無須注冊流程。另外,普通主題名的所有規(guī)則同樣適用短主題名。注意,以通配方式訂閱短主題名是無意義的,因?yàn)閮H使用兩個(gè)字符來分層定義一個(gè)有意義的名稱是不太可能的。
6.8 發(fā)布質(zhì)量等級為-1的消息
這個(gè)特性定義給非常簡單的客戶端實(shí)現(xiàn),它們除了此特性,不再支持其它特性。它們不用建立連接,也不用關(guān)閉連接,不用注冊流程,也不用訂閱流程??蛻舳司椭皇窍蚓W(wǎng)關(guān)(客戶端預(yù)先知道網(wǎng)關(guān)地址)發(fā)送PUBLISH消息,然后丟棄它們。它并不關(guān)心網(wǎng)關(guān)地址是否正確、網(wǎng)關(guān)是否在線或者網(wǎng)關(guān)是否接收到那些消息。
只有底下的值被允許用于質(zhì)量等級為-1的PUBLISH消息:
- QoS標(biāo)志:置為“0b11”;
- TopicIdType標(biāo)志:預(yù)定義主題ID置“0b01”,短主題名置“0b10”;
- TopicId字段:預(yù)定義主題ID或短主題名;
- Date字段:要發(fā)布的數(shù)據(jù)。
6.9 客戶端主題訂閱/退訂流程
為訂閱某主題名,客戶向網(wǎng)關(guān)發(fā)送SUBSCRIBE消息,同時(shí)將主題名包含在消息中。如果網(wǎng)關(guān)接受訂閱請求,則為收到的主題名生成主題ID并放入SUBACK消息返回給客戶端。如果訂閱有誤,則將拒絕原因?qū)懭隨UBACK消息的ReturnCode字段,并返回給客戶端。如果拒絕原因是“rejected: congestion”,則客戶端應(yīng)等待TWAIT后,再發(fā)送SUBSCRIBE消息。
如果客戶端訂閱的主題名包含通配符,返回的SUBACK消息的主題ID值將為0x0000。當(dāng)網(wǎng)關(guān)第一次向客戶端匹配的主題名發(fā)送PUBLISH消息時(shí),會使用注冊流程來告知客戶端即將使用的主題ID,參見6.10節(jié)。
類似客戶端的發(fā)布流程,主題ID同樣可以為某一主題名的預(yù)定義ID。短主題同樣也可以用。這兩種情況下,客戶端同樣需要訂閱預(yù)定義主題ID或短主題名。
客戶端發(fā)送UNSUBRSCRIBE消息向網(wǎng)關(guān)退訂主題,將會收到UNSUBACK消息回復(fù)。
同樣的,客戶端同時(shí)只能有一個(gè)SUBSCRIBE或UNSUBCRIBE事務(wù)。
6.10 網(wǎng)關(guān)發(fā)布流程
類似6.6節(jié)所述客戶端發(fā)布流程,網(wǎng)關(guān)發(fā)送包含主題ID的PUBLISH消息,然后接收客戶端返回的SUBACK消息。
在發(fā)送PUBLISH消息前,網(wǎng)關(guān)可能發(fā)送REGISTER消息向客戶端通告主題名和相應(yīng)的主題ID。這會發(fā)生在客戶端以未設(shè)置“CleanSession”標(biāo)志位形式重連或客戶端訂閱的主題名包含通配符的情況下??蛻舳藢⒏鶕?jù)接收到的REGISTER消息來回復(fù)REGACK消息。在向客戶端發(fā)送PUBLISH消息前,網(wǎng)關(guān)會一直等待REGACK消息。
客戶端可以使用REGACK消息來拒絕REGISTER消息,并在消息中指明拒絕原因,此方式相當(dāng)于在網(wǎng)關(guān)退訂該主題。注意,通配主題名的退訂只能在6.9節(jié)描述的退訂流程執(zhí)行,不能通過拒絕REGISTER消息實(shí)現(xiàn),因?yàn)镽EGISTER消息從不包含通配主題名。
如果客戶端收到未知主題ID的PUBLISH消息,它應(yīng)該回復(fù)ReturnCode=“Rejected: invalid Topic ID”的PUBACK消息。這會觸使網(wǎng)關(guān)刪除或糾正錯(cuò)誤的主題ID分配值。
注意,當(dāng)主題名或數(shù)據(jù)太長,以至于無法裝入REGISTER或PUBLISH消息時(shí),網(wǎng)關(guān)會靜默中止發(fā)布流程,例如,不會向受到影響的訂閱者發(fā)送警告。
6.11 心跳?;盍鞒?/h2>
和MQTT一樣,心跳值在CONNECT消息中指定??蛻舳藨?yīng)在每一個(gè)心跳周期發(fā)送PINGREQ消息,網(wǎng)關(guān)發(fā)送PINGRESP消息來回應(yīng)。
同理,當(dāng)客戶端接收到當(dāng)前連接的網(wǎng)關(guān)發(fā)來的PINGREQ消息時(shí),應(yīng)回復(fù)PINGRESP消息給網(wǎng)關(guān)。否則忽略接收到的PINGREQ消息。
客戶端應(yīng)用使用此流程來監(jiān)督它們在網(wǎng)關(guān)上的活力。如果客戶端多次重發(fā)PINGREQ消息后,仍無法接收到網(wǎng)關(guān)發(fā)回的PINGRESP消息,則在嘗試重連此網(wǎng)關(guān)之前,應(yīng)首先嘗試連接到其他網(wǎng)關(guān)(參見6.13節(jié))。注意,因?yàn)榭蛻舳说男奶?jì)時(shí)不是同步的,因此假如某一網(wǎng)關(guān)壞了,實(shí)際上不會有受影響的客戶端幾乎同時(shí)轉(zhuǎn)向新網(wǎng)關(guān)而產(chǎn)生CONNECT消息風(fēng)暴的危險(xiǎn)。
6.12 客戶端斷開流程
客戶端向網(wǎng)關(guān)發(fā)送DISCONNECT消息來聲明意圖關(guān)閉連接。在此之后,客戶端要再次同網(wǎng)關(guān)交換信息,必須先同網(wǎng)關(guān)建立一個(gè)新的連接。類似MQTT,即便CleanSession標(biāo)志符有置位,發(fā)送DISCONNECT消息也不會影響已經(jīng)存在的訂閱信息和遺囑數(shù)據(jù)。它們會一直存在,直到客戶端顯式退訂、刪除、更新,或者客戶端以CleanSession標(biāo)志符置位方式建立新的連接。網(wǎng)關(guān)對收到的DISCONNECT消息回復(fù)一DISCONNECT消息給客戶端。
客戶端也可能收到網(wǎng)關(guān)主動發(fā)來的DISCONNECT消息。這有可能發(fā)生在網(wǎng)關(guān)因?yàn)槟承╁e(cuò)誤無法確定接收到的消息所屬的客戶端時(shí)??蛻舳私邮盏竭@樣的DISCONNECT消息時(shí),應(yīng)該再次發(fā)送CONNECT消息來和網(wǎng)關(guān)重建連接。
6.13 客戶端重發(fā)流程
向網(wǎng)關(guān)發(fā)送的所有消息都采用“單播”方式(例如使用網(wǎng)關(guān)的單播地址發(fā)送而不是廣播),使用重試間隔Tretry和重試次數(shù)Nretry來監(jiān)控網(wǎng)關(guān)的預(yù)期回復(fù)。客戶端發(fā)送消息后啟動重試計(jì)時(shí)Tretry,當(dāng)收到網(wǎng)關(guān)的回復(fù)后停止計(jì)時(shí)。如果計(jì)時(shí)時(shí)間到了,但還未收到網(wǎng)關(guān)的回復(fù),客戶端重發(fā)此消息。在Nretry次重發(fā)后,客戶端中止此流程,并可以認(rèn)為到網(wǎng)關(guān)的MQTT-SN連接已經(jīng)斷開了。此時(shí)客戶端應(yīng)該嘗試連接到其他網(wǎng)關(guān),只有在其他網(wǎng)關(guān)都連接失敗時(shí)才再次重連此網(wǎng)關(guān)。
6.14 休眠客戶端支持
休眠客戶端指那些駐留在想盡可能節(jié)約能源的設(shè)備(電池驅(qū)動)上的客戶端。這些設(shè)備每當(dāng)未激活時(shí)就會進(jìn)入休眠模式,每當(dāng)需要發(fā)送數(shù)據(jù)或接收到數(shù)據(jù)時(shí)又會被喚醒。服務(wù)端/網(wǎng)關(guān)需要知道客戶端的休眠狀態(tài),然后為它們緩存消息,并在喚醒時(shí)發(fā)送給它們。

如圖4所示,在服務(wù)端/網(wǎng)關(guān)看來,客戶端可能處于以下的幾種狀態(tài):激活(active)、休眠(asleep)、喚醒(awake)、斷開(disconnected)、丟失(lost)。當(dāng)服務(wù)端/網(wǎng)關(guān)收到客戶端發(fā)來的CONNECT消息時(shí),此時(shí)客戶端處于active狀態(tài),如6.2節(jié)所述。服務(wù)端/網(wǎng)關(guān)通過6.11節(jié)所述的心跳計(jì)時(shí)來監(jiān)控此狀態(tài)。如果超過心跳時(shí)長(在CONNECT消息中指定)服務(wù)端/網(wǎng)關(guān)未收到客戶端發(fā)來的任何消息,網(wǎng)關(guān)將認(rèn)為客戶端已經(jīng)lost,然后為該客戶端啟動遺囑等功能。
當(dāng)服務(wù)端/網(wǎng)關(guān)收到無duration字段的DISCONNECT消息時(shí),客戶端轉(zhuǎn)入disconnected狀態(tài)。此狀態(tài)不受服務(wù)端/網(wǎng)關(guān)的計(jì)時(shí)監(jiān)管。
如果客戶端想要休眠,可以發(fā)送包含休眠時(shí)長的DISCONNECT消息。服務(wù)端/網(wǎng)關(guān)回復(fù)一個(gè)DISCONNECT消息,然后認(rèn)為客戶端已經(jīng)轉(zhuǎn)入asleep狀態(tài),參見圖5。服務(wù)端/網(wǎng)關(guān)使用休眠時(shí)長來監(jiān)控客戶的asleep狀態(tài)。如果超過休眠時(shí)長服務(wù)端/網(wǎng)關(guān)未收到客戶端發(fā)來的任何消息,服務(wù)端/網(wǎng)關(guān)將認(rèn)為客戶端已經(jīng)lost,然后和心跳流程一樣為該客戶端啟動遺囑等功能。客戶端處于asleep狀態(tài)時(shí),服務(wù)端/網(wǎng)關(guān)需要緩存發(fā)給該客戶端的所有消息。

當(dāng)服務(wù)端/網(wǎng)關(guān)收到客戶端發(fā)來的PINGREQ消息時(shí),停止休眠計(jì)時(shí)。如同CONNECT消息,PINGREQ消息也包含Client Id。相應(yīng)的客戶端將變成awake狀態(tài)。如果服務(wù)端/網(wǎng)關(guān)有該客戶端的緩存消息,此時(shí)將會發(fā)送給客戶端。和客戶端的消息傳輸將在服務(wù)端/網(wǎng)關(guān)發(fā)送PINGRESP消息時(shí)關(guān)閉,發(fā)送PINGRESP消息后,服務(wù)端/網(wǎng)關(guān)將認(rèn)為客戶端進(jìn)入asleep狀態(tài),重啟休眠計(jì)時(shí)等。
如果服務(wù)端/網(wǎng)關(guān)沒有客戶端的緩存消息,則立即回復(fù)PINGRESP消息,使客戶端回到asleep狀態(tài),重啟該客戶端的休眠計(jì)時(shí)。
當(dāng)向服務(wù)端/網(wǎng)關(guān)發(fā)送PINGREQ消息后,客戶端使用6.13節(jié)所述的“重發(fā)流程”來監(jiān)督服務(wù)端/網(wǎng)關(guān)發(fā)回消息,例如,當(dāng)它接收到PINGRESP以外的消息時(shí)重啟Tretry計(jì)時(shí),當(dāng)接收到PINGRESP時(shí)停止計(jì)時(shí)。當(dāng)Tretry超時(shí),重發(fā)PINGREQ消息,并重啟Tretry計(jì)時(shí)。為了避免過多重發(fā)PINGREQ消息(例如網(wǎng)關(guān)丟失時(shí))而耗盡電池,客戶端應(yīng)該限制PINGREQ消息的重發(fā)(例如使用重試計(jì)數(shù)),當(dāng)達(dá)到限制條件時(shí)轉(zhuǎn)回休眠,此時(shí)將不會收到PINGRESP消息。
客戶端處于asleep或awake狀態(tài)時(shí),可以通過發(fā)送CONNECT消息進(jìn)入active狀態(tài),也可以通過發(fā)送普通DISCONNECT消息(無duration字段等)進(jìn)入disconnected狀態(tài)??蛻舳丝梢酝ㄟ^發(fā)送包含新的休眠時(shí)長值的DISONNECT消息來修改休眠時(shí)長。
注意,休眠客戶端應(yīng)該只在僅想確認(rèn)服務(wù)端/網(wǎng)關(guān)是否有緩存消息時(shí)才進(jìn)入awake狀態(tài),而后盡快切回asleep狀態(tài),此外,不向服務(wù)端/網(wǎng)關(guān)發(fā)送任何消息。否則,客戶端應(yīng)向服務(wù)端/網(wǎng)關(guān)發(fā)送CONNECT消息回到active狀態(tài)。