androidmqtt
Ⅰ 如何採用mqtt協議實現android消息推送
使用一個代理伺服器message broker,客戶端client連接上這個伺服器,然後告訴伺服器,可以接收哪些類型的消息,同時client也可以發布自己的消息,這些消息根據協議的內容,可以別的client獲取。這樣就實現了消息推送。消息推送是通過一定的技術標准或協議,在互聯網上通過定期傳送用戶需要的信息來減少信息過載的一項新技術。
如果想要使用消息推送,推薦使用深圳極光的消息推送系統。深圳極光是國內首個為移動應用開發者提供專業、高效的消息推送服務的產品。品牌成長的過程,就是與客戶肩並肩邁向成功的過程。極光將以市場為導向,以創新為動力,以技術為支持,不斷用心努力,為每一位尊貴的客戶提供極致的服務。
Ⅱ Android MQTT 通信
MQTT 協議 是基於發布/訂閱模式的物聯網通信協議,憑借簡單易實現、支持 QoS、報文小等特點,占據了物聯網協議的半壁江山。
常用於 IOT 物聯網和一些需要服務端主動通知客戶端的場景。
1. 導入依賴
2. 創建 MqttHelper 輔助類,設置回調監聽
3. 連接 MQTT
連接成功或失敗,以及中途的連接掉線,會觸發 OnMqttStatusChangeListener 回調
4. MQTT 連接狀態監聽
5. MQTT 收發消息監聽
onSubMessage 訂閱的消息回調,因為存在訂閱多個 topic 的情況,所以回調能知道是來自哪個 Topic 的消息;
onPubMessage 發布的消息回調,用於確認發布的消息是否發送成功。
6. MQTT 訂閱 Topic
需要在 MQTT 連接成功後才能訂閱 topic,否則訂閱 Topic 不成功,收不到對應消息
7. MQTT 取消訂閱 Topic
8. MQTT 發布消息
9. MQTT 斷開連接
10. 通知設置
由於 MQTT 啟動了一個 Service,而 Android 8.0 以上對於後台 Service 限制時長 5 秒;所以將 MqttService 綁定到 Notification 上成為了一個前台通知;通知的標題和內容顯示可以在 strings.xml 中設置,對應屬性如下:
Android 8.0 及以上開啟前台服務綁定到通知,8.0 以下默認不啟用,可將 mqtt_foreground_notification_low_26 設為 true,將 8.0 以下設備也開啟前台通知服務
創建 MQTT 實例時需要傳送參數 MqttOptions,下面將介紹下部分參數;
1. Topic
MQTT 是一種發布/訂閱的消息協議, 通過設定的主題 Topic,
發布者向 Topic 發送的 payload 負載消息會經過伺服器, 轉發到所有訂閱襪橋
該 Topic 的訂閱者
通配符 : 假想移動端消息推送場景,有的系統消息是全體用戶接收,有的消息是 Android 或 iOS 設備接收, 又或者是某些消息具體推送到用戶,當然, 對應的多種類型消息可以通過多訂閱幾個對應的 Topic 解決,也可以使用通配符;
通配符有兩個, " + " 和 " # ", 與正斜杠 " / " 組合使用;加號只能表示一級Topic, 井號可以表示任意層級 Topic; 例如: 訂閱 Topic為 " System/+ ", 發布者發布的 Topic 可以是 System、System/Android、System/iOS; 但是不能是 System/iOS/123, 而訂閱的 Topic 如果是" System/# " 則可以收到;
注意,只有訂閱的 Topic 才可以使用 通配符, 發布和遺囑的 Topic 不能包含通配符.
2. ClientID
發布者和訂閱者都是屬於客戶端, 客戶端與服務端建立連接之後,發送的第一個報文消息必須是 Connect 消息隱好缺,而 Connect 的消息載荷中必須包含 clientID 客戶端唯一標識;
如果兩個客戶端的 clientID 一樣, 則服務端記錄第一個客戶端連接之後再收到第二個客戶端連接請求,則會向一個客戶端發送 Disconnect 報文斷開連接, 並連接第二個客戶端, 而如果此時設置了自動重連, 第一個客戶端再次連接,服務端又斷開與第二個的連接, 連上第一個客戶端, 如此將導灶辯致兩個客戶端不斷的被擠掉重連.
注意: clientID 使用的字元最好是 大小寫字母和數字, 長度最好限制在[1, 23] 之間;
3. 遺囑消息
可選參數, 客戶端沒有主動向服務端發起 disconnect 斷開連接消息,然而服務端檢測到和客戶端之間的連接已斷開, 此時服務端將該客戶端設置的遺囑消息發送出去
應用場景: 客戶端因網路等情況掉線之後, 可以及時通知到所有訂閱該遺囑 Topic 的客戶端;
遺囑 Topic 中不能存在通配符.
4. Session
客戶端和服務端之間建立的會話狀態, 一般用於消息保存, 如果設置清除 Session,則每次客戶端和服務端建立連接會創建一個新的會話,之前連接中的消息不能恢復,
而設置不清除會話, 對應發布者發送的 qos 為 1和2 的消息,還未被訂閱者接收確認,則需要保存在會話中, 以便訂閱者下次連接可以恢復這些消息;
注意: Session 存儲的消息是保存在內容中的, 所以如果不是重要的消息,最好是設置清除 Session, 或者設置 qos = 0;
5. 心跳包
標識客戶端傳輸一次控制報文到下一次傳輸之間允許的空閑時間;在這段時間內,如果客戶端沒有其他任何報文發送,必須發送一個 PINGREQ 報文到伺服器,而如果服務端在 1.5 倍心跳時間內沒有收到客戶端消息,則會主動斷開客戶端的連接,發送其遺囑消息給所有訂閱者。而服務端收到 PINGREQ 報文之後,立即返回 PINGRESP 報文給客戶端
心跳時間單位為秒,佔用2個位元組,最大 2^16 - 1 = 65535秒(18小時12分鍾15秒),設置為 0 表示不使用心跳機制; 心跳時間一般設置為幾分鍾或幾十秒即可,時間短點可以更快的發出遺囑消息通知掉線,但是時間短會增加消息頻率,影響服務端並發; 微信長連接為 300 秒,而三大運營商貌似也有個連接時間最小的為 5 分鍾。
6. qos
服務質量等級 qos 對應兩部分,一是客戶端到服務端發送的消息, 一是服務端到客戶端訂閱的消息; 從發布者到訂閱者實際 qos 為兩段路中 qos 最小的。
qos 可選值 0(最多交付一次)、1(最少交付一次)、2(正好交付一次);
qos = 0 :接收方不發送響應,發送方不進行重試;發送方只管發一次,不管是否發成功,也不管接收方是否成功接收,適用於不重要的數據傳輸;
qos = 1 :確保消息至少有一次到達接收方,發送方向接收方發送消息,需要等待接收方返回應答消息,如果發送方在一定時間之內沒有收到應答,發送方繼續下一次消息發送,直到收到應答消息,刪除本地消息緩存,不再發送;所以接收方可能收到1-n次消息;適用於需要收到所有消息,客戶端可以處理重復消息。
qos = 2 :確保消息只一次到達接收方,發送方和接收方之間消息處理流程最復雜;
Mqtt Qos 深度解讀 和 MQTT協議QoS2 准確一次送達的實現
7. payload 負載消息
位元組流類型, 是 MQTT 通信傳輸的真實數據
8. 保留消息
發布消息時設置, 對應參數 retain, 服務端將保留對應 Topic 最新的一條消息記錄; 保留消息的作用是每次客戶端連接上線都會收到其 Topic 的最後一條保留消息, 所以可能存在網路不穩定,頻繁掉線重連,每次重連重復收到保留消息;
可以向對應的 Topic 發送一條 空消息,用於清除保留消息。
MQTT 服務搭建 Apache Apollo 伺服器 搭建 MQTT 服務
Github 倉庫
mqtt 協議
Ⅲ android studio怎麼安裝mqtt
你好,
1、 下載Apollo伺服器,下載後解壓,然後運行apache-apollo-1.6\bin\apollo.cmd,輸入create mybroker(名字任意取,這里是根據 官網 介紹的來取的)創建伺服器實例,伺服器實例包含了所有的配置,運行時數據等,並且和一個伺服器喊哪進程關聯。
2、create mybroker之後會在bin目錄下生成mybroker文件夾,裡麵包含有很多信息,其中etc\apollo.xml文件下是配置伺服器信息的文件,etc\users.properties文件包含連接MQTT伺服器時用到的用戶名和密碼,後面會介紹,可以修改原始的admin=password,可以接著換行添加新的用戶名密碼。
3、打開cmd,運行…apache-apollo-1.6\bin\mybroker\bin\apollo-broker.cmd run 開啟伺服器,可以在瀏覽器中輸入 http://127.0.0.1:61680/ 查看是否安裝成功,該界面展示了topic,連接數等很多信息。
經過上面的簡單步驟,伺服器基本上就已經完成,下一篇將介紹Android客戶端的編寫和注意事項。
客戶端使用的API,開始我使用昌滲攔的是mqtt-client,使用過後發現問耐胡題百出,不能很好的滿足要求,後來使用了官方推薦的 Eclipse Paho ,下面開始客戶端代碼的編寫,為了方便測試這里有android和j2se兩個工程:
1、新建android工程MQTTClient
2、MainActivity代碼如下:
[java] view plainprint?
package ldw.mqttclient;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheledExecutorService;
import java.util.concurrent.TimeUnit;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView resultTv;
private String host = "tcp://127.0.0.1:1883";
private String userName = "admin";
private String passWord = "password";
private Handler handler;
private MqttClient client;
private String myTopic = "test/topic";
private MqttConnectOptions options;
private ScheledExecutor
Ⅳ Android 中使用MQTT(第一篇)
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議。它是一種發布/訂閱,極其簡單和輕量級的消息傳遞協議,專為受限設備和低帶寬,高延遲或不可靠的網路而設計。它的設計思想是輕巧、開放、簡單、規范,易於實現。這些特點使得它對很多場景來說都是很好的選擇,特別是對於受限的環境如機器與機器的通信(M2M)以及物聯網環境。相對於XMPP,MQTT更加輕量級,並且佔用的寬頻低。
MQTT協議有以下特點:
那麼問題來了?重連連接成功後重復接收到最後一條消息
MQTT推送消息訂閱端重復接收問題。
(背景)訂閱端斷開的時候,發布端多次推送消息。
(現象)訂閱端啟動時,接收到最後一條推送消息有兩次;即使Qos設置為2;依然是兩次。
經排查是因為
MqttMessage的Retained設置為了true;
該值很多文章上只說了是 消息保留機制,若設置為true,mqtt伺服器會保留每次發布的消息;較少提到 若訂閱某主題的客戶端重啟,則會把此主題之前發布的消息重新推送到客戶端。該值默認為false;去掉修改該值即可
那麼問題來了?重連連接後手動那麼多遺漏的消息,怎麼選擇只接收最新的一條消息呢?
MQTT推送消息訂閱端重復接收問題。
(背景)訂閱端斷開的時候,發布端多次推送消息。
(現象)訂閱端啟動時,接收到msg1,msg2,msg3 (這三個消息都是同一個類型消息,只需要處理最新的msg3就好,不然界面會刷新三次)這個誰有什麼好辦法沒呢?
GitHub地址: https://github.com/eclipse/paho.mqtt.android
mqtt的官方文檔: http://mqtt.org/documentation
Github上有中文翻譯: https://github.com/mcxiaoke/mqtt
在mole的build.gradle文件中添加依賴
在 AndroidManifest.xml 添加限權
在 AndroidManifest.xml 注冊Service (MyMqttService為自己寫的服務,下文會講到)
Ⅳ android消息推送GCM、XMPP、MQTT三種方案的優劣是什麼
android消息推送GCM、XMPP、MQTT三種方案的優劣如下:1、GCM
(1)優點:提供的服務、原生、簡單,無需實現和部署的服務端。
(2)缺點:Android版本限制(必須大於2.2版本),該服務在國內不夠穩定、需要用戶綁定相關的Google帳號,而且只受限於Google。
2、XMPP
(1)優點:成熟、強大、可擴展也性強、目前主要應用於聊天系統中,且已有開源的Java版的開發實例androidpn。
(2)缺點:協議較復雜、冗餘(基於XML)、也比較費流量和費電,部署硬體成本高。
3、MQTT
(1)優點:簡潔、小巧、可擴展性強、是比較省流量、省電。目前已有C++版的服務端組件rsmb。
(2)缺點:不夠成熟、實現起來較復雜、服務端組件rsmb不開源,也是部署硬體成本較高。
消息推送軟體可以使用深圳極光的。極光成立於2011年;憑借領先的人工智慧及機器學習技術,極光將在APP消息推送、用戶增長與活躍等方面為客戶提供服務。
Ⅵ android消息推送GCM、XMPP、MQTT三種方案的優劣,越仔細越好,有具體分析更好!
android消息推送GCM、XMPP、MQTT三種方案的優劣:1、GCM服務(Google Cloud Messaging)優點:Google提供的服務、原生、簡單,無需實現和部署服務端。缺點:Android版本限制,該服務在國內不夠穩定、需要用戶綁定Google帳號,受限於Google。
2、XMPP協議(Openfire + Spark + Smack)優點:協議成熟、強大、可擴展性強、目前主要應用於許多聊天系統中,且已有開源的Java版的開發實例androidpn。缺點:協議較復雜、冗餘(基於XML)、費流量、費電,部署硬體成本高。
3、MQTT協議優點:協議簡潔、小巧、可擴展性強、省流量、省電,目前已經應用到企業領域,且已有C++版的服務端組件rsmb。缺點:不夠成熟、實現較復雜、服務端組件rsmb不開源,部署硬體成本較高。
d消息推送可以去了解一下極光,極光是個不錯的平台。極光緊密圍繞移動開發者需求,打造的開發者服務平台,可以提供一站式SaaS服務,通過全面覆蓋PC、手機、感測器、無線路由器等多種設備數據,打造全域數據平台。當前,不斷更新的SaaS產品及服務已深受國內百萬開發者的認可和信賴。
Ⅶ 如何寫一個MQTT連接的android客戶端
MQTT是一個輕量級的消息發布/訂閱協議,它是實現基於手機客戶端的消息推送伺服器的理想解決方案。 我們可以從這里下載該項目的實例代碼,並且可以找到一個採用php書寫的伺服器端實現。 架構如下所示: wmqtt.jar 是IBM提供的MQTT協議的實現。你可以從如下站點下載它。你可以將該jar包加入你自己的Android應用程序中。 Really Small Message Broker (RSMB) ,他是一個簡單的MQTT代理,同樣由IBM提供。預設打開1883埠,應用程序當中,它負責接收來自伺服器的消息並將其轉發給指定的移動設備。 SAM是一個針對MQTT寫的PHP庫。你可以從這個下載它. send_mqtt.php是一個通過POST接收消息並且通過SAM將消息發送給RSMB的PHP腳本。 實例代碼: Ø 採用XMPP協議實現Android推送 這是我在項目中採用的方案。事實上Google官方的C2DM伺服器底層也是採用XMPP協議進行的封裝。 XMPP(可擴展通訊和表示協議)是基於可擴展標記語言(XML)的協議,它用於即時消息(IM)以及在線探測。這個協議可能最終允許網際網路用戶向網際網路上的其他任何人發送即時消息。 androidpn是一個基於XMPP協議的java開源Android push notification實現。它包含了完整的客戶端和伺服器端。經過源代碼研究我發現,該伺服器端基本是在另外一個開源工程openfire基礎上修改實現的,不過比較郁悶的是androidpn的文檔是由韓語寫的,所以整個研究過程基本都是讀源碼。它的實現示意圖如下: androidpn客戶端需要用到一個基於java的開源XMPP協議包asmack,這個包同樣也是基於openfire下的另外一個開源項目smack,不過我們不需要自己編譯,可以直接把androidpn客戶端裡面的asmack.jar拿來使用。客戶端利用asmack中提供的XMPPConnection類與伺服器建立持久連接,並通過該連接進行用戶注冊和登錄認證,同樣也是通過這條連接,接收伺服器發送的通知。 androidpn伺服器端也是java語言實現的,基於openfire開源工程,不過它的Web部分採用的是spring框架,這一點與openfire是不同的。Androidpn伺服器包含兩個部分,一個是偵聽在5222埠上的XMPP服務,負責與客戶端的XMPPConnection類進行通信,作用是用戶注冊和身份認證,並發送推送通知消息。另外一部分是Web伺服器,採用一個輕量級的HTTP伺服器,負責接收用戶的Web請求。伺服器架構如下: 最上層包含四個組成部分,分別是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager負責管理客戶端與伺服器之間的會話,Auth Manager負責客戶端用戶認證管理,Presence Manager負責管理客戶端用戶的登錄狀態,NotificationManager負責實現伺服器向客戶端推送消息功能。 伺服器端界面如下,分別對應了上述的幾個功能模塊: 發送以後,我們可以在手機端看到接收的消息:
Ⅷ 為什麼每份 Android 簡歷都說 「熟悉 MQTT 協議」
MQTT (Message Queuing Telemetry Transport,消息隊列遙測傳輸) 是一種基於 TCP/IP 協議族的應用層協議。MQTT 協議是專門針對硬體性能低下 & 網路狀況不穩定的場景設計的,這使得 MQTT 在物聯網和移動應用等受限場景得到廣泛應用。
目前,MQTT 主要分為兩個大版本:
物聯網和移動應用場景的特點是硬體性能低下和網路狀況不穩定,而 MQTT 協議就是專門針對這種環境設計的,主要在四個方面有優勢:
結論:這三種協議並沒有絕對的優勝者,最好的協議取決於具體的需求和限制條件。但如果只從帶寬、電池、功能多樣性這些基本條件看,MQTT 在其中是更占優的選擇。
MQTT 協議的設計特性中包含了一項 「高可靠性交付」,它需要一個保證可靠的底層傳輸層協議,因此 TCP 協議、TLS 協議、WebSocket 協議都可以作為 MQTT 的底層協議。而無連接的 UDP 協議會丟失或重排數據,不能滿足 MQTT 協議的傳輸需要。
MQTT 是基於發布 - 訂閱模型 (pub/sub) 的消息傳遞協議,與請求 - 響應模型不同,發布 - 訂閱模型主要有三種角色: publisher & subscriber & subscriber :
當 client 發布某個主題的消息時,broker 會將該消息分發給任何已訂閱該主題的 client。通常來說,client 不會存儲消息,一旦消橡舉息被發送到這些 client,消息就會從 broker 上刪除。另外,保留消息、持久連接和服務質量 QoS 可能會導致消息臨時存儲在 broker 上。
發布 - 訂閱模式使得 消息的發布者和訂閱者解耦 ,主要體現為空間解耦和時間解耦:
圖片引用自 https://juejin.cn/post/6976441705067184135 —— cxuan 著
一個 MQTT 消息由三部分組成:
1、固定報頭: 每一個 MQTT 消息都包含一個固定報頭,包含消息類型、標志位和剩餘長度三個部分。固定報頭長度為 2 ~ 5 位元組,具體取決於 「剩餘長度」 的大小,格式如下:
2、可變報頭: 不同消息的可變報頭內容不一樣,不過其中有一個比較通用的欄位:
3、載荷: 某些 MQTT 消息會包含一個有效載荷,對於 PUBLISH 消息來說,有效載荷就是應用消息。
MQTT 的連接總是發生在 client 和 broker 之間,兩個 client 之間不會互相感知。請求連接時,client 會向 broker 發送 CONNECT 連接消息,broker 接受連接後會響應 CONNACK 連接確認消息。一旦連接建立,連接會一直保持打開狀態,直到 client 發送 DISCONNECT 斷開連接消息或連接異常中斷。
CONNECT 是 client 發送給 broker 的首個消息,並且在一次連接中,client 只能發送一次 CONNECT 消息,發送的第二個 CONNECT 消息會被 broker 當作違反協議處理,並斷開連接。在 CONNECT 消息中,主要包含以下內容:
CONNACK 消息用於確認 CONNECT 消息。CONNECT 是 client 發送給 broker 的首個消息,相應地,broker 發送給 client 的首個消息一定是 CONNACK 消息。在 CONNACK 消息中,主要包含以下內容:
DISCONNECT 消息由 client 發送給 broker,用於斷開連接。 DISCONNECT 消息沒有可變報頭和有效載荷,也沒有對應的確認應答消息,表示一個干凈利索地斷開連接操作 。斷開連接後,client 不能再發送除 CONNECT 消息之外的消息,broker 也需要丟棄和當前會話有環的遺囑消息。
MQTT 是檔虛基於發布訂閱模型的協議,在建立連行如燃接後,client 可以向 broker 訂閱感興趣的一個或多個話題。
SUBSCRIBE 消息由 client 發送給 broker,用於訂閱感興趣的話題,SUBSCRIBE 消息主要包含以下內容:
SUBACK 消息用於確認 SUBSCRIBE 消息。SUBACK 消息主要包含以下內容:
UNSUBSCRIBE 消息由 client 發送給 broker,用於退訂不感興趣的話題,UNSUBSCRIBE 消息主要包含以下內容:
UNSUBACK 消息用於確認 UNSUBSCRIBE 消息。UNSUBACK 消息非常簡單,只有一個包唯一標識(位於可變報頭)。
當 MQTT client 在連接到 broker 之後就可以發送消息了,每條 PUBLISH 消息都包含一個 topic ,broker 會根據 topic 將消息發送給感興趣的 client。除此之外,每條消息還會包含一個 Payload,Payload 是真正發布的應用消息,載荷的內容和格式由應用層決定,MQTT 協議層不關心。
PUBLISH 消息可以由 client 發送給 broker,也可以由 broker 發送給 client,用來運送應用層消息。PUBLISH 消息主要包含以下內容:
PUBLISH 消息的接收方需要發送確認應答,不同 QoS 等級的 PUBLISH 消息響應的消息不同:
當 client 和 broker 在一段時間內沒有數據交互時,client 會發送 PINGREQ 探測消息,用於判斷連接是否正常,來決定是否要關閉該連接,這就是 MQTT 協議的保活機制。
PINGREQ 消息由 client 發送給 broker。
PINGRESP 消息由 broker 發送給 client,代表 client 是存活的。
MQTT 主題本質上是一種 「定址形式」 ,用於將應用層消息分發到期望的客戶端。MQTT 主題是一種類似於文件系統的分層結構,使用 「/」 正斜杠 作為分隔符。
客戶端訂閱主題時,可以訂閱確定的主題(例如 「group/group123」),也可以使用 「通配符」 來同時訂閱多個主題。需要注意的是: 在發布消息是不允許使用主題通配符,client 每次發布消息只能發布到單個主題。
$SYS 主題是 broker 上默認創建的只讀主題,除此之外,broker 不會默認創建任何主題,所有主題都是由客戶端訂閱或發布才創建的,都不是永久性的。關於 $SYS 主題的更多介紹在 這里
當 client 連接到 broker 時,可以使用持久連接或非持久連接,這是通過 CONNECT 消息中的 CleanSession 標志來決定的(當 CleanSession = 0 時表示持久連接)。對於持久會話,broker 會存儲會話狀態;而對於非持久會話,broker 不會存儲 client 的任何內容。會話狀態主要包含以下內容:
QoS 0 等級的 PUBLISH 消息的交付能力完全依賴於底層傳輸層,QoS 1 和 QoS 2 等級開始在應用層提高 PUBLISH 消息的交付能力。當消息丟失時,發送端會重新發送早前嘗試發送過的 PUBLISH 消息(DUP = 1),接收者收到消息也會發送確認響應消息。
在 QoS 0 的等級的 PUBLISH 消息中不包含包唯一標識。發送者不考慮消息交付結果,接收者也不發送響應。接收者最多隻能收到一次消息,也有可能一次也收不到。
在 QoS 1 等級的 PUBLISH 消息中包含包唯一標識,發送方會一直將該消息當作 「未確認」 的消息,直到收到對應的 PUBACK 確認消息。具體消息流如下:
QoS 2 是最高的服務質量,保證消息不會丟失也不會重復,缺點是會增加開銷。在 QoS 2 等級的 PUBLISH 消息中包含包唯一標識,發送者會一直將該消息當作 「未確認」 的消息,知道收到對應的 PUBCOMP 確認消息。
當 client 發布某個主題的消息時,broker 會將該消息分發給任何已訂閱該主題的 client,隨後這條消息會從 broker 上刪除。可以設置 RETAIN 保留標志設置該 PUBLISH 消息為保留消息,broker 會存儲該主題的最後一條保留消息,當新的 client 注冊訂閱時,並且匹配該消息主題時,該保留消息會發送給訂閱者。 需要注意:broker 只會為每個主題保存最近一條保留消息,新收到的 RETAIN = 1 的消息會覆蓋原本那條保留消息;
持久會話 & 服務質量等級 & 保留消息都會影響新訂閱者是否接受消息,總結如下表:
標記 DUP = 1 的消息是重復發送的消息,MQTT 消息重傳有兩種場景:
需要注意:DUP 標志只對 OoS > 0 的消息有效,所有 QoS = 0 的消息 DUP 標志必須設置為 0;
TCP 協議的報文重傳機制是對所有 TCP 報文有效的重傳機制,而 MQTT 協議的消息重傳機制只對一小部分消息有效,用於實現更可靠的消息交付保證。雖然 TCP 協議在一般情況下可以保證不丟包,但是這並不是絕對的,依然存在請求超時或者連接中斷等情況。而 MQTT 協議的 QoS 1 和 QoS 2 要求更可靠的交付能力,並且需要在客戶端重連後也能保證交付。因此,MQTT 協議也定義了一個消息重傳機制。
到這里,關於 MQTT 協議的工作原理 & 協議消息格式 & 核心特性等內容就介紹完了。我知道你應該會對 MQTT 協議的實戰應用更加感興趣,下一篇文章里,我將帶你實現基於 MQTT 協議的 IM 服務,請關注。