最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java MQTT實戰(zhàn)應用

 更新時間:2025年06月27日 11:23:43   作者:某代碼  
本文詳解MQTT協(xié)議,涵蓋其發(fā)布/訂閱機制、低功耗高效特性、三種服務質量等級(QoS0/1/2),以及客戶端、代理、主題的核心概念,最后提供Linux部署教程、SpringBoot整合方法與MQTTX工具下載鏈接,對java mqtt相關知識感興趣的朋友一起看看吧

一、MQTT協(xié)議

MQTT(Message Queuing Telemetry Transport)是一種輕量級的發(fā)布/訂閱式消息傳遞協(xié)議,專為物聯(lián)網(wǎng)(IoT)和嵌入式設備設計,它簡化了設備之間的通信,并優(yōu)化帶寬使用。 

在MQTT中,消息的發(fā)送者稱為“發(fā)布者”(Publisher)消息的接收者稱為“訂閱者”(Subscriber),而消息的中轉站是“代理”(Broker)。發(fā)布者將消息發(fā)布到特定的“主題”(Topic),代理負責將消息轉發(fā)給所有訂閱了該主題的訂閱者。這種模式解耦了消息的發(fā)送者和接收者,使得系統(tǒng)更加靈活和可擴展。

二、MQTT優(yōu)點

  • 低功耗、高效、可靠。
  • 輕量級:協(xié)議設計簡潔,消息頭部開銷小,適用于低帶寬和低功耗設備。
  • 支持發(fā)布/訂閱模式:設備可以發(fā)布消息到主題,其他設備可以訂閱對應的主題接收消息。這一模式解耦了消息生產(chǎn)者和消費者,簡化了系統(tǒng)架構,提高了靈活性和可擴展性。
  • 可拓展性和兼容性:MQTT允許使用不同的傳輸協(xié)議,包括TCP、WebSocket等。它的簡單性使得它易于與其他協(xié)議和服務集成。
  • 持久化會話:MQTT支持消息持久化,允許設備在斷線后重新連接時恢復之前的會話狀態(tài),包括未完成的訂閱和未收到的消息隊列,這對于網(wǎng)絡不穩(wěn)定或經(jīng)常斷開的物聯(lián)網(wǎng)環(huán)境尤為重要。

三、三種服務質量等級

  • QoS = 0(最多一次):消息最多被傳遞一次,可能丟失,但不會重復。此級別提供的可靠性最低,一旦消息被客戶端發(fā)送出去,它不會等待任何確認,即“Fire and Forget”模式。這意味著發(fā)布者不會確認消息是否到達Broker,也不會嘗試重傳失敗的消息)
  • QoS = 1(至少一次):消息至少被傳遞一次,可能會重復,但不會丟失。此級別保證消息至少被送達一次,但有可能被重復發(fā)送。在QoS 1下,Broker(消息隊列服務器)會發(fā)送PUBACK確認消息給客戶端,如果客戶端沒有收到確認,則會重發(fā)消息,直到收到確認為止。因此,雖然可以確保消息不會丟失,但也可能導致相同消息被多次接收
  • QoS = 2(恰好一次):消息保證被傳遞一次且僅一次,不會丟失也不會重復。這是MQTT提供的最高級別服務質量,確保每條消息只會被接收一次,提供最嚴格的可靠性保證。該機制通過一個復雜的四次握手過程實現(xiàn),包括消息標識符的確認和釋放,確保消息既不丟失也不重復

四、客戶端、代理、主題

MQTT協(xié)議中,三個核心概念分別是客戶端(Client)、代理(Broker)和主題(Topic),它們共同構成了MQTT通信的基礎框架,實現(xiàn)了消息的發(fā)布與訂閱機制。

1. 客戶端(Client):

作用:客戶端可以是消息的發(fā)布者(Publisher)或訂閱者(Subscriber),也可以同時具備這兩種角色。發(fā)布者負責向MQTT系統(tǒng)中的某個主題發(fā)布消息;訂閱者則訂閱感興趣的主題,以接收來自該主題的消息??蛻舳丝梢允莻鞲衅?、手機應用、服務器程序等各種設備或應用。

相互關系:客戶端不直接相互通信,而是通過Broker中轉消息。發(fā)布者客戶端向Broker發(fā)送消息,而訂閱者客戶端從Broker接收消息。

 2. 代理(Broker):

作用:Broker是MQTT通信的中心節(jié)點,它接收來自發(fā)布者客戶端的消息,并根據(jù)消息中的主題分發(fā)給相應的訂閱者客戶端。Broker負責維護客戶端的連接狀態(tài)、存儲消息(如果需要持久化)、管理主題的訂閱關系等。

相互關系:Broker是客戶端之間的中介,它管理著所有的消息流動。每個客戶端都與Broker建立連接,無論發(fā)布還是訂閱操作,都必須通過Broker來完成。

3. 主題(Topic):

