Hallo Pythonisten,

gegeben sei das unter https://paste.debian.net/1335477/ hinterlegte
Programm:

#!/usr/bin/python
"""
keks.
"""

import time
import uuid
import paho.mqtt.client as mqtt


class MQTTClient:
    """maintain connection to MQTT broker"""

    def __init__(
        self,
        broker_host,
        subscribe_topic,
        broker_port=1883,
        max_retries=20,
        retry_delay=30,
        keepalive=60,
    ):
        self.broker_host = broker_host
        self.broker_port = broker_port
        self.subscribe_topic = subscribe_topic
        self.max_retries = max_retries
        self.retry_delay = retry_delay
        self.keepalive = keepalive

        # Initialize MQTT client
        print("create mqtt.Client")
        client_id = f"mqttkeks-{uuid.uuid4()}"
        self.client = mqtt.Client(client_id=client_id)
        print("mqtt.Client created")
        self.client.on_connect = self.on_connect
        self.client.on_disconnect = self.on_disconnect

    def __del__(self):
        self.disconnect()

    def connect(self):
        """connect to broker and begin the mqtt loop"""
        if not self.reconnect_with_retry():
            print("Failed to connect to MQTT broker")

    def disconnect(self):
        """disconnect"""
        if self.client.is_connected():
            self.client.loop_stop()
            self.client.disconnect()
            print("Disconnected from MQTT broker.")

    def reconnect_with_retry(self):
        retry_count = 0
        while retry_count < self.max_retries:
            try:
                self.client.loop_stop(force=True)
                self.client.disconnect()
                self.client.connect(
                    self.broker_host,
                    self.broker_port,
                    self.keepalive
                )
                print("(Re)connected successfully to MQTT")
                self.loop_start()
                print("restarted MQTT loop")
                return True
            except (ConnectionRefusedError, OSError) as ex:
                print(
                    "Failed to connect to MQTT broker: "
                    f"(Attempt {retry_count + 1}): {ex}"
                    )
                retry_count += 1
                if retry_count < self.max_retries:
                    print(
                        "Retrying connection in "
                        f"{self.retry_delay} seconds..."
                    )
                    time.sleep(self.retry_delay)
                else:
                    print(
                        "Max retry attempts reached. "
                        "Could not connect to MQTT broker"
                    )
                    raise

    def on_connect(self, client, userdata, flags, rc):
        """subscribe to topic and log successful connection"""

        print(f"Connected to MQTT broker {rc=}")
        if rc == 0:
            try:
                self.client.subscribe(self.subscribe_topic)
                print(f"Subscribed to {self.subscribe_topic=}")
            except Exception as ex:
                print(
                        f"subscribe to {self.subscribe_topic=} failed."
                        f"{ex=}"
                )
        else:
            print(
                f"Connection failed with code {rc}."
            )

    def on_disconnect(self, client, userdata, rc):
        """Handle unexpected disconnection and try to reconnect."""
        print(
            f"Disconnected from MQTT broker with result code {rc}"
        )
        if rc != 0:  # If disconnection is unexpected
            print("Attempting to reconnect to MQTT broker...")
            self.reconnect_with_retry()

    def start(self):
        """Start MQTT client"""
        self.connect()

    def stop(self):
        """Stop MQTT client and disconnect"""
        self.disconnect()

    def loop_start(self):
        """Start MQTT network loop in a separate thread"""
        self.client.loop_start()


if __name__ == "__main__":
    mqttc = MQTTClient(
                'mqtt.ka51.zugschlus.de',
                'tele/rain/raw_json',
                retry_delay=5,
            )
    try:
        print("mqtt.start(")
        mqttc.start()
        print(")")
        while True:
            time.sleep(10)  # Keeps the program alive
    except KeyboardInterrupt:
        print("\nKeyboardInterrupt received; exiting.")
    finally:
        print("mqtt.stop(")
        mqttc.stop()
        print(")")

# end

Beim Erstaufruf verhält es sich wie es soll:

create mqtt.Client
mqtt.Client created
mqtt.start(
(Re)connected successfully to MQTT
restarted MQTT loop
)
Connected to MQTT broker rc=0
Subscribed to self.subscribe_topic='tele/rain/raw_json'

Wenn ich nun den mqtt Broker neu starte, versucht es sofort zu
reconnecten, holt sich ein TCP RST ab, weil der Broker so schnell nicht
wieder da ist.

Disconnected from MQTT broker with result code 7
Attempting to reconnect to MQTT broker...
Failed to connect to MQTT broker: (Attempt 1): [Errno 111] Connection refused
Retrying connection in 30 seconds...

und nach 30 Sekunden reconnected er wieder:

(Re)connected successfully to MQTT
restarted MQTT loop

Aber es wird on_connect nicht aufgerufen, deswegen geht das subscribe
nicht raus.

Die Plattform ist Debian stable, python 3.11 und paho-mqtt 1.6.1.

Hat hier jemand mehr praktische Erfahrung mit der Paho-Bibliothek?

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421
_______________________________________________
python-de Mailingliste -- python-de@python.org
Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an 
python-de-le...@python.org
https://mail.python.org/mailman3/lists/python-de.python.org/
Mitgliedsadresse: arch...@mail-archive.com

Reply via email to