MQTT的上行与下行是异步的,如果需要将其作为一个原子操作
可以使用countDownLatch,参考以下写法
/**
* 发送Mqtt消息并等待响应
*
* @param publishTopic 发送主题
* @param subscribeTopic 订阅主题
* @return 发送结果
*/
public static R<Object> publishAndSubscribe(MqttClient mqttClient, MqttMsgDTO dto,
String publishTopic, String subscribeTopic) throws Exception {
String msgId = ObjectId.next();
MqttMessage mqttMessage = build(dto, msgId);
CountDownLatch countDownLatch = new CountDownLatch(1);
R<Object> res = new R<>();
mqttClient.subscribe(subscribeTopic, (topic, message) -> {
String json = new String(message.getPayload());
MqttResult mqttResult = JSONUtil.toBean(json, MqttResult.class);
if (mqttResult.getId() != null && msgId.equals(mqttResult.getId())) {
res.setCode(mqttResult.getCode());
res.setData(mqttResult.getData());
if (mqttResult.getCode() == 200) {
res.setMsg("下发成功");
res.setSuccess(true);
} else {
res.setMsg("下发失败");
res.setSuccess(false);
}
countDownLatch.countDown();
}
});
//发布消息
mqttClient.publish(publishTopic, mqttMessage);
//最多等待2秒的响应
countDownLatch.await(20, TimeUnit.SECONDS);
if (0 == res.getCode()) {
res.setMsg("下发响应超时");
res.setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
return res;
}