一、MQTT 是基于发布(Publish)/订阅(Subscribe) 模式来进行通信及数据交换的。
搭建测试地址:免费下载、试用 EMQ 产品
二、使用
1.maven依赖
<dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-mqtt</artifactId> <version>6.0.6</version> </dependency>
2.配置类
public class MQTTConfig { //连接地址 private static String url; //账号 private static String username; //密码 private static String password; //回调地址 private static String back = "";}
3. 连接工具
public class MQTTConnect { //连接服务器默认客户端ID private final String clientId = "AS" + DateUtils.dateMonth(); private MqttClient mqttClient; //@Autowired //private RedisCache redisCache; 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(MQTTConfig.getUrl(), clientId, new MemoryPersistence()); MqttConnectOptions options = new MqttConnectOptions(); options.setUserName(userName); options.setPassword(passWord.toCharArray()); options.setConnectionTimeout(10); options.setCleanSession(false); 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(); 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); } 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); }}
4. 发布/订阅回调返回
@Component 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) { } /** * subscribe订阅后得到的消息会执行到这里 */ @Override public void messageArrived(String topic, MqttMessage message) { log.info("收到来自 " + topic + " 的消息:{}", newString(message.getPayload())); } }
5.项目启动自动订阅
@Component public class MQTTBack implements CommandLineRunner { private final String clientId = DateUtils.getYear(); private final Logger log = LoggerFactory.getLogger(MQTTBack.class); @Override public void run(String... args) throws Exception { try { MemoryPersistence memoryPersistence = new MemoryPersistence(); MqttConnectOptions options = new MqttConnectOptions(); //设置用户名密码 options.setUserName(MQTTConfig.getUsername()); options.setPassword(MQTTConfig.getPassword().toCharArray()); options.setCleanSession(true); //连接超时时间 options.setConnectionTimeout(10); //设置会话心跳时间 options.setKeepAliveInterval(30); MqttClient client = new MqttClient(MQTTConfig.getUrl(), clientId, memoryPersistence); client.setCallback(new Callback()); client.connect(options); client.subscribe(MQTTConfig.getBack()); } catch (Exception e) { log.info("上报数据启动出错:{}", e.getMessage()); } } //重新连接 public void reconnect() throws MqttException { MqttClient client = new MqttClient(MQTTConfig.getUrl(), clientId, new MemoryPersistence()); client.connect(); if (client.isConnected()) { System.out.println("Connected to MQTT server"); } else { System.out.println("Not connected to MQTT server"); } } }