python - Paho 连接问题 - Mosquitto:与代理通信时发生网络协议错误
问题描述
- 我运行 mosquitto(docker 映像 - 在外部服务器上)
- 一段时间后,我的 mosquitto 不起作用并显示此错误(我不知道为什么)
与代理通信时发生网络协议错误。
- 当这个 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
- 看起来我的 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]
解决方案
推荐阅读
- python - 想在相同的比赛后打印额外的字符,在这种情况下只有“s”
- azure - 通过 HAproxy 到 Azure iothub 的 Azure SDK python 客户端(SSL 握手失败)
- python - 在执行期间跟踪python脚本中的内存消耗
- reactjs - 为什么与 Typescript 函数反应的解构道具需要传递一个对象?
- c++ - 错误 LNK2001/LNK2009:未解析的外部符号
- javascript - 如何获得排毒中每个测试的结果?
- jira - 通过 REST API 创建问题时勾选复选框 - Jira Python
- vuejs3 - Vue.js 3 - 来自导入的 Bootstrap 5 的 JS 不起作用,CSS 工作正常
- pytorch - 在 troch.nn 中禁用“就地”更新
- typescript - 在.net core web app项目中使用打字稿上传到服务器之前调整图像大小