首页 > 解决方案 > Paho 连接问题 - Mosquitto:与代理通信时发生网络协议错误

问题描述

  1. 我运行 mosquitto(docker 映像 - 在外部服务器上)
  2. 一段时间后,我的 mosquitto 不起作用并显示此错误(我不知道为什么)

与代理通信时发生网络协议错误。

  1. 当这个 mosquitto 错误发生并且我尝试连接/发布时,(python) paho.mqtt 向我抛出这个:

回溯(最近一次通话最后):

文件“/usr/lib/python3.5/threading.py”,第 914 行,在 _bootstrap_inner
self.run()
文件“/usr/lib/python3.5/threading.py”,第 862 行,运行
self._target (*self._args, **self._kwargs)
文件“/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 行,在 loop_read
rc = self._packet_read()
文件“/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py”,第 2071 行,在 _packet_read
rc = self._packet_handle()
文件“/usr/local/lib/python3.5 /dist-packages/paho/mqtt/client.py”,第 2560 行,在 _packet_handle
返回 self._handle_publish()
文件“/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py” ,第 2728 行,在 _handle_publish (topic, packet) = struct.unpack(pack_format, packet) struct.error: bad char in struct format

  1. 看起来我的 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] 

标签: pythondockermosquittopaho

解决方案


推荐阅读