本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在上一章介绍了MQTT及EMQX的安装,本篇将从Java的实际角度出发介绍如何实现mqtt消息的订阅和推送
emqx安装
emqx安装可直接参考文章【一】MQTT的服务搭建
Java中创建MQTT实例
maven 依赖
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
创建MQTT客户端
注:此处仅展示创建客户端代码,具体请根据使用环境决定创建方式(例如Spring等容器框架)
// 创建客户端实例
MqttClient client=new MqttClient(MqttConfig.HOST,"server11",new MemoryPersistence());
// 连接配置
MqttConnectOptions options = new MqttConnectOptions();
// 是否清空会话,若不清空会保留上一条主题会话消息
options.setCleanSession(false);
// 用户名和密码,开启auth后认证用
options.setUserName(MqttConfig.USERNAME);
options.setPassword(MqttConfig.PASSWORD.toCharArray());
// 设置超时时间
options.setConnectionTimeout(10);
// 设置会话心跳时间
options.setKeepAliveInterval(20);
// 设置遗言,在断开连接后由MQTT服务自动发布该消息
options.setWill();
client.connect(options);
// 客户端回调,接收消息和发送成功等均在回调里实现
client.setCallback(new PushCallback());
MqttCallback详解
public interface MqttCallback {
// 连接丢失回调,连接断开后在此处处理,例如重连等逻辑
void connectionLost(Throwable var1);
// 收到消息回调,根据topic自行处理消息内容,消息为byte包
void messageArrived(String topic, MqttMessage msg) throws Exception;
// 消息推送成功回调,当消息推送成功后会触发此方法,以此判断消息是否推送成功,
// 推送成功不代表消费者接收,如需消费者接收确认,需要自行实现
void deliveryComplete(IMqttDeliveryToken var1);
}
发布消息
方法一
MqttTopic topic=mqttClient.getTopic("test_topic");
MqttMessage msg=new MqttMessage();
msg.setQos(1);
msg.setPayload(("this is test info from mqtt server\t"+LocalDateTime.now()).getBytes());
msg.setRetained(true);
try {
MqttDeliveryToken token=topic.publish(msg);
token.waitForCompletion();
System.out.println("消息推送成功:"+LocalDateTime.now());
} catch (MqttException e) {
System.err.println("消息推送失败:"+LocalDateTime.now());
e.printStackTrace();
}
方法二
MqttMessage msg=new MqttMessage();
msg.setQos(1);
msg.setPayload(("this is test info from mqtt server\t"+LocalDateTime.now()).getBytes());
msg.setRetained(true);
MqttDeliveryToken token=mqttClient.publish(topic,msg)
token.waitForCompletion();
System.out.println("消息推送成功:"+LocalDateTime.now());
接收消息
实现MqttCallback注册回调
class PushCallback implements MqttCallback {
@Override
public void connectionLost(Throwable throwable) {
System.out.println("连接断开");
}
@Override
public void messageArrived(String s, MqttMessage msg) throws Exception {
System.out.println("消费消息");
System.out.println("主题:"+s);
System.out.println("消息qos:"+msg.getQos());
System.out.println("消息内容:"+new String(msg.getPayload())+"\n");
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("deliveryComplete-----"+token.isComplete());
}
}
// 注册该回调
mqttClient.setCallback(new PushCallback());
注意事项
clientId
mqtt的clientId必须唯一,用户名和密码可以重复使用,但是clientId每个连接必须唯一,否则会出现挤下线的情况。
mqtt端口
mqtt默认端口如下
| 端口 | 协议及作用 |
|---|---|
| 1883 | MQTT protoc port |
| 8883 | MQTT/SSL port |
| 8083 | MQTT/WebSocket port |
| 8080 | HTTP API port |
| 18083 | Dashboard Management Console Port |
| 这里面需要注意的是8080与tomcat默认端口冲突,需要注意下。 |
关于qos
| qos等级 | 说明 |
|---|---|
| 0 | 最多一次的传输 |
| 1 | 至少一次的传输 |
| 2 | 只有一次的传输 |
-
订阅和发布都可以指定qos,但最终qos是他们当中的最小值
-
如果qos为1,publisher发布的消息必须设置setRetained(true),这样才能保存重发。
以上就是在Java中实际使用MQTT的一个简单步骤,当然还有更细节的复杂实现,诸如断开重连,业务消息的消费确认等需要在实际项目中按需自行开发。
如果您觉得本篇文章对您有所帮助,欢迎您订阅点赞留言。
有兴趣的小伙伴可以关注公众号【暴走的怪兽君】,常更新Java干货资讯,免费提供大量教程和工具下载。