MQTT PAHO-MessageId,用于确认成功传递消息

时间:2019-02-26 11:00:15

标签: mqtt paho

我在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。所以我的问题:

  1. 是否可以设置自己的messageId?
  2. 我可以在发布之前获取mqtt客户端生成的messageId吗?

1 个答案:

答案 0 :(得分:2)

请勿使用Paho库生成的消息的MQTT ID-因为它

  1. 交货太迟无法满足您的需求
  2. 如果您发送大量邮件,可能会重复出现。

相反,请使用您自己的ID(甚至可能由数据库自动生成),并在publishing时将其作为用户定义的上下文对象传递:

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