作用:主題是MQTT中消息的分類標簽,類似于一個消息通道或者頻道。每個消息都會關聯(lián)一個主題,發(fā)布者通過指定主題來決定消息的去向,而訂閱者通過訂閱特定主題來接收相關消息。

相互關系:主題是連接發(fā)布者與訂閱者的橋梁。發(fā)布者向特定主題發(fā)布消息,而訂閱者則通過訂閱這些主題來接收消息。Broker根據(jù)主題匹配規(guī)則,確保消息被正確地路由到已訂閱該主題的所有客戶端。主題可以是靜態(tài)的字符串,也可以包含通配符(如"+“和”#”)來實現(xiàn)靈活的匹配規(guī)則。

五、實戰(zhàn)應用

1. 安裝部署(linux)

 -- 拉取鏡像

docker pull emqx/emqx:5.0.26

-- 安裝容器

docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.0.26

2. 訪問控制臺

訪問:ip:18083

默認的用戶名密碼:admin/public

3. 客戶端認證

4. 創(chuàng)建用戶

5. SpringBoot中整合

5.1 導入jar包
<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-stream</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>
5.2 yml配置
mqtt:
  #MQTT-服務器連接地址,如果有多個,用逗號隔開
  host: tcp://192.168.17.101:1883
  #MQTT-連接服務器默認客戶端ID,可以隨便寫
  clientId: mqtt_test
  #MQTT-用戶名
  username: zhangsan
  #MQTT-密碼
  password: 123456
  #MQTT-指定消息的推送和訂閱主題
  topic: test
  #連接超時
  timeout: 100
  #設置會話心跳時間
  keepalive: 10
5.3 MqttConfig.java
@Slf4j
@Configuration
@ConfigurationProperties("mqtt")
@Data
public class MqttConfig {
    String host;
    String clientId;
    String topic;
    String username;
    String password;
    Integer timeout;
    Integer keepalive;
    // MQTT客戶端的配置類,可以設置mqtt服務器的賬號和密碼
    @Bean
    public MqttConnectOptions mqttConnectOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        // 設置是否自動重連
        options.setAutomaticReconnect(true);
        // false 保持會話不被清理自動重連后才能收到訂閱的主題消息(包括離線時發(fā)布的消息)
        options.setCleanSession(true);
        options.setConnectionTimeout(timeout);
        options.setKeepAliveInterval(keepalive);
        return options;
    }
    // MqttClient 類,MQTT的客戶端類,可以去連接MQTT服務器
    @Bean
    public MqttClient mqttClient(MqttConnectOptions mqttConnectOptions) {
        try {
            MqttClient client = new MqttClient(host, clientId);
            // 回調(diào)對象,監(jiān)聽消息的獲取,采用的接口回調(diào),可以獲取對應訂閱到的消息
            client.setCallback(new MessageCallback(client, this.topic, mqttConnectOptions));
            // 連接
            client.connect(mqttConnectOptions());
            return client;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("mqtt 連接異常");
        }
    }
}
5.4 MessageCallback.java
/**
 * consumer 消費者,對收到的消息進行處理
 */
