我使用 Java 中的 org.eclipse.paho.client.mqttv3 版本 1.2.0 开发了一个应用程序。通过 iMqttDeliveryToken 的 messageID 来标识发送到 mqtt 代理的消息。
第 1 步 - 发布消息:
ObjectMapper objectMapper = new ObjectMapper();
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setPayload(objectMapper.writeValueAsString(myObject).getBytes());
mqttMessage.setQos(1);
IMqttDeliveryToken iMqttDeliveryToken = this.client.publish("/myTopic", mqttMessage);
第 2 步 - 将消息保存到数据库中:
从 IMqttDeliveryToken 中我得到了 messageID。我用它来保存和识别数据库中的消息。
第3步 - 等待调用deliveryComplete回调:
这为我提供了相同的 IMqttDeliveryToken,我可以在其中再次获取 messageId。
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
// delete the database entry via messageId from database
}
问题是 Step3 可能比 Step2 更快。因此,在我的条目保存到数据库之前,会调用回调。我需要在发送消息之前知道 messageId 以保存它,然后才能调用回调。我无法自己生成 messageId 并将其设置如下:
mqttMessage.setId(555);
MQTT 生成自己的 messageId。所以我的问题是:
- 是否可以设置自己的messageId?
- 发布前能否获取mqtt客户端生成的messageId?
最佳答案
不要使用 Paho 库生成的消息的 MQTT ID - 因为它
- 交付时间太晚,无法满足您的需求
- 如果您发送大量消息,可能会重复。
相反,当 publishing 时,使用您自己的 ID(甚至可能由数据库自动生成)并将其作为用户定义的上下文对象传递。 :
Long databaseId = 42;
ObjectMapper objectMapper = new ObjectMapper();
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setPayload(objectMapper.writeValueAsString(myObject).getBytes());
mqttMessage.setQos(1);
this.client.publish("/myTopic", mqttMessage, databaseId, mPublishCallback);
稍后您可以在发布回调方法中检索 ID:
private final IMqttActionListener mPublishCallback = new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken publishToken) {
Long databaseId = (Long) publishToken.getUserContext();
}
@Override
public void onFailure(IMqttToken publishToken, Throwable ex) {
Long databaseId = (Long) publishToken.getUserContext();
}
};
另外,您使用同步客户端吗?我更喜欢使用IMqttAsyncClient
关于MQTT PAHO - 用于确认成功消息传递的 MessageId,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54883984/