MQTT PAHO - MessageId для подтверждения успешной доставки сообщения - PullRequest
0 голосов
/ 26 февраля 2019

Я разрабатываю приложение с org.eclipse.paho.client.mqttv3 версии 1.2.0 на Java.Для идентификации сообщения, которое отправляется брокеру mqtt через идентификатор сообщения iMqttDeliveryToken.

Шаг 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
}

Проблема в том, что Шаг 3 может быть быстрее, чем Шаг 2.Поэтому обратный вызов вызывается до того, как моя запись будет сохранена в базе данных.Мне нужно знать идентификатор сообщения перед отправкой сообщения, чтобы сохранить его, прежде чем можно будет вызвать обратный вызов.Я не могу сгенерировать messageId самостоятельно и установить его так:

mqttMessage.setId(555);

MQTT генерирует собственный messageId.Итак, мои вопросы:

  1. Можно ли установить собственный идентификатор сообщения?
  2. Можно ли получить идентификатор сообщения, сгенерированный клиентом mqtt до публикации?

1 Ответ

0 голосов
/ 27 февраля 2019

Не используйте идентификатор MQTT сообщения, сгенерированного библиотекой Paho - потому что оно

  1. доставлено слишком поздно для ваших нужд
  2. может повториться, если вы отправите большое количествоmessages.

Вместо этого используйте свой собственный идентификатор (может быть, даже автоматически сгенерированный вашей базой данных) и передайте его как определенный пользователем объект контекста при публикации :

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);

Позже вы можете получить идентификатор в методах обратного вызова публикации:

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

...