MQTT協(xié)議
Apollo允許客戶(hù)端通過(guò)開(kāi)放的MQTT協(xié)議連接。該協(xié)議主要是用在資源有限的驅(qū)動(dòng)上,以及網(wǎng)絡(luò)不穩(wěn)定的情況下使用,是一個(gè)訂閱、發(fā)布模型。這種驅(qū)動(dòng)通常不適用類(lèi)似http,stomp這類(lèi)基于文本,或者類(lèi)似openfire,AMQP等傳統(tǒng)二進(jìn)制協(xié)議。MQTT是一個(gè)簡(jiǎn)介的二進(jìn)制協(xié)議,適用這類(lèi)驅(qū)動(dòng)資源受限,而且是不穩(wěn)定的網(wǎng)絡(luò)條件下。
之前的穩(wěn)定發(fā)布版本中,MQTT是作為一個(gè)Apollo的一個(gè)插件提供的。但是現(xiàn)在,這個(gè)插件已經(jīng)變?yōu)殚_(kāi)發(fā)項(xiàng)目的一部分。MQTT在Apollo中已經(jīng)不需要其他配置文件或者是第三方插件支持了。
MQTT是一個(gè)線路層的協(xié)議,任何實(shí)現(xiàn)該協(xié)議的客戶(hù)端都可以連接到Apollo。當(dāng)然也可以整合其他MQTT兼容的消息代理中。
更多有關(guān)MQTT協(xié)議內(nèi)容,參考the MQTT Specification
MQTT協(xié)議配置
為了開(kāi)始使用MQTT協(xié)議,首先使用MQTT3.1協(xié)議的客戶(hù)端,連接到Apollo正在監(jiān)聽(tīng)端口。Apollo會(huì)做協(xié)議檢測(cè),而且自動(dòng)識(shí)別MQTT連接,而且將連接作為MQTT協(xié)議處理。你不必要為MQTT協(xié)議打開(kāi)一個(gè)端口(STomp,Openfire,AMQP等都是自動(dòng)識(shí)別)。如果你一定指定連接的協(xié)議,有下面兩種方式:你可以選擇不用協(xié)議識(shí)別,而是為MQTT指定連接:
<connector id="tcp" bind="tcp://0.0.0.0:61613" protocol="mqtt"/>
或者你可以限制哪種協(xié)議可以被自動(dòng)識(shí)別。通過(guò)下面的<detece>配置方式:
<connector id="tcp" bind="tcp://0.0.0.0:61613">
<detect protocols="mqtt openwire" />
</connector>
<detect> 下protocols 對(duì)應(yīng)的參數(shù)通過(guò)空格來(lái)隔開(kāi)支持的通信協(xié)議。如果只支持一種協(xié)議,就不要空格,默認(rèn)情況下對(duì)任何協(xié)議生效。
如果你想調(diào)整MQTT默認(rèn)設(shè)置,在apollo.xml文件中有一個(gè)<connector> 元素,通過(guò)MQTT參數(shù)配置:
<connector id="tcp" bind="tcp://0.0.0.0:61613">
<mqtt max_message_length="1000" />
</connector>
MQTT元素支持下面幾個(gè)參數(shù):
max_message_length
: The size (in bytes) of the largest message that can be sent to the broker. Defaults to 100MB(broker能接受的最大消息量:默認(rèn)是100M)protocol_filters
: A filter which can filter frames being sent/received to and from a client. It can modify the frame or even drop it.(一個(gè)控制發(fā)送和接收,Client的過(guò)濾器框架??梢孕薷模瑒h除這個(gè)框架)die_delay
: How long after a connection is deemed to be “dead” before the connection actually closes; default: 5000ms(在實(shí)際斷開(kāi)連接之前,會(huì)有默認(rèn)5000ms的時(shí)間被認(rèn)為連接已經(jīng)dead)
mqtt 配置元素也可以用來(lái)控制目的消息頭的解析。下面是支持的參數(shù):
queue_prefix
: a tag used to identify destination types; default: null(用來(lái)確認(rèn)目的地類(lèi)型)path_separator
: used to separate segments in a destination name; default:/(用來(lái)分割目的地名稱(chēng))
any_child_wildcard
: indicate all child-level destinations that match the wildcard; default:+(識(shí)別子目錄)
any_descendant_wildcard
: indicate destinations that match the wildcard recursively; default:#(目標(biāo)地址通配符)
regex_wildcard_start
: pattern used to identify the start of a regex(表示正則表達(dá)開(kāi)始)regex_wildcard_end
: pattern used to identify the end of a regex(表示正則表達(dá)結(jié)束)part_pattern
: allows you to specify a regex that constrains the naming of topics. (你可以指定正則表達(dá)規(guī)則)default:[ a-zA-Z0-9\_\-\%\~\:\(\)]+
Client 可用函數(shù)庫(kù)
Apollo 支持MQTT3.1 協(xié)議,下面是可用的Clients:
- Java : mqtt-client, MeQanTT
- C : libmosquitto
- Erlang : erlmqtt, my-mqtt4erl
- .NET : MQTTDotNet, nMQTT
- Perl : net-mqtt-perl, [anyevent-mqtt-perl]https://github.com/beanz/anyevent-mqtt-perl()
- Python : nyamuk
- Ruby : mqtt-ruby, ruby-em-mqtt
- Javascript : Node.js MQTT Client
- Delphi : TMQTTCLient
- Device specific: Arduino, mbed, Nanode, Netduino
如果要找到新支持的Clients ,可以檢索:the MQTT website for its software
在目錄example 目錄下,你可以找到一些例子,實(shí)現(xiàn)了與broker之間收發(fā)。
connecting
為了確保broker配置文件的安全,所以只允許一個(gè)admin 用戶(hù)連接,默認(rèn)的用戶(hù)名和密碼是:admin ,password.
Mqtt 客戶(hù)端不能specify 虛擬主機(jī)(更多請(qǐng)看:see the section on Virtual Hosts in the user guide),以至于默認(rèn)情況下虛擬主機(jī)已經(jīng)被使用了。通常第一虛擬主機(jī)定義在apollo.xml文件中。
Destination 類(lèi)型
MQTT協(xié)議是訂閱,發(fā)布協(xié)議,是不允許真正的利用隊(duì)列點(diǎn)對(duì)點(diǎn)的消息收發(fā)。因此Apollo僅允許利用主題,還進(jìn)行MQTT消息發(fā)送。訂閱的概念和持久的主題訂閱 和其他協(xié)議提到的有些類(lèi)似,同時(shí)也被MQTT CONNECT 框架的clean session屬性控制。
Clean Sessions
但一個(gè)Client 發(fā)送一個(gè)連接,這個(gè)連接中clean session 被設(shè)置為false,那么之前連接中有相同Client_id 的session 將會(huì)被重復(fù)使用。這就意味著Client斷開(kāi)了,訂閱依然能收到消息。這就等同與同Apollo建立一個(gè)長(zhǎng)訂閱。
如果 clean session 設(shè)置為true ,那么新session就開(kāi)始了,其他的session會(huì)慢慢消失,刪除。這就是Apollo中定義的普通的主題訂閱。
Topic Retained Messages
如果消息被發(fā)布的同時(shí)retain 標(biāo)記被設(shè)置,消息將被主題記住,以至于新的訂閱到達(dá),最近的retain 消息會(huì)被發(fā)送到訂閱者。比如說(shuō):你想發(fā)布一個(gè)參數(shù),而且你想讓最新的這個(gè)參數(shù)發(fā)布到總是可用的訂閱了這個(gè)主題的客戶(hù)端上,你就設(shè)置在PUBLISH 框架上設(shè)置retain 標(biāo)簽。
注意:retained 消息 不會(huì)被設(shè)置成retained 在 QoS設(shè)置為零的broker 重啟過(guò)程中。
Last Will and Testament Message
當(dāng)Client第一次連接的時(shí)候,有一個(gè)will 消息和一個(gè)更QoS相關(guān)的消息會(huì)跟你有關(guān)。will消息是一個(gè)基礎(chǔ)消息,這個(gè)基礎(chǔ)消息只有在連接異?;蛘呤堑艟€的時(shí)候才會(huì)被發(fā)送。一般用在你有一個(gè)設(shè)備,當(dāng)他們掉了的時(shí)候,你需要知道。所以如果一個(gè)醫(yī)療Client從broker掉線,will消息將會(huì)作為一個(gè)鬧鐘主題發(fā)送,而且會(huì)被系統(tǒng)作為高優(yōu)先級(jí)提醒。
Reliable Messaging
MQTT協(xié)議允許Client 發(fā)布消息的時(shí)候指定Qos參數(shù):
- At Most Once (QoS=0)
- At Least Once (QoS=1)
- Exactly Once (QoS=2)
最多一次
這個(gè)設(shè)置時(shí)推送消息給Client,可靠性最低的一種。如果設(shè)置Qos=0,那broker就不會(huì)返回結(jié)果碼,告訴你他收到消息了,也不會(huì)在失敗后嘗試重發(fā)。這有點(diǎn)像不可靠消息,如JMS。
至少一次
該設(shè)置會(huì)確保消息會(huì)被至少一次推送到Client。如果推送設(shè)置為至少推送一次,Apollo會(huì)返回一個(gè)回調(diào)函數(shù),確保代理已經(jīng)收到消息,而且確保會(huì)確保推送該消息。如果Client 將發(fā)布了一個(gè)Qos=1的消息,如果在指定的時(shí)間內(nèi)沒(méi)有收到回復(fù),Client會(huì)希望重新發(fā)布這個(gè)消息。所以可能存在這種情況:代理收到一個(gè)需要推送的消息,然后又收到一個(gè)消息推送到同一個(gè)Client。所以如果傳輸過(guò)程中PUBACK丟失,Client會(huì)重新發(fā)送,而且不會(huì)去檢測(cè)是否是重發(fā),broker就將消息發(fā)送到訂閱主題中。
恰好一次
該設(shè)置是可靠等級(jí)最高的。他會(huì)確保發(fā)布者不僅僅會(huì)推送,而且不會(huì)像Qos=1 那樣,會(huì)被接收兩次。當(dāng)然這個(gè)設(shè)置會(huì)增加網(wǎng)絡(luò)的負(fù)載。當(dāng)一個(gè)消息被發(fā)布出去的時(shí)候,broker會(huì)保存該消息的id,而且會(huì)利用任何長(zhǎng)連接,堅(jiān)持要把該消息推送給目標(biāo)地址。如果Client收到PUBREC 標(biāo)志,那就表明broker已經(jīng)收到消息了。 這個(gè)時(shí)候broker會(huì)期待Client發(fā)送一個(gè)PUBREL 來(lái)清除session 中消息id,broker如果發(fā)送成功就會(huì)發(fā)送一個(gè)PUBCOMP通知Client。
Wildcard Subscriptions
通配用在主題的目標(biāo)地址中。這能實(shí)現(xiàn)一個(gè)主題發(fā)送到多個(gè)用戶(hù),或者多層用戶(hù)中。
/
is used to separate names in a path(分割路徑)+
is used to match any name in a path(通配地址任何字符)#
is used to recursively match path names(遞歸通配)
比如通配可能這樣來(lái)用:
PRICE/#
: Any price for any product on any exchange(任何交易中任何產(chǎn)品的價(jià)格)PRICE/STOCK/#
: Any price for a stock on any exchange(任何交易中的股票價(jià)格)PRICE/STOCK/NASDAQ/+
: Any stock price on NASDAQ(納斯達(dá)克的任何股票價(jià)格)PRICE/STOCK/+/IBM
: Any IBM stock price on any exchange(任何交易中IBM股票價(jià)格)
Keep Alive
Apollo只有在Client指定了CONNECT的KeepAlive 值的時(shí)候,才會(huì)設(shè)置保持連接、心跳檢測(cè)。如果one Client指定了keepalive,apollo 將會(huì)使用1.5*keepalive值。這個(gè)在MQTT中有說(shuō)明。
Destination Name Restrictions
路徑名稱(chēng)限制了使用(a-z, A-Z, 0-9, _, - %, ~, :, ' ', '(', ')' ,. )字符,通配符(*)在復(fù)雜的分隔符中。而且確保使用utf-8來(lái)編譯你的URL。
聯(lián)系客服