<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    聶永的博客

    記錄工作/學(xué)習的點點滴滴。

    MQTT-SN協(xié)議亂翻之功能描述

    前言

    緊接上文,這是第三篇,主要是對MQTT-SN 1.2協(xié)議進行總體性功能描述。

    嗯,這一部分可以結(jié)合著MQTT協(xié)議對比著來看。

    網(wǎng)關(guān)的廣播和發(fā)現(xiàn)

    網(wǎng)關(guān)只能在成功連接到MQTT Server之后,才能夠周期性的在無線個人區(qū)域網(wǎng)WPNs內(nèi)對所有客戶端廣播ADVERTISE消息,便于客戶端被動知道網(wǎng)關(guān)的存在。

    在同一網(wǎng)絡(luò)下,多個擁有不同Id的網(wǎng)關(guān)可有同時運行中,但會由客戶端根據(jù)信號強弱決定連接具體網(wǎng)關(guān),無論何時只能連接一個網(wǎng)關(guān)。

    客戶端可維護一份可用網(wǎng)關(guān)列表(包含網(wǎng)關(guān)地址),在接收到包含有新的網(wǎng)關(guān)id的ADVERTISE和GWINFO消息后,其列表需要添加新的網(wǎng)關(guān)元素進去。

    ADVERTISE廣播消息包含的下一次廣播間隔時長Duration屬性,單位秒,設(shè)為變量T_ADV,應(yīng)該盡可能大與15分鐘(900秒),頻率降低是為了避免低速個人區(qū)域網(wǎng)絡(luò)的擁塞。

    針對接收ADVERTISE消息頻率,處理能力較強客戶端可以用于監(jiān)督網(wǎng)關(guān)是否可用。eg:客戶端連續(xù)N_ADV次接收不到某個網(wǎng)關(guān)ADVERTISE廣播消息,可認為此網(wǎng)關(guān)經(jīng)死掉不可用并且從已維護的網(wǎng)關(guān)列表中移除。同樣的,作為備用的網(wǎng)關(guān)認為主網(wǎng)關(guān)已掛掉,此時可處于激活狀態(tài),正常發(fā)揮作用。

    網(wǎng)關(guān)發(fā)送廣播消息ADVERTISE的時間間隔很長,這對導(dǎo)致新加入的客戶端不利,但客戶端可以直接發(fā)送SEARCHGW廣播消息進行查詢網(wǎng)關(guān)。大量的新入設(shè)備會造成廣播風暴造成網(wǎng)絡(luò)擁擠,每一個新加入的客戶端在發(fā)送SEARCHGW廣播消息之前都需要獲取一個隨機的延遲發(fā)送值(0-Tsearchgw),在延遲等待發(fā)送期間若接收到其它客戶端發(fā)送的SEARCHGW廣播消息,會取消掉自己的SEARCHGW廣播消息發(fā)送,等待網(wǎng)關(guān)GWINFO消息通知。

    SEARCHGW消息屬性radius廣播半徑,記為變量Rb,1跳(1 hop)在一般密集部署下的MQTT-SN客戶端基本可用。

    網(wǎng)關(guān)接收到SEARCHGW會即刻回復(fù)包含自身id的GWINFO消息。客戶端收到SEARCHGW后,若有需要延遲發(fā)送的SEARCHGW會取消掉,若自身維護一份多個可用網(wǎng)關(guān)列表,在等待T_GWINFO時間內(nèi)沒有收到GWINFO消息,會從列表中取出一條網(wǎng)關(guān)信息組裝成GWINFO消息并廣播出去。這就要求客戶端已運行多時,并且維護多個可用網(wǎng)關(guān)列表。

    GWINFO和SEARCHGW所包含半徑radius屬性值一致,這就要求底層網(wǎng)絡(luò)在傳輸時進行決定是否需要傳輸?shù)狡渌愋途W(wǎng)絡(luò)中。

    若沒有接收到響應(yīng),SEARCHGW消息可能被重新傳輸。兩個連續(xù)的SEARCHGW消息重傳間隔應(yīng)該呈指數(shù)形式增加,避免太密集傳輸。

    客戶端的連接建立

    無論是基于哪一種傳輸協(xié)議,TCP or UDP,客戶端都需要建立連接,并且保持心跳,邏輯上和服務(wù)器端保持一條不斷線的雙向通道。下面一張圖,演示了客戶端建立連接的過程,并且設(shè)定客戶端在CONNECT消息中標志位字段中遺囑WILL屬性為true,然后就有了遺囑主題/消息的請求過程。

    很多情況下,連接CONNECT是不需要遺囑支持的,網(wǎng)關(guān)會直接返回CONNACK消息,但網(wǎng)關(guān)會因為擁塞或不支持一些CONNET特性,CONNACK所包含返回代碼字段ReturnCode中包含拒絕代碼,要求客戶端檢查是否連接成功,區(qū)別對待。比如:

     CONNACK消息返回狀態(tài)碼為0x01(Rejected: congestion,因擁塞被拒絕),客戶端需要在T_WAIT時間間隔后進行重試。
    

    回話清理

    已經(jīng)連接的客戶端斷線后,若之前在CONNECT中沒有設(shè)置過會話清理(Clean Session)標識,那么之前的訂閱等信息在網(wǎng)關(guān)處將會持久存在。相比MQTT,MQTT-SN中的“Clean Session”標識被擴展到遺囑特性中。在CONNECT消息中,CleanSession和Will組合將會產(chǎn)生以下效果:

    • CleanSession=true, Will=true: 網(wǎng)關(guān)將會刪除之前對應(yīng)的所有訂閱和遺囑,新的遺囑主題/消息稍后即將重新處理
    • CleanSession=true, Will=false: 網(wǎng)關(guān)將會刪除之前對應(yīng)的所有訂閱和遺囑,返回CONNACK消息
    • CleanSession=false, Will=true: 網(wǎng)關(guān)將繼續(xù)持有之前對應(yīng)的所有訂閱,新的遺囑主題/消息稍后即將重新處理
    • CleanSession=false, Will=false: 網(wǎng)關(guān)將會繼續(xù)持有之前對應(yīng)的所有訂閱和遺囑等數(shù)據(jù),并返回CONNACK消息

    更新遺囑流程

    • CONNEECTION中標志位Will中設(shè)置是否需要更新遺囑主題/消息
    • 空WILLTOPIC(兩個字節(jié))消息將會促使網(wǎng)關(guān)刪除對應(yīng)遺囑數(shù)據(jù)
    • WILLTOPICUPD/WILLMSGUPD可以更新/修改遺囑主題、遺囑消息
    • 空白WILLTOPICUPD(兩個字節(jié))消息意味著請求網(wǎng)清空對應(yīng)已有的遺囑數(shù)據(jù)

    主題注冊流程

    受限于無線傳感器網(wǎng)絡(luò)的有限帶寬和微小消息負載,PUBLISH消息中不能夠包含完整的主題名稱topic name。這就需要客戶端和網(wǎng)關(guān)之間通過注冊流程,獲取主題名稱對應(yīng)的(16位的自然數(shù))topic id,然后塞入PUBLISH消息的topicId屬性中。

    客戶端發(fā)送REGISTER消息,網(wǎng)關(guān)返回REGACK消息,其所包含的ReturenCode屬性決定注冊成功與否:

    • ReturnCode = “accepted”,topicId可以很愉快的使用在稍后的PUBLISH消息中
    • ReturnCode = “rejected: congestion”,客戶端需要稍等一段時間(T_WAIT表示,大于5分鐘)再次重新注冊
    • ReturnCode = “rejected: invalid topic ID/not supported”,客戶端需要稍作調(diào)整,再次重新注冊

    任意時間,只能執(zhí)行一個REGISTER消息,有沒有完成注冊流程,需要等待。

    網(wǎng)關(guān)->客戶端方向,網(wǎng)關(guān)發(fā)送REGISTER消息給通知客戶端指定topicId對應(yīng)某個主題,以便后面發(fā)送PUBLISH消息使用。若客戶端在訂閱SUBSCRIBE消息時使用了通配符(#/+),那么與之相匹配的topic name也將被一一通知到。因此不建議使用通配符,較為低效。

    客戶端發(fā)布流程

    客戶端一旦獲取到topic name對應(yīng)topic id,就可以直接發(fā)送PUBLISH消息了。這和MQTT協(xié)議相比,PUBLISH消息中Topic Name被替換成Topic Id,除此之外,還要注意ReturnCode:

    • ReturnCode = “rejected: congestion”,客戶端需要稍等一段時間(>5分鐘)后再次重試
    • ReturnCode = “rejected: invalid topic ID”,客戶端需要重新注冊topic name獲取topic id,然后再次重新發(fā)布

    QoS 1和 QoS 2在任一時間,都必須等待已有PUBLISH消息完成,才能進行下面的PUBLISH消息發(fā)布流程。

    預(yù)定義topic id和兩個字符的topic name

    預(yù)定義的topic id已提前指派好對應(yīng)的topic name,需要客戶端和網(wǎng)關(guān)在代碼層級支持,省略了中間注冊流程,在連接建立之后可以馬上進行PUBLISH消息,但這需要在PUBLISH標志Flags字段中設(shè)置TopicIdType值為0b01(0b10表示兩個字節(jié)長度的短topic name)。雖然可以快速發(fā)送PUBLISH消息,但客戶端想訂閱預(yù)定義的topic id,接收對應(yīng)的PUBLISH消息,一樣需要發(fā)送SUBSCRIBLE消息請求進行訂閱。若亂指定預(yù)定義topic id,會收到ReturnCode=“Rejection: invalid topic Id”的異常。

    預(yù)定義的短topic name只有兩個字符長度的字符串(也是兩個字節(jié)),topic id為兩個字節(jié)表示的一個自然數(shù)(0-65535),兩者使用場景一致,都需要在標志位Flags設(shè)置TopicIdType具體值,0b01表示預(yù)定義topic id,0b10表示兩個字節(jié)長度的短topic name,需要分清。

    PUBLISH對應(yīng)QoS -1值

    這對僅僅支持PUBLISH QoS -1的非常簡單的客戶端實現(xiàn)而言,除此之外不支持任何特性。它不關(guān)心連接是否建立,也沒有注冊、訂閱這一說,按照已經(jīng)固化到代碼中的網(wǎng)關(guān)地址直接發(fā)送PUBLISH消息,不關(guān)心網(wǎng)關(guān)地址是否正確、網(wǎng)關(guān)是否存活、消息是否發(fā)送成功。

    下面的PUBLISH屬性值依賴于QoS -1的情況:

    • QoS標志,被置為0b11
    • TopicIdType標志,可能是(預(yù)定義topic id)0b01也可能是(短topic name)0b10
    • TopicId字段,預(yù)定義topic id或短topic name
    • Data字段,需要發(fā)送的數(shù)據(jù),沒啥變化

    客戶端的訂閱和退訂

    客戶端對某個主題感興趣,可以發(fā)起SUBSCRIBLE流程,攜帶上感興趣的主題名(topic id),服務(wù)器一般會返回包含有指定主題Id(topic id)的SUBACK消息。訂閱失敗,可以從PUBACK的ReturnCode中獲知:

    • ReturnCode = “rejected: congestion”,客戶端需要稍等一段時間T_WAIT(>5分鐘)后再次重試

    有一種情況是SUBSCRIBLE訂閱主題包含通配符,網(wǎng)關(guān)的處理就很簡單,在SUBACK中返回的topic id為0x0000。稍后,網(wǎng)關(guān)向客戶端發(fā)送REGISTER消息走注冊流程,通知通配符匹配到的主題對應(yīng)的topic id值。

    來自客戶端的SUBSCRIBLE消息一樣支持預(yù)定義topic id,以及短topic name,這和PUBLISH消息差不多。

    退訂就很簡單,客戶端發(fā)送UNSUBSCRIBLE消息,網(wǎng)關(guān)返回UNSUBACK消息。

    但同一時刻,客戶端只允許處理訂閱SUBSCRIBLE或取消訂閱UNSUBSCRIBLE按照串行化順序,下一個操作依賴于上一個操作完全成功。

    網(wǎng)關(guān)發(fā)布流程

    服務(wù)器發(fā)布流程和客戶端類似,在發(fā)布之前需要檢測其主題是否已經(jīng)向客戶端提前注冊過,若無需要把主題和指定的topic id放入REGISTER消息中發(fā)送給客戶端進行注冊流程,然后等待客戶端處理結(jié)果REGACK。注冊通過,然后才能正常發(fā)送PUBLISH消息。

    網(wǎng)關(guān)需要確保REGISTER的主題以及PUBLISH消息的內(nèi)容負載都不能太長超過當前網(wǎng)絡(luò)負載上限(比如在ZigBee環(huán)境下不能超過60個字節(jié)),取消注冊/發(fā)布流程就好了。

    網(wǎng)關(guān)發(fā)布PUBLISH消息時,客戶端檢測到未知的topic id,把拒絕理由封裝到PUBACK后,網(wǎng)關(guān)遇到ReturnCode=“Rejected: invalid Topic ID”非法topic id,需要考慮刪除或重新注冊。

    客戶端或許會拒絕其注冊,或許會不允許PUBLISH消息,網(wǎng)關(guān)如上靜默處理就好了,失敗就失敗了,不需要告知別人。

    客戶端發(fā)布流程于此類似,需要在發(fā)布之前進行主題注冊以獲取指定的topic id,提交PUBLISH消息后,同樣需要檢查PUBACK所包含的ReturnCode字段是接受還是拒絕,因網(wǎng)絡(luò)擁塞而產(chǎn)生的拒絕,客戶端需要在T_WAIT時間后再次重試。

    客戶端的發(fā)布必須是串行方式,下一個需要發(fā)送到PUBLISH消息需要等待上一個發(fā)送成功被網(wǎng)關(guān)接受之后才能進行處理。

    心跳保活流程

    一般是客戶端->網(wǎng)關(guān),網(wǎng)關(guān)->客戶端也沒有問題。但要求PINGREQ -> PINGRESP 一定要單個時針循環(huán),PINGREQ發(fā)送者不能也是PINGRESP的發(fā)送者,那樣不但亂了流程,也浪費了網(wǎng)絡(luò)資源。嗯,不允許雙向互發(fā)。

    客戶端可基于心跳機制監(jiān)測已連接網(wǎng)關(guān)健康與否,連續(xù)多次接收不到來自網(wǎng)關(guān)的PINGRESP消息后,客戶端連接下一個可替換的網(wǎng)關(guān)。因為客戶端的連接和心跳和其它客戶端狀態(tài)屬性不同步,但這可能會帶來一個問題,同一時間若有大量的客戶端洪水般同時連接一個網(wǎng)關(guān),網(wǎng)關(guān)可能毫無征兆的會被沖垮掉。這就要求網(wǎng)關(guān)要有批量的連接處理能力,并發(fā)特性增強才行。

    客戶端斷線流程

    客戶端主動發(fā)送DISCONNECT消息告知網(wǎng)關(guān)需要斷線之后,若有交換信息的需要可以重新發(fā)起一個新的會話連接。DISCONNECT消息之后,網(wǎng)關(guān)不會清理掉已有訂閱和遺囑數(shù)據(jù),除非在之前的CONNECT消息中已硬性設(shè)置了CleanSession會話清理標識為true。網(wǎng)關(guān)接收到DISCONNECT消息之后會返回一個DISCONNECT消息作為響應(yīng)。

    有一種情況是客戶端會突然接收到來自網(wǎng)關(guān)的DISCONNECT消息,這也許是網(wǎng)關(guān)自身發(fā)生了異常錯誤,或網(wǎng)關(guān)無法定位客戶端的消息歸屬(客戶端的消息和客戶端無法關(guān)聯(lián)到一起),此時客戶端需要發(fā)送CONNECT消息重建與網(wǎng)關(guān)的會話連接。

    客戶端重傳流程

    客戶端->網(wǎng)關(guān)的消息都是單路傳播的,這依賴于客戶端所持有的已連接網(wǎng)關(guān)的單播地址。

    客戶端發(fā)送一個消息之后,需要啟動一個重試定時器Tretry和一個重試計數(shù)器Nretry用以監(jiān)督網(wǎng)關(guān)消息響應(yīng)。定時器會被客戶端在指定時間內(nèi)接收到來自網(wǎng)關(guān)的消息后取消掉,若沒有準時接收到則會觸發(fā)定時器執(zhí)行消息重發(fā)流程,連續(xù)Nretry次重發(fā)后,客戶端會直接取消掉當前流程,判斷當前網(wǎng)關(guān)已經(jīng)斷線,需要連接到另外一個可用的網(wǎng)關(guān)。假如另外的網(wǎng)關(guān)也是連接失敗,會嘗試重連之前的網(wǎng)關(guān)。

    若在休眠狀態(tài)下,一旦超過重試計數(shù)器值,客戶端直接進入休眠狀態(tài)。

    客戶端休眠支持策略

    這里所說的客戶端指的是依賴電池驅(qū)動的電子設(shè)備,你要明白一個事實,節(jié)省電池資源是多麼的重要,省電就是關(guān)鍵,沒電了就沒得玩了嘛。當不處于激活狀態(tài)時為了省電就得需要進入睡眠/休眠狀態(tài),當有數(shù)據(jù)需要接收或發(fā)送時就可以醒過來。網(wǎng)關(guān)嘛需要追蹤設(shè)備的休眠狀態(tài)并且支持緩存需要發(fā)送給休眠設(shè)備的消息,在設(shè)備喚醒時一一發(fā)送。

    下面是客戶端的狀態(tài)轉(zhuǎn)換圖,很清晰描述了各種狀態(tài)之間的交互:

    客戶端具有五種狀態(tài):激活(active),休眠(asleep),喚醒(awake),斷線(disconnected),丟失(lost),每次只能是其中一種。

    網(wǎng)關(guān)需要監(jiān)督客戶端的狀態(tài),開始于CONNECT消息中存活時長字段(keep alive),在大于存活時長時間內(nèi)網(wǎng)關(guān)接收不到來自客戶端消息,網(wǎng)關(guān)認為客戶端已經(jīng)處于丟失狀態(tài)(lost),會激活對應(yīng)的遺囑特性若存在的話。

    客戶端發(fā)送DISCONNECT消息但沒有duration休眠時長字段,網(wǎng)關(guān)這將處于沒有時間監(jiān)督的斷線狀態(tài)。一旦包含duration休眠時長字段,表示客戶端需要休眠一段時間,網(wǎng)關(guān)這客戶端被轉(zhuǎn)換為休眠狀態(tài),休眠時長為duration所定義在值。超過此休眠時長的一段時間內(nèi),網(wǎng)關(guān)若接收不到客戶端發(fā)送過來的任何消息,那么客戶端會被轉(zhuǎn)化為丟失狀態(tài),若已設(shè)置遺囑特性,此時遺囑特性會生效。客戶端休眠期間需要被發(fā)送的消息都會被網(wǎng)關(guān)緩存。

    睡眠狀態(tài)下流程圖會更形象的說明流程:

    毫無疑問,網(wǎng)關(guān)可使用一個休眠定時器維護客戶端的休眠狀態(tài)等,休眠定時器會被停掉當網(wǎng)關(guān)接收到客戶端發(fā)送過的PINGREQ消息,網(wǎng)關(guān)從PINGREQ消息所包含的Client Id檢索是否存在已緩存的PUBLISH消息,若有會一一按照順序發(fā)送到客戶端。所有對應(yīng)已緩存消息發(fā)送完畢后,會隨之發(fā)送一個PINGRESP消息。若沒有緩存消息,網(wǎng)關(guān)直接返回一個PINGRESP消息。網(wǎng)關(guān)會重新啟動休眠定時器,網(wǎng)關(guān)維護的客戶端狀態(tài)被轉(zhuǎn)換為休眠狀態(tài),客戶端在接收到PINGRESP消息之后,將直接轉(zhuǎn)向休眠狀態(tài),節(jié)省用電。

    客戶端在喚醒狀態(tài)下處理消息,遵守“客戶端重傳流程”行為,一旦達到重試計數(shù)器限制,將進入睡眠狀態(tài)。

    客戶端從休眠狀態(tài)轉(zhuǎn)向喚醒狀態(tài)用于檢查網(wǎng)關(guān)是否為其緩存消息時,需要發(fā)送一個PINGREQ消息到網(wǎng)關(guān);從休眠/喚醒狀態(tài)轉(zhuǎn)換為激活狀態(tài),需要發(fā)送一個CONNECT消息告知網(wǎng)關(guān);轉(zhuǎn)換為斷線狀態(tài)時需要發(fā)送兩個字節(jié)的DISCONNECT(沒有休眠時長字段duration)消息;需要重新定義的休眠時長,發(fā)送一個DISCONNECT消息(包含新的duration時長值)通知網(wǎng)關(guān)即可。

    小結(jié)

    功能性描述介紹完了,基本上MQTT-SN協(xié)議介紹已接近尾聲,最后面的篇章就是短短的實現(xiàn)描述了。

    posted on 2015-01-09 17:32 nieyong 閱讀(6978) 評論(1)  編輯  收藏 所屬分類: MQTT

    評論

    # re: MQTT-SN協(xié)議亂翻之功能描述 2015-03-05 14:49 皮脂分泌和細菌導(dǎo)致青春痘長起

    好文章,要多關(guān)注  回復(fù)  更多評論   

    公告

    所有文章皆為原創(chuàng),若轉(zhuǎn)載請標明出處,謝謝~

    新浪微博,歡迎關(guān)注:

    導(dǎo)航

    <2015年1月>
    28293031123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    統(tǒng)計

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲欧美日韩一区二区三区| 日本成年免费网站| 最近高清中文字幕免费| 搡女人真爽免费视频大全| 亚洲国产成人五月综合网 | 8090在线观看免费观看| 毛片a级毛片免费播放100| 亚洲中文久久精品无码| 亚洲精品免费网站| 亚洲午夜国产精品无卡| 免费在线观看一区| 黄页网站在线观看免费高清| 亚洲人成国产精品无码| 亚洲激情视频图片| 免费在线看黄的网站| 日韩免费在线观看| 亚洲国产亚洲片在线观看播放 | 亚洲s色大片在线观看| 亚洲欧洲国产综合AV无码久久| 91成人免费福利网站在线| 国产高清视频在线免费观看| 精品亚洲成a人片在线观看 | 久久精品亚洲日本波多野结衣| 亚洲精品成人无码中文毛片不卡| 亚洲宅男精品一区在线观看| 无码日韩精品一区二区三区免费 | 男人天堂免费视频| 又黄又爽的视频免费看| 色老板亚洲视频免在线观| 无码国产精品一区二区免费式芒果| 国产国拍亚洲精品福利| 国产精品亚洲精品日韩电影| 女人18毛片免费观看| 国产免费131美女视频| 国产91在线|亚洲| 日韩在线播放全免费| 亚洲av网址在线观看| 在线观看亚洲AV每日更新无码| 99久久免费中文字幕精品| 亚洲人成人77777网站| 久久久久久久久久免免费精品|