简介
最近刚接触到MQTT协议,先是看了下协议相关的文档说明,然后开始写代码实践实现相应的功能。中间走了不少弯路,也看了不少资料,吃了不少苦头,究其原因还是自己对于协议的认识不够准确,把握还是有所欠缺,趁着现在有些小进展,把相关所得记录总结一下,供大家参考。
基本环境搭建
MQTT代理服务器broker是用的Mosca,之前需要先搭建相应NodeJS环境,可以参考其他同类文档说明
MQTT客户端实现用的Eclipse Paho版本,需要引入相应jar包,附上build.gradle中相应依赖关系
compile('org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1')
关键代码
import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import java.util.Date; /** * 发布消息 */ public class Publisher { private MqttClient client; private String host = "tcp://127.0.0.1:1883"; private String userName = "admin"; private String passWord = "password"; private MqttTopic topic; private MqttMessage message; private String myTopic = "test/topic"; public Publisher(){ try{ client = new MqttClient(host, "clientB", new MemoryPersistence()); connect(); }catch (Exception e){ e.printStackTrace(); } // delivery(); } private void delivery(){ try { MqttDeliveryToken token = topic.publish(message); token.waitForCompletion(); System.out.println(token.isComplete() + "========="); } catch (MqttException e) { e.printStackTrace(); } } private void connect() { MqttConnectOptions options = new MqttConnectOptions(); options.setCleanSession(true); options.setUserName(userName); options.setPassword(passWord.toCharArray()); // 设置超时时间 options.setConnectionTimeout(10); // 设置会话心跳时间 options.setKeepAliveInterval(20); try { client.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { System.out.println("connectionLost-----------"); while(!client.isConnected()){ try{ Thread.sleep(1000); client.connect(options); }catch (Exception e){ e.printStackTrace(); } } } @Override public void deliveryComplete(IMqttDeliveryToken token) { System.out.println("deliveryComplete---------"+token.isComplete()); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { System.out.println("messageArrived----------"+topic+"-----" + message.getPayload()); } }); // topic = client.getTopic(myTopic); // message = new MqttMessage(); // message.setQos(1); // message.setRetained(true); // System.out.println(message.isRetained()+"------ratained状态"); // message.setPayload("eeeeeaaaaaawwwwww---".getBytes()); // client.connect(options); client.connect(options); for (int i = 0; i < 10; i++) { try{ String content = new Date() + "MQTT Test body" + i; MqttMessage message = new MqttMessage(content.getBytes()); message.setQos(0); System.out.println(i + " pushed at " + new Date() + " " + content); client.publish(myTopic + "/notice/", message); }catch (Exception e){ e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Publisher client = new Publisher(); } }
import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import java.util.concurrent.ScheduledExecutorService; /** * 订阅消息 */ public class Subscriber { private String host = "tcp://127.0.0.1:1883"; private String userName = "admin"; private String passWord = "password"; private MqttClient client; private String myTopic = "test/topic"; private MqttConnectOptions options; private ScheduledExecutorService scheduler; public Subscriber() { init(); } private void init() { try { client = new MqttClient(host, "clientA", new MemoryPersistence()); options = new MqttConnectOptions(); options.setCleanSession(true); options.setUserName(userName); options.setPassword(passWord.toCharArray()); // 设置超时时间 单位为秒 options.setConnectionTimeout(10); // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制 options.setKeepAliveInterval(20); //设置回调 client.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { //连接丢失后,一般在这里面进行重连 System.out.println("connectionLost----------"); cause.printStackTrace(); while(!client.isConnected()){ try{ Thread.sleep(1000); client.connect(options); client.subscribe(myTopic + "/notice/",0); }catch (Exception e){ e.printStackTrace(); } } } @Override public void deliveryComplete(IMqttDeliveryToken token) { //publish后会执行到这里 System.out.println("deliveryComplete---------" + token.isComplete()); } @Override public void messageArrived(String topicName, MqttMessage message) throws Exception { //subscribe后得到的消息会执行到这里面 System.out.println("messageArrived----------" + message.getPayload()) ; } }); client.connect(options); client.subscribe(myTopic + "/notice/",0); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Subscriber subscriber = new Subscriber(); } }