package cn.iododer.yudao.module.mqtt.util;

import cn.iododer.yudao.module.mqtt.config.MqttFactory;
import cn.iododer.yudao.module.mqtt.config.MqttProperties;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

@Component
public class MqttUtils {

    @Autowired
    private MqttProperties config;

    /**
     * 发布消息
     *
     * @param qos 0-至多1次、1-至少1次、2-一次
     * @param retained 是否保留：true-sub重新连接mqtt服务端时，总能拿到该主题的最新消息、false-sub重新连接mqtt服务端时，只能拿到连接后发布的消息
     * @param topic 话题
     * @param message 消息内容
     */
    public void pub(String topic, String message) throws MqttException {
        // 获取客户端实例
        MqttClient client = MqttFactory.getInstance();
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(config.getQos());
        mqttMessage.setRetained(false);
        // 此处必须指明编码方式，否则会出现订阅端中文乱码的情况
        mqttMessage.setPayload(message.getBytes(StandardCharsets.UTF_8));
        // 主题的目的地，用于发布/订阅信息
        MqttTopic mqttTopic = client.getTopic(topic);
        // 提供一种机制来跟踪消息的传递进度
        // 用于在以非阻塞方式（在后台运行）执行发布是跟踪消息的传递进度
        MqttDeliveryToken token;
        try {
            // 将指定消息发布到主题，但不等待消息传递完成，返回的token可用于跟踪消息的传递状态
            // 一旦此方法干净地返回，消息就已被客户端接受发布，当连接可用，将在后台完成消息传递。
            token = mqttTopic.publish(mqttMessage);
            token.waitForCompletion();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }


    /**
     * 断开连接
     */
    public static void disConnect() {
        try {
            // 获取客户端实例
            MqttClient client = MqttFactory.getInstance();
            client.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}