请先关联依赖 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
(一).封装MQTTv3的使用
class TestMqttV3{ public static void main(String[] args){ //设置配置信息 MqttV3 mqttV3 = new MqttV3.Builder() .setUserName("iot") .setPassword("iot123!") .setPublishTopic("st/message") .setSubscribeTopic("st/message") .setClientId("clientId") .setCleanSession(true) // .setIReceiveActionListener(new IReceiveActionListener(){...}) //设置接收消息的监听 //.setIMqttStatusListener(new IMqttStatusListener(){...}) //设置链接状态的监听 .build(); //进行链接 mqttV3.connect("server url"); //发布消息 mqttV3.publishMsg("publish msg", new IPublishActionListener() { @Override public void onConnectionLost() { } @Override public void onSuccess(IMqttToken asyncActionToken) { } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { } }); //断开链接 mqttV3.destory(); } }
(二).封装MQTTv3的源码
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions; import org.eclipse.paho.client.mqttv3.IMqttActionListener; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.IMqttMessageListener; import org.eclipse.paho.client.mqttv3.IMqttToken; import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import java.util.List; import javax.net.SocketFactory; /** * Created by 刘强lq on 2018/3/14. */ public class MqttV3 { //尽力而为。消息发送者会想尽办法发送消息,但是遇到意外并不会重试。 public static final int QOS_UNRELIABLE = 0; //至少一次。消息接收者如果没有知会或者知会本身丢失,消息发送者会再次发送以保证消息接收者至少会收到一次,当然可能造成重复消息。 public static final int QOS_REPEAT = 1; //恰好一次。保证这种语义肯待会减少并发或者增加延时,不过丢失或者重复消息是不可接受的时候,级别2是最合适的。 public static final int QOS_JUST = 2; //mqtt设置的参数实例 private final MqttConnectOptions mMqttConnectOptions; //mqtt实例 private MqttAsyncClient mqttClient; private MqttV3(Builder builder) { this.mqttVersion = builder.mqttVersion; this.userName = builder.userName; this.password = builder.password; this.publishTopic = builder.publishTopic; this.subscribeTopic = builder.subscribeTopic; this.subscribeTopics = builder.subscribeTopics; this.subscribeQos = builder.subscribeQos; this.publishQos = builder.publishQos; this.clientId = builder.clientId; this.automaticReconnect = builder.automaticReconnect; this.cleanSession = builder.cleanSession; this.connectionTimeout = builder.connectionTimeout; this.keepAliveInterval = builder.keepAliveInterval; this.publishMsgRetained = builder.publishMsgRetained; this.userContext = builder.userContext; this.socketFactory = builder.socketFactory; this.mIReceiveActionListener = builder.mIReceiveActionListener; this.mIMqttStatusListener = builder.mIMqttStatusListener; mMqttConnectOptions = new MqttConnectOptions(); mMqttConnectOptions.setAutomaticReconnect(this.automaticReconnect); mMqttConnectOptions.setCleanSession(this.cleanSession); mMqttConnectOptions.setUserName(this.userName); mMqttConnectOptions.setPassword(this.password.toCharArray()); mMqttConnectOptions.setMqttVersion(this.mqttVersion); mMqttConnectOptions.setKeepAliveInterval(this.keepAliveInterval); mMqttConnectOptions.setConnectionTimeout(this.connectionTimeout); if (this.socketFactory != null) { mMqttConnectOptions.setSocketFactory(this.socketFactory); } } /** * 进行链接 * * @param serverURI 链接的地址 */ public void connect(String serverURI) { try { mqttClient = new MqttAsyncClient(serverURI, this.clientId, new MemoryPersistence()); //设置回调 mqttClient.setCallback(new MqttCallbackExtended() { @Override public void connectComplete(boolean reconnect, String serverURI) { // if (reconnect) { //// System.out.println("重连到: " + serverURI); // } else { //// System.out.println("链接到: " + serverURI); // } if (mIMqttStatusListener !=null){ mIMqttStatusListener.connectComplete(reconnect, serverURI); } } @Override public void connectionLost(Throwable cause) { //连接丢失后,一般在这里面进行重连 // subscribe(); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { // subscribe后得到的消息会执行到这里面 } @Override public void deliveryComplete(IMqttDeliveryToken token) { // publish后会执行到这里 } }); mqttClient.connect(mMqttConnectOptions, this.userContext, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { //System.out.println("链接成功"); if (mIMqttStatusListener !=null){ mIMqttStatusListener.connectSuccess(asyncActionToken); } DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions(); disconnectedBufferOptions.setBufferEnabled(true); disconnectedBufferOptions.setBufferSize(100); disconnectedBufferOptions.setPersistBuffer(false); disconnectedBufferOptions.setDeleteOldestMessages(false); mqttClient.setBufferOpts(disconnectedBufferOptions); subscribe(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { // System.out.println("链接失败"); if (mIMqttStatusListener !=null){ mIMqttStatusListener.connectFail(asyncActionToken,exception); } } }); } catch (MqttException e) { e.printStackTrace(); } } /** * 订阅 */ private void subscribe() { try { if (MqttV3.this.subscribeTopic != null) { //订阅单个Topic mqttClient.subscribe(MqttV3.this.subscribeTopic, this.subscribeQos, this.userContext, iMqttActionListener, iMqttMessageListener); } else {//订阅多个Topic int size = MqttV3.this.subscribeTopics.size(); String[] subscribeTopics = MqttV3.this.subscribeTopics.toArray(new String[size]); int[] qos = new int[size]; IMqttMessageListener[] messageListeners = new IMqttMessageListener[size]; for (int i = 0; i < size; i++) { qos[i] = QOS_JUST; messageListeners[i] = iMqttMessageListener; } mqttClient.subscribe(subscribeTopics, qos, this.userContext, iMqttActionListener, messageListeners); } } catch (MqttException e) { e.printStackTrace(); } } /** * 订阅后的消息回调--真正的接收消息 */ private IMqttMessageListener iMqttMessageListener = new IMqttMessageListener() { @Override public void messageArrived(String s, MqttMessage mqttMessage) throws Exception { if (MqttV3.this.mIReceiveActionListener != null) { MqttV3.this.mIReceiveActionListener.receiveMsg(mqttMessage.toString()); } } }; /** * 订阅的动作后的回调 */ private IMqttActionListener iMqttActionListener = new IMqttActionListener() { @Override public void onSuccess(IMqttToken iMqttToken) { //System.out.println("订阅成功"); if (mIMqttStatusListener !=null){ mIMqttStatusListener.subscribeSuccess(iMqttToken); } } @Override public void onFailure(IMqttToken iMqttToken, Throwable throwable) { //System.out.println("订阅失败"); if (mIMqttStatusListener !=null){ mIMqttStatusListener.subscribeFail(iMqttToken,throwable); } } }; /** * 发布消息 * * @param msg 消息 */ public void publishMsg(String msg, IPublishActionListener iPublishActionListener) { try { //retained:设置发送完消息后是否还保留 与cleanSession差不多 if (mqttClient.isConnected()) { mqttClient.publish(publishTopic, msg.getBytes(), QOS_JUST, this.publishMsgRetained, this.userContext, iPublishActionListener); } else { iPublishActionListener.onConnectionLost(); } } catch (MqttException e) { e.printStackTrace(); } } private int mqttVersion; private String clientId; private String publishTopic; private int subscribeQos; private String subscribeTopic; private ListsubscribeTopics; private int publishQos; private String userName; private String password; private int connectionTimeout; private int keepAliveInterval; private boolean automaticReconnect; private boolean cleanSession; private boolean publishMsgRetained; private Object userContext = null; private SocketFactory socketFactory; private IReceiveActionListener mIReceiveActionListener; private IMqttStatusListener mIMqttStatusListener; public String getClientId() { return clientId; } public int getSubscribeQos() { return subscribeQos; } public String getSubscribeTopic() { return subscribeTopic; } public int getPublishQos() { return publishQos; } public String getPublishTopic() { return publishTopic; } public boolean isPublishMsgRetained() { return publishMsgRetained; } public Object getUserContext() { return userContext; } public List getSubscribeTopics() { return subscribeTopics; } public MqttConnectOptions getmMqttConnectOptions() { return mMqttConnectOptions; } public SocketFactory getSocketFactory() { return socketFactory; } public MqttAsyncClient getMqttClient() { return mqttClient; } public static class Builder { private String publishTopic; private String subscribeTopic; private List subscribeTopics; private int publishQos = QOS_JUST; private int subscribeQos = QOS_JUST; private String userName = "admin"; private String password = "admin"; private int mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1; private String clientId = MqttAsyncClient.generateClientId(); private int connectionTimeout = MqttConnectOptions.CONNECTION_TIMEOUT_DEFAULT / 3; private int keepAliveInterval = MqttConnectOptions.KEEP_ALIVE_INTERVAL_DEFAULT / 3; private boolean automaticReconnect = true; private boolean cleanSession = false; private boolean publishMsgRetained = true; private Object userContext = null; private SocketFactory socketFactory; private IReceiveActionListener mIReceiveActionListener; private IMqttStatusListener mIMqttStatusListener; /** * @param automaticReconnect 设置自动重连:当断开链接时候 */ public Builder setAutomaticReconnect(boolean automaticReconnect) { this.automaticReconnect = automaticReconnect; return this; } /** * 如果cleanSession为true 那么只会接收到最后一条数据(用户名相同,客户端id不同的情况下) * 否则就会接收到以往所有的历史数据 * * @param cleanSession 清空会话:当发送完消息后,清空mqtt服务器端的发送的会话(消息) */ public Builder setCleanSession(boolean cleanSession) { this.cleanSession = cleanSession; return this; } /** * @param publishMsgRetained 推送消息后是否保留 */ public Builder setPublishMsgRetained(boolean publishMsgRetained) { this.publishMsgRetained = publishMsgRetained; return this; } /** * 设置mqtt对应的版本号 默认是1.1版本 * * @param mqttVersion mqtt对应的版本号 */ public Builder setMqttVersion(int mqttVersion) { this.mqttVersion = mqttVersion; return this; } /** * @param publishTopic 推送消息的topic */ public Builder setPublishTopic(String publishTopic) { this.publishTopic = publishTopic; return this; } /** * @param subscribeTopic 订阅消息的topic */ public Builder setSubscribeTopic(String subscribeTopic) { this.subscribeTopic = subscribeTopic; return this; } /** * @param subscribeTopics 订阅多个不同发送消息的topic */ public Builder setSubscribeTopics(List subscribeTopics) { this.subscribeTopics = subscribeTopics; return this; } /** * @param publishQos 发布的qos */ public Builder setPublishQos(int publishQos) { this.publishQos = publishQos; return this; } /** * @param subscribeQos 设置订阅的qos * @return */ public Builder setSubscribeQos(int subscribeQos) { this.subscribeQos = subscribeQos; return this; } /** * @param userName 设置用户名 */ public Builder setUserName(String userName) { this.userName = userName; return this; } /** * @param password 设置密码 */ public Builder setPassword(String password) { this.password = password; return this; } /** * 设置客户端id 唯一 * * @param clientId 客户端唯一id * @return */ public Builder setClientId(String clientId) { this.clientId = clientId; return this; } /** * @param connectionTimeout 链接超时的时间 */ public Builder setConnectionTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } /** * @param keepAliveInterval 保持长链接的时间 */ public Builder setKeepAliveInterval(int keepAliveInterval) { this.keepAliveInterval = keepAliveInterval; return this; } /** * @param userContext 用户上下文 :null */ public Builder setUserContext(Object userContext) { this.userContext = userContext; return this; } /** * 设置ssl的SocketFactory * * @param socketFactory sslContext.getSocketFactory() */ public Builder setSocketFactory(SocketFactory socketFactory) { this.socketFactory = socketFactory; return this; } /** * 设置接收消息的接口 * * @param IReceiveActionListener * @return */ public Builder setIReceiveActionListener(IReceiveActionListener IReceiveActionListener) { mIReceiveActionListener = IReceiveActionListener; return this; } public Builder setIMqttStatusListener(IMqttStatusListener IMqttStatusListener) { mIMqttStatusListener = IMqttStatusListener; return this; } public MqttV3 build() { return new MqttV3(this); } } /** * 断开链接 */ public void destory() { try { if (mqttClient != null) { mqttClient.disconnect(); mqttClient.close(); } } catch (MqttException e) { e.printStackTrace(); } } }
(三)接口类
1.IMqttStatusListener接口
/** * Created by 刘强lq on 2018/3/14. * * mqtt的状态监听 */ public interface IMqttStatusListener { /** * 链接成功 * @param asyncActionToken */ void connectSuccess(IMqttToken asyncActionToken); /** * 链接失败 * @param asyncActionToken * @param exception */ void connectFail(IMqttToken asyncActionToken, Throwable exception); /** * 订阅成功 * @param iMqttToken */ void subscribeSuccess(IMqttToken iMqttToken); /** * 订阅失败 * @param iMqttToken * @param throwable */ void subscribeFail(IMqttToken iMqttToken, Throwable throwable); /** * 链接完成 * @param reconnect 链接完成后的链接状态 可能会失去链接 * @param serverURI 链接服务器地址 */ void connectComplete(boolean reconnect, String serverURI); }
2.IMqttActionListener接口
import org.eclipse.paho.client.mqttv3.IMqttActionListener; public interface IPublishActionListener extends IMqttActionListener { /** * 链接丢失 */ void onConnectionLost(); }
3.IMqttReceiveActionListener接口
/** * Created by 刘强lq on 2018/3/14. * * 接收的消息 */ public interface IReceiveActionListener { void receiveMsg(String msg); }