MQTT相关的介绍和概念网上有很多,现将第一次的实践记录下来。
参考链接:https://www.cnblogs.com/swp520lmg/articles/8707173.html
首先搭建MQTT服务器, 这里用的是mosquitto
百度搜索,下载对应的版本
一路下一步就OK了,最后软件安装完成之后的截图:
网上看到有需要下载OPENSSL的,这里暂时没有遇到那种问题,可以看看readme-windows.txt里面有介绍
mosquitto的简单实用 默认没有登录用户和密码
新建cmd启动代理
mosquitto -d -v
新建cmd订阅test主题
mosquitto_sub -d -v -t test
新建cmd发布test主题 消息内容为hellmqtt
mosquitto_pub -d -t test -m hellomqtt
实际上对于MQTT服务器其实就是代理,链接到服务器上的端没有服务端和客户端的区别,都能自行订阅和发布消息
添加依赖
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
发送消息
public class ServerMqtt {
// tcp://MQTT服务端的安装地址:MQTT端口号[默认1883]
private static String HOST = "tcp://192.168.2.154:1883";
// 定义服务端发布的主题,客户端订阅它
private static String TOPIC = "whjk/01";
// private static String TOPIC = "mqtt-server-pub";
// MQTT的ID
private static String CLIENT_ID = "test";
// 用户名密码,非必须的 默认状态下没有
// private static String USER_NAME = "zhangsan";
// private static String PASSWORD = "12345";
private MqttClient client;
private MqttTopic topic;
private MqttMessage msg;
// private static final MqttServer mqttServer = new MqttServer();
//
// public static MqttServer getInstance() {
// return mqttServer;
// }
//
// private MqttServer() {}
public ServerMqtt() throws MqttException {
// 将MQTT的id设置为以内存保存
client = new MqttClient(HOST, CLIENT_ID, new MemoryPersistence());
connect();
}
private void connect() {
// MQTT连接设置
MqttConnectOptions options = new MqttConnectOptions();
// options.setUserName(USER_NAME);
// options.setPassword(PASSWORD.toCharArray());
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(false);
options.setAutomaticReconnect(true);
// 超时时间
options.setConnectionTimeout(10);
// 会话心跳时间,服务器每隔1.5*20秒发送消息判断客户端是否在线
options.setKeepAliveInterval(20);
try {
// 设置回调
client.setCallback(new PushCallback());
client.connect(options);
topic = client.getTopic(TOPIC);
} catch (Exception e) {
// TODO: handle exception
}
}
// 发布消息
public void publish(MqttTopic topic, MqttMessage msg) throws MqttException {
MqttDeliveryToken token = topic.publish(msg);
token.waitForCompletion();
System.out.println("msg is published complete" + token.isComplete());;
}
public static void main(String[] args) throws MqttException {
ServerMqtt server = new ServerMqtt();
// 定义消息
server.msg = new MqttMessage();
// 消息可靠性 0:最多一次 、1:最少一次 、2:只有一次
server.msg.setQos(1);
server.msg.setRetained(true);
// 设置消息负载
server.msg.setPayload("我是服务端".getBytes());
server.publish(server.topic, server.msg);
System.out.println(server.msg.isRetained() + "----retained状态");
}
}
接受消息
public class ClientMqtt {
private static String HOST = "tcp://192.168.2.154:1883";
private static String TOPIC = "mqtt-server-pub";
private static String CLIENT_ID = "test";
// private static String USER_NAME = "zhangsan";
// private static String PASSWORD = "12345";
private MqttClient client;
private MqttConnectOptions options;
private ScheduledExecutorService scheduledExecutor = null;
private void start() {
try {
client = new MqttClient(HOST, CLIENT_ID, new MemoryPersistence());
options = new MqttConnectOptions();
// options.setUserName(USER_NAME);
// options.setPassword(PASSWORD.toCharArray());
options.setCleanSession(true);
options.setConnectionTimeout(10);
options.setKeepAliveInterval(20);
client.setCallback(new PushCallback());
MqttTopic topic = client.getTopic(TOPIC);
// 如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
options.setWill(topic, "close".getBytes(), 0, true);
client.connect(options);
// 可以同时订阅多个,消息可靠性和订阅主题需一一对应
int[] Qos = {1};
String[] tp = {TOPIC};
client.subscribe(tp, Qos);
} catch (Exception e) {
e.printStackTrace();
}
}
// -----无用
private void reConnect() {
scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
// scheduledExecutor.submit(() -> {
//
//
// });
scheduledExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
if (!client.isConnected()) {
try {
client.connect(options);
} catch (MqttSecurityException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
}
}
}
}, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
}
public void disConnect() {
try {
client.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ClientMqtt client = new ClientMqtt();
client.start();
}
}
回调方法
public class PushCallback implements MqttCallback {
private MqttClient client;
private MqttConnectOptions options;
public PushCallback() {}
public PushCallback(MqttClient client, MqttConnectOptions options) {
this.client = client;
this.options = options;
}
// 方法实现说明 断线重连方法,如果是持久订阅,重连是不需要再次订阅,如果是非持久订阅,重连是需要重新订阅主题 取决于options.setCleanSession(true); true为非持久订阅
@Override
public void connectionLost(Throwable arg0) {
System.out.println("连接断开,可以做重连");
// while (true){
// try {
// System.out.println("连接失败重连");
// client.connect(options);
// //发布相关的订阅
// String[] topic = {"msg.topic","dance.topic"};
// int[] qos = {1,1};
// client.subscribe(topic, qos);
// System.out.println("连接失败重连成功");
// break;
// } catch (MqttException e) {
// e.printStackTrace();
// System.out.println("连接失败重连失败");
// }
// }
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("push complete----" + token.isComplete());
}
@Override
public void messageArrived(String topic, MqttMessage msg) throws Exception {
System.out.println("接收消息主题:" + topic);
System.out.println("接收消息Qos:" + msg.getQos());
System.out.println("接收消息内容:" + new String(msg.getPayload()));
}
}
这样 一个简单的MQTT的小demo就弄好了,感兴趣的可以试试。。。
以此记录自己学习的过程,希望各位大佬指点一二,感谢!!!