1、我是maven项目
首先引入mqtt的jar包、我这里引用的是mqttv3
打开pom文件、加入jar包。
<!-- mqtt -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
2、java代码块
public class Mqtt {
/**
* 上一次失去信号的时间
*/
private static Long lastCutOffSignalTime = null;
/**
* MqttClient 客户端
*/
private static MqttClient client;
/**
* 检查客户端状态
*/
public static void checkMyClientStatus() {
System.out.println("检查客户端状态!");
//服务断开后,客户端依然会保持连接状态,即isConnected为true
if (client == null) {
System.out.println("客户端为null,重新创建客户端!");
client = createClient();
}else if (client.isConnected() == false){
//如果断开时间超过1小时,将重新创建客户端
if (System.currentTimeMillis() - lastCutOffSignalTime > 3600*1000L) {
try {
client.close();
} catch (MqttException e) {
System.out.println("关闭客户端失败!");
}
client = createClient();
}else { //连接
try {
System.out.println("客户端断开将重新连接!");
//连接配置信息
client.reconnect();
} catch (Exception e) {
e.printStackTrace();
System.out.println("客户端重新连接异常:" + e.getMessage());
}
}
}else {
System.out.println("客户端正在连接成功,ID:" + client.getClientId() + ",URI:" +client.getCurrentServerURI());
}
}
/**
* 创建mqtt
* 需要订阅主题时在此方法 订阅主题
* @return
* @throws MqttException
*/
private static MqttClient createClient() {
System.out.println("创建MQTT客户端!");
// 设置mqtt链接地址
String serverURI = "";
// 设置客户端id
String clientId = "";
MqttClient client = null;
//设置回调函数
try {
client = new MqttClient(serverURI, clientId);
client.setCallback(new MyMqttCallback());
//连接配置信息
MqttConnectOptions options = getOptions();
client.connect(options);
boolean isSuccess = client.isConnected();
if (isSuccess) {
// 在此订阅主题,订阅主题的方法
subscribeTopic(client);
System.out.println("MQTT服务启动成功!" +"客户端ID:" + client.getClientId() );
}else {
System.out.println("MQTT服务启动失败!");
}
}catch (MqttException e) {
System.out.println("创建MQTT客户端失败:" + e.getMessage());
return null;
}
return client;
}
/**
* 生成配置对象,用户名,密码等
* @return
*/
public static MqttConnectOptions getOptions() {
MqttConnectOptions options = new MqttConnectOptions();
//设置连接认证的用户名和密码
options.setUserName("");
options.setPassword("".toCharArray());
//若设为false,如果订阅的客户机断线,MQTT服务器将保存客户端会话的主体订阅和ACK位置,重新连接时,将这些消息推送(若客户端长时间不连接,需要设置一个过期值)。默认为true
//设置为true后,即使断开后也不能重新连接
options.setCleanSession(false);
options.setAutomaticReconnect(true);
options.setConnectionTimeout(30);
//设置保持长连接平的频率,单位为秒
options.setKeepAliveInterval(60);
return options;
}
/**
* 订阅主题
*/
private static void subscribeTopic(MqttClient client) {
if (client.isConnected()) {
String subscribeTopic = "toClient";
try {
client.subscribe(subscribeTopic,1);
System.out.println("订阅主题成功," + subscribeTopic);
} catch (MqttException e) {
System.out.println("订阅主题失败," + e.getMessage());
}
}
}
static class MyMqttCallback implements MqttCallbackExtended{
/**
* 连接完成后调用
*/
@Override
public void connectComplete(boolean reconnect, String serverURI) {
//如果是重新连接上的
if(reconnect) {
System.out.println("mqtt重新连接成功!");
subscribeTopic(client);
}
}
/**
* 断开连接后调用
*/
@Override
public void connectionLost(Throwable e) {
System.out.println("mqtt连接断开,:" + e.getMessage());
lastCutOffSignalTime = System.currentTimeMillis();
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
try {
//publish后会执行到这里
if (token.isComplete()) {
System.out.println("主题发布成功");
}else{
System.out.println("主题发布失败");
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
/**
* 接收订阅主题的处理方法
*/
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("接收订阅主题");
String mess = message.getPayload().toString();
System.out.println("订阅主题"+topic);
}
}
/**
* 发布消息
* @param str 需要发送的内容
*/
public static void publish(String str) throws Exception {
// 需要订阅的mqtt主题
String topic = "";
if(client == null){
checkMyClientStatus();
}
MqttTopic mqttTopic = client.getTopic(topic);
MqttMessage message = new MqttMessage();
// 0,最多一次送达。也就是发出去就fire掉,没有后面的事情了。
// 1,至少一次送达。发出去之后必须等待ack,没有ack,就要找时机重发
// 2,准确一次送达。消息id将拥有一个简单的生命周期。
message.setQos(2);
message.setPayload(str.getBytes());
MqttDeliveryToken token = mqttTopic.publish(message);
// 阻止当前线程,直到消息这是完成传递的令牌。
token.waitForCompletion();
}
}