Почему клиент mqtt отправляет «CONNECT» дважды и почему mosquitto_username_pw_set () всегда вызывает CONNACK (5)? - PullRequest
0 голосов
/ 21 октября 2019

Я реализую функцию, которая позволит клиенту mqtt подключаться к другому брокеру во время выполнения и использовать имя пользователя и пароль, предоставленные пользователем.

  • Я использую статическую сборку Qt 5.11.2 с компилятором MSVC 15.0.
  • Это клиент для Windows, у которого mosquitto_loop_forever () в цикле, выполняемом в отдельном потоке (используя WinAPICreateThread ()).
  • Я использовал mosquitto 1.5.4 для своей программы.
  • Когда предполагается подключение к другому брокеру, я вызываю mosquitto_disconnect (), а затем снова mosquitto_connect ()с новыми данными, и я снова вызываю mosquitto_username_pw_set () для установки нового имени пользователя и пароля перед mosquitto_connect ().
  • Я пока не использую SSL / TLS, я подключаюсь через стандартный порт 1883, и удаленный брокер принимает соединения оттам.

Проблема возникает, когда я хочу, чтобы мой клиент переключил свое соединение с другим брокером в моей локальной сети. Это попадает в петлю переподключения. По-видимому, он отправляет сообщение CONNECT дважды, что, как я изначально подозревал, приводит к дублированию идентификатора и, следовательно, CONNACK (5) на удаленном посреднике, но это оказалось чем-то другим.

Я выяснил, удалив строки, которые устанавливаютпараметры экземпляра mosquitto, это то, что mosquitto_username_pw_set () вызывает отказ от брокера - CONNACK (5), но когда эта функция удалена, CONNECT по-прежнему происходит дважды, а соединение просто нормально - CONNACK (0).

ВопросВот почему удаление этой конкретной функции позволяет соединению работать нормально и почему CONNECT отправляется вообще дважды?

Вот что я пробовал:

  • Я дважды проверил, могут ли мои идентификаторыбыть жестко закодированным в любом месте, это был совет, который я часто видел на стеке и где угодно. Идентификаторы клиента не жестко закодированы.
  • I проверено , если mosquitto_username_pw_set () возвращает MOSQ_ERR_SUCCESS, и это происходит.
  • Я попытался перейти на mosquitto 1.6.7. Такое же поведение происходит.
  • Я проверил, были ли в моих темах, именах пользователей и паролях завершающие символы в конце. У них их не было.
  • Я попытался уничтожить экземпляр mosquitto и снова вызвать mosquitto_new () перед подключением. Не помогло.
  • Итак, я сделал минимальный пример, в котором нет зависимостей Qt, он переключается между 1 и 2 и воспроизводит проблему, поэтому я могу надеяться, что ее можно будет легко определить, удалив функции, которые устанавливают параметрыпо одному. Поведение все еще происходит, так что, вероятно, это не какая-то специфика Qt.

Когда я полностью удаляю mosquitto_username_pw_set () из кода, клиент подключается очень хорошо (CONNACK (0)), но CONNECT равен все еще уходит дважды , но без CONNACK (5).

Я не уверен, почему это происходит.

Вот некоторый код:

Функция потока:

DWORD WINAPI MosqThread(LPVOID lpParam)
{
    while (1)
    {
    mosquitto_loop_forever(g_mosq_ext, 1000, 1);
    }
    return 0;
}

Инициализация Mosquitto:

mosquitto_lib_init();
bool clean_session = true;
    g_mosq_ext = mosquitto_new(NULL, clean_session, NULL);

Часть кода, в которой проблема возникает с этой очень специфической функцией mosquitto_username_pw_set ().

(подключение к localhost в основном идентично, как в "num == 2" для адреса локальной сети)

while(true)
    {
        num = getchar();
        if(num == '1')
        {
           //connect to localhost
        }
        if(num == '2')
        {
            int rc;
            do {
                mosquitto_disconnect(g_mosq_ext);

                //Removing this function from everywhere in the code
                //makes client connect to broker just fine
                //Otherwise, no
                mosquitto_username_pw_set(g_mosq_ext, "guest", "guest");

                mosquitto_log_callback_set(g_mosq_ext,log_callback);
                mosquitto_connect_callback_set(g_mosq_ext,connect_callback);
                mosquitto_disconnect_callback_set(g_mosq_ext,disconnect_callback);

                rc = mosquitto_connect(g_mosq_ext, "192.168.1.75", 1883, true);
                printf("[%s] 192.168.1.75: %s rc=%d\n",
                       __FUNCTION__,
                       mosquitto_strerror(rc),
                       rc);
                printf("sleep 1 sec \n");
                _sleep(1000);
                printf("sleep done \n");
            } while (rc != MOSQ_ERR_SUCCESS);

            //Start thread, calls CreateThread() in itself
            thread();
}
}

Поскольку я тестировал этот минимальный пример, я собрал несколько журналов.

Обратные вызовы журналов показали мне это:

1
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[main] localhost: No error. rc=0
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received CONNACK (0)
[connect_callback] Connection Accepted. 0
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending PINGREQ
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received PINGRESP
2
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending DISCONNECT
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[main] 192.168.1.75: No error. rc=0
sleep 1 sec
sleep done
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received CONNACK (5)
[connect_callback] Connection Refused: not authorised. 5
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received CONNACK (5)
[connect_callback] Connection Refused: not authorised. 5
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received CONNACK (5)
[connect_callback] Connection Refused: not authorised. 5
1
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[main] localhost: No error. rc=0
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received CONNACK (0)
[connect_callback] Connection Accepted. 0
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending CONNECT
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received CONNACK (0)
[connect_callback] Connection Accepted. 0
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending PINGREQ
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending PINGREQ
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k sending PINGREQ
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received PINGRESP
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received PINGRESP
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received PINGRESP
[log_callback] 4191392.004 Client mosq-11EwIEknLGlr2Joo3k received PINGRESP

Существует дубликат CONNECT, которыйЯ подозреваю, что это может быть проблемой.

И когда я попытался удалить mosquitto_username_pw_set (), чтобы увидеть, где он меня находит:

1
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending CONNECT
[main] localhost: No error. rc=0
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH received CONNACK (0)
[connect_callback] Connection Accepted. 0
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending PINGREQ
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH received PINGRESP
2
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending DISCONNECT
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending CONNECT
[main] 192.168.1.75: No error. rc=0
sleep 1 sec
sleep done
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending CONNECT
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH received CONNACK (0)
[connect_callback] Connection Accepted. 0
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending PINGREQ
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH sending PINGREQ
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH received PINGRESP
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH received PINGRESP
[log_callback] 3863712.003 Client mosq-qZDF50s4TWJEM7LSHH received PINGRESP

CONNECT все еще происходит дважды, но посредник не отказывает в соединенияхпотому что mosquitto_username_pw_set () отсутствует.

Я ожидал, что смогу правильно подключиться к другому брокеру с помощью mosquitto_username_pw_set (), но я как-то получаю CONNECT дважды, а затемCONNACK (5), когда по всем учетным записям это не должно происходить, и в то же время, когда этой функции нет, клиент подключается просто отлично, даже если CONNECT все еще отправляется дважды с одного и того же идентификатора.

Это mosquitto_loop_forever () пытается переподключиться и затем мешает с синхронизацией?

Есть ли что-то, что делает mosquitto_username_pw_set ()?

Это на самом деле конфигурация брокера, которую я долженотметьте вместо этого?

Есть еще идеи?

...