项目场景:
因为公司架构迁移,之前是采用Aliiot的通信方式便弃用了,现准备使用mqtt通信的方式交互
环境准备
1、emqx服务部署
emqx服务下载地址:https://www.emqx.com/en/downloads/broker
选择对应需要的版本下载,安装到服务器或本地都可,修改配置文件。详细配置可参考官方文档
https://www.emqx.io/docs/zh/v5.0/admin/cfg.html
2、开发环境搭建
如果是测试你可以在spring.io下载一个demo进行,也可以直接结合到自己的项目中
https://start.spring.io/
如果已经存在项目,直接在pom文件内导入所需依赖
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
配置添加
mqtt:
url: mqtt地址
qos: 0
user: user #在conf中可配置
pass: password #在conf中可配置
clientId: uuv-server #表示服务id
topic: /+/+/user/ClientToServer #订阅的topic
1、编写配置类
@Value("${mqtt.url}")
String url;
@Value("${mqtt.qos:0}")
Integer qos;
@Value("${mqtt.user}")
String user;
@Value("${mqtt.pass}")
String pass;
@Value("${mqtt.clientId}")
String clientId;
@Value("${mqtt.topic}")
String topic;
MqttClient client;
@Autowired
List<MqttMessageListener> listeners;
ExecutorService executor = Executors.newFixedThreadPool(10,new NamedThreadFactory("MQTT-WORKER-",true));
@PostConstruct
public void init() throws MqttException {
MqttDefaultFilePersistence persistence =
new MqttDefaultFilePersistence(System.getProperty("user.dir")+"/logs");
client = new MqttClient(url, clientId, persistence);
MqttConnectOptions opts = new MqttConnectOptions();
opts.setMqttVersion(MQTT_VERSION_DEFAULT);
// 设置是否自动重连
opts.setAutomaticReconnect(true);
if(StringUtils.isNotBlank(user)){
opts.setUserName(user);
opts.setPassword(pass.toCharArray());
}
opts.setKeepAliveInterval(80);
client.connect(opts);
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
log.info("===connectionLost回调执行===", cause);
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
log.info("===messageArrived回调执行===,topic:{},message:{}", topic, message);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
log.info("===deliveryComplete回调执行===,token:{}", token);
}
});
for(String t : StringUtils.split(topic,",")){
client.subscribe(t, qos, (tc, message) -> {
String receive = new String(message.getPayload(), StandardCharsets.UTF_8);
log.debug("Topic:{} receive:{}",tc,receive);
JSONObject obj = JSON.parseObject(receive);
clientToServer(obj);
});
}
}
private void clientToServer(JSONObject msg) {
listeners.forEach(l -> executor.submit(() -> l.onMessage(msg)));
}
public void publish(String product, String key, Object request){
String topic = "/" + product + "/" + key+ "/user/ServerToClient";
publish(topic, request);
}
@SneakyThrows
private void publish(String topic, Object msg){
MqttMessage message = new MqttMessage(JSON.toJSONString(msg).getBytes(StandardCharsets.UTF_8));
message.setQos(qos);
log.info("ServerToClient,topic:{},message:{}", topic, message);
try {
client.publish(topic, message);
} catch (MqttException e) {
log.error("push mqtt fail:{}", e.getMessage(), e);
throw new RuntimeException(e);
}
}
2、使用
将上述配置类注入,在对应的业务处调用即可
mqttClient.publish(peoduct,key,jsonObject);
3、联调测试
1、首次启动emqx平台,在右侧齿轮处修改语言
然后启动你的服务端,在emqx平台客户端处可以看到连接
左侧订阅管理也可以看到服务端订阅的主题和topic
这样就可以写个小demo测试啦