- 记录一下我实习的第一个任务,学习MQTT协议
- 首先呢得了解MQTT是什么,这里推荐一个我学习MQTT的中文文档
- MQTT协议的基于TCP/IP协议的一个物联网协议,有几个概念必须要弄懂得主题(topic)、订阅(subscribe)、发布(publish)、消息质量(QOS)、代理服务器(broke),先查看文档了解MQTT协议
代理服务器EMQ
这里使用的是EMQ作为服务器
- 下载好EMQ的服务器,EMQ是基于MQTT的代理服务器
- cmd命令进入到安装目录下的bin目录
emqx start
命令启动- localhost:18083 进入登入页面,默认用户名:admin,密码:public
- 红色框出来的就是客户端访问的地址
java实现连接EMQ的代理服务器,主题的订阅、退订,消息的发布、接收
- 首先要先导入jar包,或者是在maven工程中添加依赖
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
- MqttClient.class是一个我自己封装好的一个工具类
package com.gxuwz.mqtt.demo01;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
/**
* Mqtt客户端类
* @author Mr.Liu
* @date 2021/3/31 17:58
*/
public class MyMqttClient {
/** mqtt客户端对象 */
private MqttConnectOptions mqttConnectOptions;
/** MQTT连接对象 对连接进行设置 */
private MqttClient mqttClient;
private MemoryPersistence memoryPersistence;
/** 定义需要的属性变量 */
private String serviceUrl;
private String userName;
private String password;
private String clientId;
/**
* 定义构造函数
* @param serviceUrl
* @param userName
* @param password
*/
public MyMqttClient(String serviceUrl, String userName, String password, String clientId) {
this.serviceUrl = serviceUrl;
this.userName = userName;
this.password = password;
this.clientId = clientId;
}
/**
* 类初始化,建立mqttClient连接
*/
public void init(){
//初始化连接对象
mqttConnectOptions = new MqttConnectOptions();
//初始化mqttClient
if (mqttConnectOptions != null){
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
mqttConnectOptions.setCleanSession(true);
//设置超时时间 单位为秒
mqttConnectOptions.setConnectionTimeout(30);
mqttConnectOptions.setUserName(userName);
mqttConnectOptions.setPassword(password.toCharArray());
//设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
mqttConnectOptions.setKeepAliveInterval(45);
memoryPersistence = new MemoryPersistence();
if (mqttConnectOptions != null && clientId != null){
try {
mqttClient = new MqttClient(serviceUrl, clientId, memoryPersistence);
} catch (MqttException e) {
e.printStackTrace();
}
}else {
System.out.println("mqttConnectOptions == null || clientId == null");
}
}else {
System.out.println("mqttConnectOptions == null");
}
System.out.println("MqttClient是否连接?"+mqttClient.isConnected());
if (mqttClient != null){
//创建回调函数对象,用来接收已经订阅的消息
mqttClient.setCallback(new MqttReceiveCallback());
System.out.println("创建连接......");
try {
mqttClient.connect(mqttConnectOptions);
} catch (MqttException e) {
e.printStackTrace();
}
}else {
System.out.println("mqttClient对象为空,连接失败...");
}
System.out.println("mqttClient是否连接?"+mqttClient.isConnected());
}
/**
* 订阅主题
* @param topic 主题
* @param qos 消息质量
*/
public void subscribeTopic(String topic, int qos){
if (mqttClient != null && mqttClient.isConnected() && topic != null){
try {
mqttClient.subscribe(topic, qos);
} catch (MqttException e) {
e.printStackTrace();
}
}else {
System.out.println("订阅主题失败!mqttClient == null || mqttClient.isConnected() == false");
}
}
/**
* 取消订阅主题
* @param topic 主题名称
*/
public void cleanTopic(String topic){
if (mqttClient != null && mqttClient.isConnected()){
try {
mqttClient.unsubscribe(topic);
} catch (MqttException e) {
e.printStackTrace();
}
}else {
System.out.println("取消订阅失败!");
}
}
/**
* 发布消息
* @param publishTopic 发布消息的主题名称
* @param message 消息内容
* @param qos 消息质量
*/
public void publishMessage(String publishTopic, String message, int qos){
// 判断是否连接
if (mqttClient != null && mqttClient.isConnected()){
System.out.println("发布消息.......");
System.out.println("发布消息人的clientId:"+mqttClient.getClientId());
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setQos(qos);
mqttMessage.setPayload(message.getBytes());
MqttTopic mqttTopic = mqttClient.getTopic(publishTopic);
if (mqttTopic != null){
try {
MqttDeliveryToken publish = mqttTopic.publish(mqttMessage);
if (!publish.isComplete()){
System.out.println("消息发布成功!");
}
} catch (MqttException e) {
e.printStackTrace();
}
}else {
System.out.println("mqttTopic == null");
}
}else {
System.out.println("mqttClient == null || mqttClient.isConnected() == false");
}
}
}
- 用MQTT协议来连接服务器,需要到一个消息的回调,用来接收到已经订阅主题的发布的消息
package com.gxuwz.mqtt.demo01;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* Mqtt连接回调函数 ,用来接收已经订阅的消息
* @author Mr.Liu
* @date 2021/4/1 9:36
*/
public class MqttReceiveCallback implements MqttCallback {
@Override
public void connectionLost(Throwable throwable) {
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("Client 接收消息主题 : " + topic);
System.out.println("Client 接收消息Qos : " + message.getQos());
System.out.println("Client 接收消息内容 : " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
}
- 接下来是测试主类
/**
* 测试类
* @author Mr.Liu
* @date 2021/4/1 9:45
*/
public class DemoTest01 {
public static void main(String[] args) {
String serviceUrl = "tcp://127.0.0.1:1883";
String userName = "Mr.Liu";
String password = "liujunbao789";
String clientId = "Admin_Liu";
// 创建对象
MyMqttClient mqttClient = new MyMqttClient(serviceUrl, userName, password, clientId);
// mqttClient类初始化
mqttClient.init();
// 订阅主题
mqttClient.subscribeTopic("/test",0);
// 发布消息
mqttClient.publishMessage("/test01", "你好呀,我是小白", 1);
// 取消订阅
mqttClient.cleanTopic("/test");
}
以上就是用java使用MQTT来实现的发布、接收消息,订阅、退订主题。
我在学习过程中也参考了这位大佬的博客添加链接描述