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

MQTT PAHO-用于确认成功消息传递的MessageId,mqtt,paho,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.writeValueAs

我用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中获得消息ID。我使用它在数据库中保存和标识消息

步骤3-等待调用deliveryComplete回调:

这为我提供了相同的IMqttDeliveryToken,在这里我可以再次获得messageId

@Override
   public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
      // delete the database entry via messageId from database
}
问题是第三步可能比第二步快。因此,在将我的条目保存到数据库之前调用回调。在发送消息之前,我需要知道messageId,以便在调用回调之前保存消息。我无法自行生成messageId并将其设置为:

mqttMessage.setId(555);
MQTT生成自己的messageId。所以我的问题是:

  • 是否可以设置自己的messageId
  • 我可以在发布之前获取mqtt客户机生成的messageId吗

  • 不要使用Paho库生成的消息的MQTT id,因为它

  • 对于您的需求来说,交付太晚了
  • 如果发送大量消息,可能会重复
  • 相反,在以下情况下,使用您自己的id(甚至可能由数据库自动生成),并将其作为用户定义的上下文对象传递:

    稍后,您可以在发布回调方法中检索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。我真的需要一个新的IMqttActionListener实例吗?我刚刚找到了发布函数,我必须在其中设置一个IMqttActionListener作为参数。我询问的原因是,如果消息成功发送到mqtt代理,也会从我的客户端调用我的set callback deliveryComplete。
    mpPublishCallback
    的方法将帮助您查明发布特定消息是否失败(需要重试)或者成功我用QoS1管理它并正确处理异常。因此,我不需要发送标识信息的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();
        }
    };