MQTT Provider AND Consumer

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import lombok.Data;
import lombok.ToString;

/**
 * MQTT平台配置
 *
 **/
@Data
@ToString
@Configuration
@ConfigurationProperties(prefix = "xx.mqtt")
public class XxMqttConfig {

	/**
	 * MQTT平台host IP and PORT
	 **/
	private String host = "tcp://192.168.10.199:1883";
	/**
	 * MQTT-username
	 **/
	private String username = "xxxxx";
	/**
	 * MQTT-password
	 **/
	private String password = "xxxxx";

	/**
	 * 订阅主题的客户端ID
	 */
	private String clientId = "xxxxx-dl-client";

	private String sendId = "xxxx-dl-send";

	/**
	 * 主题集合
	 */
	private String topics = "testtopic/#,1";

	private Integer timeout = 100;

	private Integer keepalive = 20;

	/**
	 * QoS0 代表,Sender 发送的一条消息,Receiver 最多能收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,也就算了; 
	 * QoS1 代表,Sender 发送的一条消息,Receiver 至少能收到一次,也就是说 Sender 向Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,但是因为重传的原因,Receiver 有可能会收到重复的消息;
	 * QoS2 代表,Sender 发送的一条消息,Receiver 确保能收到而且只收到一次,也就是说 Sender 尽力向 Receiver发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,同时保证 Receiver 不会因为消息重传而收到重复的消息。
	 * 
	 */
	private Integer qos = 2;
	
	/**
	 * MQTT开关
	 */
	private Boolean open = false;

}
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

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.persist.MemoryPersistence;
import org.springframework.context.annotation.Configuration;

