Повторные подключения и тайм-ауты клиентов AWS JAVA IoT

Я использую правила Интернета вещей для темы ПОДКЛЮЧЕН / ОТКЛЮЧЕН (см. здесь). Поэтому я хочу получать электронную почту, когда устройство подключено или отключено. На моем устройстве я запускаю следующий код при запуске (только при запуске):

iotClient = new AWSIotMqttClient(Configuration.IOT_CLIENT_ENDPOINT,
                    deviceId,
                    keyStore,
                    keystorePass);
            
iotClient.setKeepAliveInterval(1200000); //20 minutes (maximum)
iotClient.connect();

Но у меня очень странное поведение. У меня 3 устройства, и на каждом из них я получаю трассировку стека, но по разным причинам:

[pool-8-thread-1] com.amazonaws.services.iot.client.core.AwsIotConnection.onConnectionSuccess Connection successfully established
[pool-8-thread-1] com.amazonaws.services.iot.client.core.AbstractAwsIotClient.onConnectionSuccess Client connection active: <client ID>
[pool-8-thread-1] com.amazonaws.services.iot.client.core.AwsIotConnection.onConnectionFailure Connection temporarily lost
[pool-8-thread-1] com.amazonaws.services.iot.client.core.AbstractAwsIotClient.onConnectionFailure Client connection lost: <client ID>
[pool-8-thread-1] com.amazonaws.services.iot.client.core.AwsIotConnection$1.run Connection is being retried
[pool-8-thread-1] com.amazonaws.services.iot.client.core.AwsIotConnection.onConnectionSuccess Connection successfully established
[pool-8-thread-1] com.amazonaws.services.iot.client.core.AbstractAwsIotClient.onConnectionSuccess Client connection active: <client ID>

Иногда я получаю эту трассировку стека из-за причины отключения DUPLICATE_CLIENTID или иногда из-за причины отключения MQTT_KEEP_ALIVE_TIMEOUT (MQTT_KEEP_ALIVE_TIMEOUT происходит каждые 30-35 минут, DUPLICATE_CLIENTID происходит каждые 10 минут)

Итак, я не понимаю, почему мне нужно иметь дело с DUPLICATE_CLIENTID, если у каждого клиента есть уникальный идентификатор, и с MQTT_KEEP_ALIVE_TIMEOUT, если нет периодической проблемы с подключением ( Каждую минуту я получаю логи на свой сервер, так что это не проблема с Wi-Fi / Интернетом). Я использую последнюю версию SDK AWS IoT отсюда - https://github.com/aws/aws-iot-device-sdk-java.

Как я могу решить эти проблемы?

МОЕ ЛЮБОВНОЕ РЕШЕНИЕ:

Я добавил запланированный поток, который отправляет пустые сообщения в тему - $ {iot: Connection.Thing.ThingName} / ping каждые 20 минут:

scheduledExecutor.scheduleAtFixedRate(() -> {
    try {
        iotClient.publish(String.format(Configuration.PING_TOPIC, deviceId), AWSIotQos.QOS0, "");
    } catch (AWSIotException e) {
        LOGGER.error("Failed to send ping", e);
    }
}, Configuration.PING_INITIAL_DELAY_IN_MINUTES, Configuration.PING_PERIOD_IN_MINUTES, TimeUnit.MINUTES);

Таким образом, это решение решает неактивную проблему, но я все же хочу найти более элегантное решение ...


person Rougher    schedule 18.12.2020    source источник


Ответы (1)


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

Во время переподключения он все еще подключается с использованием переданного вами идентификатора устройства (однако соединение могло не существовать со стороны MQTT), и поэтому он видит, что пытается подключиться с тем же идентификатором.

Прочитав немного об этом, похоже, вы на самом деле не регистрируете свое устройство как (вещь) в aws ..

Если бы вы были, они, когда вы создаете соединение MQTT и передаете этот идентификатор вещи, то даже при повторном подключении он не выдаст вам эту ошибку DuplicateID.

     AWSIotMqttClient client = new AWSIotMqttClient(...);
     
     SomeDevice someDevice = new SomeDevice(thingName);    // SomeDevice extends AWSIotDevice
     
     client.attach(someDevice);
     
     client.connect();

вы также можете поэкспериментировать с iotClient.cleanSession(true/false), чтобы увидеть, может ли это вам помочь.

/ ** * Устанавливает, должны ли клиент и сервер устанавливать чистый сеанс для каждого соединения. * Если false, сервер должен попытаться сохранить состояние клиента между соединениями. * Это должно быть установлено до вызова {@link #connect ()}. * * @param cleanSession * Если true, сервер запускает чистый сеанс с клиентом при каждом соединении. * Если false, сервер должен сохранять состояние клиента между соединениями. * /

@Override
public void setCleanSession(boolean cleanSession) { super.setCleanSession(cleanSession); }

https://docs.aws.amazon.com/iot/latest/developerguide/iot-thing-management.html

MQTT_KEEP_ALIVE_TIMEOUT Если нет связи клиент-сервер в течение 1,5x времени поддержания активности клиента, клиент отключается.

Это означает, что вы не отправляете / не получаете сообщения ... нет способа исправить это, если вы не сохраняете активное соединение и не делаете что-то

person Susan Mustafa    schedule 18.12.2020
comment
Итак, если устройство работает, но не отправляет / не принимает сообщения, то каждые 30 минут я буду получать электронные письма о состоянии подключения / отключения? Это выглядит странно. Как я могу решить эту проблему с помощью AWS IoT? - person Rougher; 18.12.2020
comment
@Rougher, это то, что говорится в документации ... Клиенты отключаются, если нет активности. - person Susan Mustafa; 18.12.2020
comment
Но как насчет iotClient.setKeepAliveInterval (0)? Установка этого значения на 0 отключит функцию проверки активности соединения. Прочтите здесь: github.com/aws/aws-iot-device-sdk-java/blob/master/ - person Rougher; 18.12.2020
comment
Попробуйте @Rougher. Может 0 сохранить его навсегда? Стоит попробовать. Пожалуйста, дайте мне знать. Я хотел бы знать - person Susan Mustafa; 18.12.2020
comment
Если я установил для keep-alive значение 0, через 30 минут он отключается и не подключается повторно. Похоже на следующую проблему: github.com/aws/aws- iot-device-sdk-js / issues / 254 - person Rougher; 22.12.2020