MQTT의 이해 및 사용

MQTT는 1999년 IBM에서 출시한 TCP/IP 프로토콜 기반의 게시/구독 모델 기반 경량 프로토콜입니다.
여기에 이미지 설명 삽입

프로세스 이해: 구독자는 구독 시 주제(주제)와 서비스 품질(QoS)을 선택한 다음 게시자가 메시지를 게시하고 에이전트는 주제에 따라 관련 구독자에게 다른 메시지를 푸시합니다.
주제: 신문 구독을 예로 들면 모든 사람의 선호도는 군사, 금융 및 기타 주제입니다.
QoS: 전송 품질(메시지 게시자와 구독자가 동의), QoS0(게시 후 상관 없이 최대 한 번), QoS1(전송 후, 사양에 따라 재전송 시작 ​​여부, 최소 한 번), QoS2 (한 번만 확인)

응용 시나리오: 이 프로토콜은 오버헤드가 적고 네트워크 요구 사항이 높지 않기 때문에 주로 사물 인터넷에서 사용됩니다.이번 사용 시나리오는 Android 시스템과 통신하고 위치 정보를 반환하는 것입니다.

1. MQTT 종속성

여기에 springboot 통합 mqtt가 있으므로 pom.xml에 추가하십시오.

<!--Mqtt依赖-->
<dependency>
	<groupId>org.springframework.integration</groupId>
	<artifactId>spring-integration-mqtt</artifactId>
</dependency>

2. MQTT 클라이언트

setCleanSession은 세션 수명 주기를 나타내며 기본값은 True입니다. true일 경우 새로운 세션을 생성한다는 의미이며, 클라이언트 연결이 끊어지면 해당 세션은 자동으로 소멸됩니다. false이면 영구 세션을 생성한다는 의미이며 클라이언트 연결이 끊어진 후에도(ClientID가 변경되지 않은 경우) 세션이 시간 초과되어 로그아웃될 때까지 세션이 계속 유지됩니다.

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.stereotype.Component;

/**
 * 类描述:Mqtt连接工具类
 *
 * @ClassName MQTTConnect
 * @Author yeapt
 * @Date 2023-07-20 12:22
 */

@Component
public class MQTTConnect {
    
    
    //mqtt服务器的地址和端口号
    private String HOST = "tcp://192.168.1.113:123";
    private final String clientId = "DC" + (int) (Math.random() * 100000000);
    private MqttClient mqttClient;

    /**
     * 客户端connect连接mqtt服务器
     *
     * @param userName     用户名
     * @param passWord     密码
     * @param mqttCallback 回调函数
     **/
    public void setMqttClient(String userName, String passWord, MqttCallback mqttCallback) throws MqttException {
    
    
        MqttConnectOptions options = mqttConnectOptions(userName, passWord);
        if (mqttCallback == null) {
    
    
            mqttClient.setCallback(new Callback());
        } else {
    
    
            mqttClient.setCallback(mqttCallback);
        }
        mqttClient.connect(options);
    }

    /**
     * MQTT连接参数设置
     */
    private MqttConnectOptions mqttConnectOptions(String userName, String passWord) throws MqttException {
    
    
        mqttClient = new MqttClient(HOST, clientId, new MemoryPersistence());
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(userName);
        options.setPassword(passWord.toCharArray());
        //连接超时时间,默认:30
        options.setConnectionTimeout(10);
        //重连配置,默认:false
        options.setAutomaticReconnect(true);
        //会话生命周期,默认:true
        options.setCleanSession(true);
        //默认:60
        options.setKeepAliveInterval(60);
        return options;
    }

    /**
     * 关闭MQTT连接
     */
    public void close() throws MqttException {
    
    
        mqttClient.disconnect();
        mqttClient.close();
    }

    /**
     * 向某个主题发布消息 默认qos:1
     *
     * @param topic:发布的主题
     * @param msg:发布的消息
     */
    public void pub(String topic, String msg) throws MqttException {
    
    
        MqttMessage mqttMessage = new MqttMessage();
        //Qos2:保证消息至少传输成功1次
        mqttMessage.setQos(2);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    /**
     * 向某个主题发布消息
     *
     * @param topic: 发布的主题
     * @param msg:   发布的消息
     * @param qos:   消息质量    Qos:0、1、2
     */
    public void pub(String topic, String msg, int qos) throws MqttException {
    
    
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(qos);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    /**
     * 订阅某一个主题 ,此方法默认的的Qos等级为:1
     *
     * @param topic 主题
     */
    public void sub(String topic) throws MqttException {
    
    
        mqttClient.subscribe(topic);
    }

    /**
     * 订阅某一个主题,可携带Qos
     *
     * @param topic 所要订阅的主题
     * @param qos   消息质量:0、1、2
     */
    public void sub(String topic, int qos) throws MqttException {
    
    
        mqttClient.subscribe(topic, qos);
    }
}

3. MQTT 콜백 기능

비즈니스를 처리하는 데 사용되며 정보를 얻은 후 처리하는 방법

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;

/**
 * 类描述:MQTT回调
 *
 * @ClassName Callback
 * @Author yeapt
 * @Date 2023-07-20 12:24
 */
@Slf4j
public class Callback implements MqttCallback {
    
    
    /**
     * MQTT 断开连接会执行此方法
     */
    @Override
    public void connectionLost(Throwable throwable) {
    
    
        log.info("断开了MQTT连接 :{}", throwable.getMessage());
        log.error(throwable.getMessage(), throwable);
    }

    /**
     * publish发布成功后会执行到这里
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
    
    
        log.info("发布消息成功");
    }

    /**
     * subscribe订阅后得到的消息会执行到这里
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
    
    
        //  TODO    此处可以将订阅得到的消息进行业务处理、数据存储
        log.info("收到来自 " + topic + " 的消息:{}", new String(message.getPayload()));
}}

4. 디버깅 및 사용

개발 단계에서는 메인 방식을 테스트용으로 사용하지만 실제 사용에서는 일반적으로 프로그램이 시작될 때 모니터링을 켭니다.

/**
* main函数自己测试用
*/
public static void main(String[] args) throws MqttException {
    
    
  MQTTConnect mqttConnect = new MQTTConnect();
  mqttConnect.setMqttClient("admin", "password", new Callback());
  mqttConnect.sub("/abcd-trace/#",2);
  mqttConnect.pub("/abcd-trace/#", "Mr.Y" + (int) (Math.random() * 100000000));
    }
import com.stylefeng.guns.modular.xujianapi.util.mqtt.Callback;
import com.stylefeng.guns.modular.xujianapi.util.mqtt.MQTTConnect;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

/**
 * 类描述:MQTT监听类
 *
 * @ClassName MQTTListener
 * @Author yeapt
 * @Date 2023-07-20 12:27
 */
@Slf4j
@Component
public class MQTTListener implements ApplicationListener<ContextRefreshedEvent> {
    
    
    private final MQTTConnect server;

    @Autowired
    public MQTTListener(MQTTConnect server) {
    
    
        this.server = server;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
    
    
        try {
    
    
            server.setMqttClient("admin", "password", new Callback());
            server.sub("/abcd-trace/#");
        } catch (MqttException e) {
    
    
            log.error(e.getMessage(), e);
        }
    }
}

이는 클라이언트에 대한 설명일 뿐이며, 추후 기회가 된다면 퍼블리셔와 에이전트의 글에 대해서도 공부해보도록 하겠습니다.

Supongo que te gusta

Origin blog.csdn.net/weixin_43487532/article/details/131827651
Recomendado
Clasificación