import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.xxx.xxx.xxx.xxx.config.DhMqttConfig;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class XxttConsumerConfig {

	@Resource
	private XxMqttConfig mqtt;

	/**
	 * 客户端对象
	 */
	private MqttClient client;

	/**
	 * 在bean初始化后连接到服务器
	 */
	@PostConstruct
	private void init() {
		if (mqtt.getOpen()) {//开关控制
			if (connect(mqtt.getHost(), mqtt.getClientId()))
				log.info("订阅者:" + mqtt.getClientId() + "成功连接到:" + mqtt.getHost() + "MQTT服务SUCCESS");
			subscribeDefaultTopic();	
		}
	}

	/**
	 * 客户端连接服务端
	 */
	private Boolean connect(String host, String clientId) {
		try {
			// 创建MQTT客户端对象
			client = new MqttClient(host, clientId, new MemoryPersistence());
			// 设置回调
			client.setCallback(new MqttConsumerCallBack());
			client.connect(setOptions());
			return true;
		} catch (MqttException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 连接设置
	 * 
	 * @return
	 */
	private MqttConnectOptions setOptions() {
		MqttConnectOptions options = new MqttConnectOptions();
		// 是否清空session,设置为false表示服务器会保留客户端的连接记录,客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
		// 设置为true表示每次连接到服务端都是以新的身份
		options.setCleanSession(true);
		// 设置连接用户名
		options.setUserName(mqtt.getUsername());
		// 设置连接密码
		options.setPassword(mqtt.getPassword().toCharArray());
		// 设置超时时间,单位为秒
		options.setConnectionTimeout(mqtt.getTimeout());
		// 设置心跳时间 单位为秒,表示服务器每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线
		options.setKeepAliveInterval(mqtt.getKeepalive());
		options.setAutomaticReconnect(true);
		// 设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息
		options.setWill("willTopic", (mqtt.getClientId() + "与服务器断开连接").getBytes(), 0, false);
		return options;
	}

	/**
	 * 消息等级,和主题数组一一对应,服务端将按照指定等级给订阅了主题的客户端推送消息 String[] topics = { "topic1","topic2"
	 * };int[] qos = { 1, 1 }; 订阅默认主题
	 */
	public void subscribeDefaultTopic() {
		// 默认主题
		List<String> topicList = Arrays.asList(mqtt.getTopics().trim().split(","));
		String[] topics = new String[topicList.size()];
		topicList.toArray(topics);
		int[] qos = new int[topicList.size()];
		for (int i = 0; i < topics.length; i++) {
			qos[i] = mqtt.getQos();
		}
		try {
			// 订阅主题
			client.subscribe(topics, qos);
		} catch (MqttException e) {
			e.printStackTrace();
		}
		log.info("正在订阅默认主题列表:" + JSON.toJSONString(topics) + "===对应Qos列表:" + JSON.toJSONString(qos) + "===SUCCESS");
	}
	
	/**
	 * 断开连接
	 */
	public void disConnect() {
		try {
			client.disconnect();
		} catch (MqttException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 订阅主题
	 */
	public void subscribe(String topic, int qos) {
		try {
			client.subscribe(topic, qos);
		} catch (MqttException e) {
			e.printStackTrace();
		}
	}
}









=========================================================================================










import javax.annotation.Resource;

import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.annotation.Configuration;

import com.xxx.xxx.xxxx.xxxx.config.DhMqttConfig;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class MqttConsumerCallBack implements MqttCallback {

	@Resource
	private XxMqttConfig mqtt;

	/**
	 * 客户端断开连接的回调
	 */
	@Override
	public void connectionLost(Throwable throwable) {
		log.info(mqtt.getClientId() + "与服务器断开连接,可重连");
	}

	/**
	 * 消息到达的回调
	 */
	@Override
	public void messageArrived(String topic, MqttMessage message) throws Exception {
		
		// 这里可以处理接收的数据
      log.info("\n----------------------------START---------------------------\n" +
              "接收到订阅消息:\ntopic:" + topic + "\nmessage:" + new String(message.getPayload()) +
              "\n-----------------------------END----------------------------");  
//		log.info(String.format("接收消息主题 : %s", topic));
//		log.info(String.format("接收消息Qos : %d", message.getQos()));
//		log.info(String.format("接收消息内容 : %s", new String(message.getPayload())));
//		log.info(String.format("接收消息retained : %b", message.isRetained()));
	}

	/**
	 * 消息发布成功的回调
	 */
	@Override
	public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
		IMqttAsyncClient client = iMqttDeliveryToken.getClient();
		log.info(client.getClientId() + "接收消息成功!");
	}

}
import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.context.annotation.Configuration;

import com.xxx.xxxx.xxx.xxx.config.DhMqttConfig;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class MqttProviderConfig {

	@Resource
	private XxMqttConfig mqtt;

	/**
	 * 客户端对象
	 */
	private MqttClient client;

	/**
	 * 在bean初始化后连接到服务器
	 */
	@PostConstruct
	private void init() {
		if (mqtt.getOpen()) {//开关控制
			if (connect(mqtt.getHost(), mqtt.getSendId()))
				log.info("提供者:" + mqtt.getSendId() + "成功连接到:" + mqtt.getHost() + "MQTT服务SUCCESS");
		}
	}
	
	/**
	 * 客户端连接服务端
	 */
	private Boolean connect(String host, String sendId) {
		try {
			// 创建MQTT客户端对象
			client = new MqttClient(host, sendId, new MemoryPersistence());
			// 设置回调
			client.setCallback(new MqttProviderCallBack());
			client.connect(setOptions());
			return true;
		} catch (MqttException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 连接设置
	 * 
	 * @return
	 */
	private MqttConnectOptions setOptions() {
		MqttConnectOptions options = new MqttConnectOptions();
		// 是否清空session,设置false表示服务器会保留客户端的连接记录(订阅主题,qos),客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
		// 设置为true表示每次连接服务器都是以新的身份
		options.setCleanSession(true);
		// 设置连接用户名
		options.setUserName(mqtt.getUsername());
		// 设置连接密码
		options.setPassword(mqtt.getPassword().toCharArray());
		// 设置超时时间,单位为秒
		options.setConnectionTimeout(mqtt.getTimeout());
		// 设置心跳时间 单位为秒,表示服务器每隔 1.5*20秒的时间向客户端发送心跳判断客户端是否在线
		options.setKeepAliveInterval(mqtt.getKeepalive());
		options.setAutomaticReconnect(true);
		// 设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息
		options.setWill("willTopic", (mqtt.getSendId() + "与服务器断开连接").getBytes(), 0, false);
		return options;

	}

	/**
	 * 发布
	 * 
	 * @param qos
	 * @param retained
	 * @param topic
	 * @param message
	 */
	public void publish(int qos, boolean retained, String topic, String message) {
		MqttMessage mqttMessage = new MqttMessage();
		mqttMessage.setQos(qos);
		//消息保留机制,若设置为true,mqtt服务器会保留每次发布的消息,若订阅某主题的客户端重启,则会把此主题之前发布的消息重新推送到客户端。
		mqttMessage.setRetained(retained);
		mqttMessage.setPayload(message.getBytes());
		// 主题的目的地,用于发布/订阅信息
		MqttTopic mqttTopic = client.getTopic(topic);
		// 提供一种机制来跟踪消息的传递进度
		// 用于在以非阻塞方式(在后台运行)执行发布是跟踪消息的传递进度
		MqttDeliveryToken token;
		try {
			// 将指定消息发布到主题,但不等待消息传递完成,返回的token可用于跟踪消息的传递状态
			// 一旦此方法干净地返回,消息就已被客户端接受发布,当连接可用,将在后台完成消息传递。
			token = mqttTopic.publish(mqttMessage);
			token.waitForCompletion();
		} catch (MqttException e) {
			e.printStackTrace();
		}
	}

}







===================================================================================





import javax.annotation.Resource;

import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.annotation.Configuration;

import com.xxx.xxx.xxx.xxx.config.DhMqttConfig;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class MqttProviderCallBack implements MqttCallback {

	@Resource
	private DhMqttConfig mqtt;

	/**
	 * 与服务器断开的回调
	 */
	@Override
	public void connectionLost(Throwable cause) {
		log.info(mqtt.getSendId() + "与服务器断开连接");
	}

	/**
	 * 消息到达的回调
	 */
	@Override
	public void messageArrived(String topic, MqttMessage message) throws Exception {
		 log.info("\n----------------------------START---------------------------\n" +
	              "发送的订阅消息:\ntopic:" + topic + "\nmessage:" + new String(message.getPayload()) +
	              "\n-----------------------------END----------------------------");  
	}

	/**
	 * 消息发布成功的回调
	 */
	@Override
	public void deliveryComplete(IMqttDeliveryToken token) {
		IMqttAsyncClient client = token.getClient();
		log.info(client.getClientId() + "发布消息成功!");
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NuoleAQ

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值