Проблема с подключением Paho - Mosquitto: при общении с брокером произошла ошибка сетевого протокола - PullRequest
0 голосов
/ 23 ноября 2018
  1. Я запускаю mosquitto (образ докера - на внешнем сервере)
  2. Через некоторое время мой mosquitto не работает и показывает эту ошибку (не знаю почему)

Произошла ошибка сетевого протокола при взаимодействии с брокером.

Когда возникает ошибка комара, и я пытаюсь подключиться / опубликовать, (python) paho.mqtt выдает мне следующее:

Traceback (последний вызов был последним):

Файл "/usr/lib/python3.5/threading.py", строка 914, в _bootstrap_inner
self.run ()
Файл "/ usr /lib / python3.5 / threading.py ", строка 862, в прогоне
self._target (* self._args, ** self._kwargs)
File" / usr / local /lib / python3.5 / dist-packages / paho / mqtt / client.py ", строка 2913, в _thread_main
self.loop_forever (retry_first_connection = True)
Файл "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", строка 1578, в loop_forever
rc = self.loop (timeout, max_packets)
Файл "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", строка 1072, в цикле
rc= self.loop_read (max_packets)
Файл "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", строка 1374, в цикле_читать
rc = self._packet_read ()
Файл "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", строка 2071, в _packet_read
rc = self._packet_handle ()
File" /usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py ", строка 2560, в _packet_handle
вернуть self._handle_publish ()
File" /usr/local/lib/python3.5/dist-packages / paho / mqtt / client.py ", строка 2728, в _handle_publish (тема, пакет) = struct.unpack (pack_format, пакет) struct.error: неверный символ в формате struct

Похоже, что мой paho.mqtt.client все еще подключен, но даже если я перезапущу mosquitto и использую mosquitto_sub (ошибка mosquitto исчезла), я все равно не вижу сообщений из моей программы.Мне нужно перезапустить программу, но это неудовлетворительное решение.

Не могли бы вы сказать мне, пожалуйста, почему Mosquitto показывает мне эту ошибку и / или как я могу поймать (python) paho.mqtt socket.error (Это возможно?)

Я думаю, что эта часть кода должна быть достаточной :)

mqtt_client.py

class MQttClient:
    client = None
    connected_flag = False
    loop_is_working_flag = False
    broker_is_online_flag = True
    subscribe_command_channel_flag = True
    mosquitto_ip = None

    def __init__(self, config):
        self.config = config
        self.logger = Logger(config, self)


    def connect(self, ip_address='127.0.0.1', port=1883, keepalive=4):
        self.mosquitto_ip = ip_address
        self.client = mqtt.Client(self.config.get(REQUIRE_INI_SECTION, DEVICE_ID_INI_PARAMETER), clean_session=False)
        self.client.on_connect = self.on_connect
        self.client.on_disconnect = self.on_disconnect
        try:
            self.client.connect(ip_address, port, keepalive=keepalive)
            self.client.loop_start()
            self.wait_for_connect()
            self.loop_is_working_flag = True
        except (OSError, ConnectionRefusedError):
            self.logger.error(CAN_NOT_CONNECT_WITH_IP_ADDRESS_ERROR.format(ip_address), send_to_mosquitto=False)

    def publish_message(self, message, topic, retain=False):
        return self.client.publish(self.config.get(REQUIRE_INI_SECTION, BUILDING_NAME_INI_PARAMETER)
                                   + '/' + topic + '/' +
                                   self.config.get(REQUIRE_INI_SECTION, DEVICE_ID_INI_PARAMETER), message, qos=1,
                                   retain=retain)

    def on_connect(self, client, userdata, flags, rc):
        if rc is 0:
            self.connected_flag = True
            self.logger.info(CONNECTED_TO_THE_MOSQUITO_INFO.format(self.mosquitto_ip), send_to_mosquitto=True)

    def on_disconnect(self, client, userdata, rc):
        if rc is not 0:
            self.connected_flag = False
            self.logger.error(DISCONNECTED_FROM_THE_MOSQUITO_ERROR.format(
                self.mosquitto_ip, str(rc)), send_to_mosquitto=True)

    def wait_for_connect(self):
        while not self.connected_flag:
            pass

    ...

И использование:

контроллер.py

class Controller:

    def __init__(self):
        self.config = configparser.ConfigParser()
        self.config.read(CONFIG_FILE_PATH)
        self.client = MQttClient(self.config)
        self.__connect_to_mosquitto()

    def __connect_to_mosquitto(self):
        if Network.host_is_available(self.config.get(NETWORK_INI_SECTION, BROKER_IP_INI_PARAMETER)):
            if not self.client.loop_is_working_flag:                
                self.client.connect(ip_address=self.config.get(NETWORK_INI_SECTION, BROKER_IP_INI_PARAMETER))
                time.sleep(0.2)
                self.client.publish_message(self.json_parser.get_json_welcome_data(), MOSQUITTO_TOPIC_WELCOME_DATA)

        else:
            self.logger.error(NO_CONNECTION_WITH_BROKER_ERROR, send_to_mosquitto=False)
            Network.restart_network_interface_if_there_is_no_connection(
                self.config.get(NETWORK_INI_SECTION, ROUTER_IP_INI_PARAMETER))

    ...

    def execute(self):
        while self.client.connected_flag and self.client.broker_is_online_flag:
            ...
            if self.client.publish_message(data, MOSQUITTO_TOPIC_DATA)[0] is not 0:
                ...
                self.logger.error(CAN_NOT_SEND_DATA_TO_MOSQUITTO_ERROR)
                break

Я проверил, и этот метод возвращает 0 (успех).Но я не получаю сообщения о mosquitto_sub

 self.client.publish_message(data, MOSQUITTO_TOPIC_DATA)[0] 
...