//@Component
@Slf4j
public class MessageCallback implements MqttCallbackExtended {
    private MqttClient client;
    private String topic;
    private MqttConnectOptions mqttConnectOptions;
    public MessageCallback() {
    }
    public MessageCallback(MqttClient mqttClient, String topic, MqttConnectOptions mqttConnectOptions) {
        this.client = mqttClient;
        this.topic = topic;
        this.mqttConnectOptions = mqttConnectOptions;
    }
    // 在客戶端連接斷開時觸發(fā)
    @Override
    public void connectionLost(Throwable throwable) {
        if (client != null && !client.isConnected()) {
            log.info("{}, 連接斷開,正在reconnect....", client.getClientId());
            try {
                client.reconnect();
                // client.connect(this.mqttConnectOptions);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        } else {
            log.info("未知異常,連接斷開");
        }
    }
    // 在客戶端與服務器連接成功時觸發(fā)
    @Override
    public void connectComplete(boolean b, String url) {
        log.info("{} 上線了{} {}", client.getClientId(), b, url);
        try {
            client.subscribe(this.topic, 0);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    // 在客戶端收到訂閱的消息時觸發(fā)
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.info("接收消息主題 : " + topic);
        log.info("接收消息內(nèi)容 : " + new String(message.getPayload()));
        String msg = new String(message.getPayload());
        try {
            JSONObject jsonObject = JSON.parseObject(msg);
            String clientId = String.valueOf(jsonObject.get("clientid"));
            if (topic.endsWith("disconnected")) {
                log.info("設備{}已掉線", clientId);
            } else if (topic.endsWith("connected")) {
                log.info("設備{}已上線", clientId);
            } else {
                log.info("其他主題的消息");
            }
        } catch (JSONException e) {
            log.error("JSON Format Parsing Exception : {}", msg);
        }
    }
    // 在客戶端發(fā)送消息至服務器成功時觸發(fā)
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        log.info("deliveryComplete---------" + token.isComplete());
    }
}
5.5 MqttUtil.java
@Component
@Slf4j
public class MqttUtil {
    @Autowired(required = false)
    private MqttClient client;
    /**
     * 訂閱主題
     *
     * @param topic
     * @param qos
     */
    public void subscribe(String topic, int qos) {
        try {
            client.subscribe(topic, qos);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    /**
     * 訂閱主題
     *
     * @param topic
     */
    public void subscribe(String topic) {
        try {
            client.subscribe(topic);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    /**
     * 發(fā)布消息
     *
     * @param qos         連接方式 0,1,2 默認0
     * @param retained    是否保留最新的消息
     * @param topic       訂閱主題
     * @param pushMessage 消息體
     */
    public void publish(int qos, boolean retained, String topic, String pushMessage) {
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retained);
        message.setPayload(pushMessage.getBytes());
        MqttTopic mqttTopic = client.getTopic(topic);
        if (null == mqttTopic) {
            log.error("topic not exist");
        }
        MqttDeliveryToken token;
        try {
            // 發(fā)送消息
            token = mqttTopic.publish(message);
            token.waitForCompletion();
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    /**
     * 發(fā)布消息
     *
     * @param topic       主題
     * @param pushMessage 消息內(nèi)容
     */
    public void publish(String topic, String pushMessage) {
        publish(0, true, topic, pushMessage);
    }
}
5.6 MqttController.java
@RestController
@Slf4j
public class MqttController {
    @Autowired
    MqttClient client;
    @Autowired
    MqttUtil mqttUtil;
    @GetMapping("/send")
    public String send() {
        try {
            for (int i = 0; i < 3; i++) {
                mqttUtil.publish("test", "消息hello" + i);
                log.info("發(fā)送成功:{}", i);
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }
}

六、MQTTX官網(wǎng)地址

MQTT客戶端工具MQTTX下載地址 : MQTTX:全功能 MQTT 客戶端工具

到此這篇關于Java MQTT實戰(zhàn)應用的文章就介紹到這了,更多相關Java MQTT內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java面向對象程序設計:繼承,多態(tài)用法實例分析

    Java面向對象程序設計:繼承,多態(tài)用法實例分析

    這篇文章主要介紹了Java面向對象程序設計:繼承,多態(tài)用法,結合實例形式分析了java繼承與多態(tài)的相關概念、原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下
    2020-04-04
  • java發(fā)送http的get、post請求實現(xiàn)代碼

    java發(fā)送http的get、post請求實現(xiàn)代碼

    下面小編就為大家?guī)硪黄猨ava發(fā)送http的get、post請求實現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • Java線程休眠的5種方法

    Java線程休眠的5種方法

    這篇文章主要介紹了Java線程休眠的5種方法,分別是Thread.sleep、TimeUnit、wait、Condition、LockSupport,下面文章將對這五種方法進行詳細講解,需要的小伙伴可以參考一下
    2022-05-05
  • 劍指Offer之Java算法習題精講鏈表專題篇

    劍指Offer之Java算法習題精講鏈表專題篇

    跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質的變化
    2022-03-03
  • SSH框架網(wǎng)上商城項目第29戰(zhàn)之使用JsChart技術顯示商品銷售報表

    SSH框架網(wǎng)上商城項目第29戰(zhàn)之使用JsChart技術顯示商品銷售報表

    這篇文章主要為大家詳細介紹了SSH框架網(wǎng)上商城項目第29戰(zhàn)之使用JsChart技術顯示商品銷售報表,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Java中Spring擴展點詳解

    Java中Spring擴展點詳解

    這篇文章主要介紹了Java中Spring技巧之擴展點的應用,下文Spring容器的啟動流程圖展開其內(nèi)容的相關資料,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06
  • springboot亂碼問題排查思路解析

    springboot亂碼問題排查思路解析

    這篇文章主要為大家介紹了springboot亂碼問題排查思路解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Spring Security整合CAS的示例代碼

    Spring Security整合CAS的示例代碼

    本篇文章主要介紹了Spring Security整合CAS的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • java編寫汽車租賃系統(tǒng)

    java編寫汽車租賃系統(tǒng)

    這篇文章主要為大家詳細介紹了java編寫汽車租賃系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java基于NIO實現(xiàn)聊天室功能

    Java基于NIO實現(xiàn)聊天室功能

    這篇文章主要為大家詳細介紹了Java基于NIO實現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論

衡阳县| 辽阳市| 额尔古纳市| 延长县| 忻城县| 阳高县| 霍林郭勒市| 江油市| 中西区| 科技| 乌兰察布市| 吉隆县| 教育| 会东县| 平山县| 石景山区| 顺昌县| 大悟县| 新郑市| 安远县| 武义县| 滨州市| 惠安县| 渑池县| 冕宁县| 宁海县| 通榆县| 衡水市| 白朗县| 休宁县| 长岭县| 白水县| 新田县| 赣榆县| 黄大仙区| 喜德县| 赤峰市| 东丽区| 婺源县| 清水县| 夏邑县|