gmqtt icon indicating copy to clipboard operation
gmqtt copied to clipboard

Unhandled [WinError 10054]

Open Allineer opened this issue 6 years ago • 6 comments

Елена, извините, опишу на русском, ибо писать много, а мой английский совсем не вери-велл :(

Пришлось протестировать на богопротивной Windows и сразу столкнулся с проблемой. Вкратце: обычное поведение клиента состоит в том, что при неудачном подключении к брокеру, выполняются попытки переподключения.

Я категорически несогласен с этим поведением и не совсем понимаю, как это поведение обойти.

Пытаюсь обойти следующим образом:

        try:
            await self._client.connect(self._host, self._port, self._ssl, version=MQTTv311)
        except:
            self._client.stop_reconnect()
            await self._client.disconnect()

И это даже работает - при неудачной попытке первичного подключения, клиент бросает дальнейшие попытки.

Но не на Windows... В начале теста я забыл изменить значение параметра ssl метода connect - брокер требует безопасное подключение, но я передал значение False. В итоге наблюдаю следующую картину:

[CONNECTION MADE]
[EXC: CONN LOST]
================================================================================
Traceback (most recent call last):
  File "...Python\lib\asyncio\selector_events.py", line 804, in _read_ready__data_received
    data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] Удаленный хост принудительно разорвал существующее подключение
================================================================================
[CMD 0xe0] b''
[TRYING WRITE TO CLOSED SOCKET]

И так по кругу. Приведенный выше код try...except, который призван остановить попытки после первой же неудачной, в данном случае не срабатывает. Посоветуйте, что можно сделать?

Вопрос, на самом деле, даже более широкий: каким образом я могу не дожидаться подключения к брокеру, если уже после первой попытки понятно, что продолжать бесполезно - ошибочные host и порт, некорректные логин и пароль и т.п.? В то же время, если возникла необходимость переподключения в процессе работы (например, на какое-то время пропало соединение), то продолжать попытки нужно практически до победы.

Allineer avatar Oct 02 '19 12:10 Allineer

@Allineer Попробуйте сделать self._client.stop_reconnect() еще до собственно await self._client.connect. Эта функция просто изначально поменяет конфиг количества неудачных переподключений.

Lenka42 avatar Oct 02 '19 12:10 Lenka42

@Lenka42 логично :) А как потом включить реконнект, после успешного первичного подключения на случай последующих проблем с подключением?

И остается проблема с WinError - при возникновении такой ошибки, управление не возвращается из метода connect - получается такой себе вечный await.

Allineer avatar Oct 02 '19 12:10 Allineer

Обидно конечно, что на винде не работает. У нас на Линуксе как раз такое поведение как вы описываете, при первом коннэкте если не подключилось - ошибка. А если первый раз успешно подключилось - дальше реконнэкты при разрывах. Мне кажется эту ошибку будет сложно отловить, у нее вон трэйсбэк напрямую из asyncio а не вашего кода. Но я завтра ее еще поковыряю. А вернуть реконнэкты можно методом client.set_config({'reconnect_retries': 10, 'reconnect_delay': 60}) reconnect_retries - количество допустимых неудачных подключений подряд reconnect_delay - ожидание в секундах между попытками подключения

Lenka42 avatar Oct 02 '19 15:10 Lenka42

А какой у вас брокер?

Lenka42 avatar Oct 02 '19 16:10 Lenka42

mosquitto 1.5.7-1

Allineer avatar Oct 02 '19 17:10 Allineer

при первом коннэкте если не подключилось - ошибка. А если первый раз успешно подключилось - дальше реконнэкты при разрывах.

Тоже не совсем так, правда на macOS:

Using selector: KqueueSelector
[CONNECTION MADE]
[CMD 0x20] b'\x00\x05'
[CONNACK] 0x5
[QoS query IS EMPTY]
[RECV EMPTY] Connection will be reset automatically.
[CONN CLOSE NORMALLY]
[CMD 0xe0] b''
[CONNECTION MADE]
[CMD 0x20] b'\x00\x05'
[CONNACK] 0x5
[QoS query IS EMPTY]
[RECV EMPTY] Connection will be reset automatically.
[CONN CLOSE NORMALLY]
[CMD 0xe0] b''

Или некорректные имя пользователя-пароль считаются успешным подключением?

Allineer avatar Oct 02 '19 18:10 Allineer