Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to specify session_id for connect() #226

Merged
merged 4 commits into from
Jan 2, 2025

Conversation

vladak
Copy link
Contributor

@vladak vladak commented Nov 5, 2024

The ConnectionManager used by MiniMQTT disallows connecting to the same host/port combination multiple times. Sometimes it is actually handy to be able to create multiple connections, e.g. to test a MQTT broker implementation. This change allows for that by propagating the session_id parameter from connect() to the ConnectionManager.

Tested with CPython and a MQTT broker (called femtomqtt) running on localhost:

#!/usr/bin/env python3

try:
    import logging
except ImportError:
    import adafruit_logging as logging

try:
    from secrets import secrets
except ImportError:
    pass

import ssl
import sys

import adafruit_minimqtt.adafruit_minimqtt as MQTT


def main(session_id):
    logger = logging.getLogger(__name__)
    try:
        console_handler = logging.StreamHandler()
        logger.addHandler(console_handler)
    except Exception:
        pass
    logger.setLevel(logging.DEBUG)

    try:
        import wifi
        import socketpool

        logger.info("Connecting to wifi")
        wifi.radio.connect(secrets["SSID"], secrets["password"], timeout=10)
        logger.info("Connected to wifi")
        pool = socketpool.SocketPool(wifi.radio)
        host = secrets["broker"]
    except ImportError:
        import socket

        pool = socket
        host = "localhost"

    port = 1883
    mqtt_client = MQTT.MQTT(
        broker=host,
        port=port,
        socket_pool=pool,
        ssl_context=ssl.create_default_context(),
        connect_retries=1,
    )

    mqtt_client.logger = logger

    for i in range(2):
        logger.debug(f"connect #{i} with session_id = {session_id}")
        if session_id:
            session_id += f"{i}"
        mqtt_client.connect(session_id=session_id)


if __name__ == "__main__":
    session_id = None
    if len(sys.argv) > 1:
        session_id = sys.argv[1]
    try:
        main(session_id)
    except KeyboardInterrupt:
       pass

With no arguments the program ends with:

connect #0 with session_id = None
Attempting to connect to MQTT broker (attempt #0)
Attempting to establish MQTT connection...
Sending CONNECT to broker...
Fixed Header: bytearray(b'\x10\x14')
Variable Header: bytearray(b'\x00\x04MQTT\x04\x02\x00<')
Receiving CONNACK packet from broker
Got message type: 0x20 pkt: 0x20
Resetting reconnect backoff
connect #1 with session_id = None
Attempting to connect to MQTT broker (attempt #0)
Attempting to establish MQTT connection...
Closing socket
Socket error when connecting: Socket already connected to mqtt://localhost:1883
Traceback (most recent call last):
  File "/home/vkotal/Adafruit_CircuitPython_MiniMQTT/adafruit_minimqtt/adafruit_minimqtt.py", line 430, in connect
    ret = self._connect(
  File "/home/vkotal/Adafruit_CircuitPython_MiniMQTT/adafruit_minimqtt/adafruit_minimqtt.py", line 501, in _connect
    self._sock = self._connection_manager.get_socket(
  File "/home/vkotal/Adafruit_CircuitPython_MiniMQTT/venv/lib/python3.10/site-packages/adafruit_connection_manager.py", line 311, in get_socket
    raise RuntimeError(f"Socket already connected to {proto}//{host}:{port}")
RuntimeError: Socket already connected to mqtt://localhost:1883

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/vkotal/Adafruit_CircuitPython_MiniMQTT/./session_id.py", line 66, in <module>
    main(session_id)
  File "/home/vkotal/Adafruit_CircuitPython_MiniMQTT/./session_id.py", line 58, in main
    mqtt_client.connect(session_id=session_id)
  File "/home/vkotal/Adafruit_CircuitPython_MiniMQTT/adafruit_minimqtt/adafruit_minimqtt.py", line 464, in connect
    raise MMQTTException(exc_msg) from last_exception
adafruit_minimqtt.adafruit_minimqtt.MMQTTException: ('Connect failure', None)

with any argument 2 connections are created (verified with netstat):

connect #0 with session_id = foo
Attempting to connect to MQTT broker (attempt #0)
Attempting to establish MQTT connection...
Sending CONNECT to broker...
Fixed Header: bytearray(b'\x10\x13')
Variable Header: bytearray(b'\x00\x04MQTT\x04\x02\x00<')
Receiving CONNACK packet from broker
Got message type: 0x20 pkt: 0x20
Resetting reconnect backoff
connect #1 with session_id = foo0
Attempting to connect to MQTT broker (attempt #0)
Attempting to establish MQTT connection...
Sending CONNECT to broker...
Fixed Header: bytearray(b'\x10\x13')
Variable Header: bytearray(b'\x00\x04MQTT\x04\x02\x00<')
Receiving CONNACK packet from broker
Got message type: 0x20 pkt: 0x20
Resetting reconnect backoff

Also tested the same code on Adafruit CircuitPython 9.2.0 on 2024-10-28; Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM with ESP32S3.

Copy link
Contributor

@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good and is upward compatible.

@dhalbert
Copy link
Contributor

dhalbert commented Jan 2, 2025

@vladak could you resolve the merge conflicts? Thanks.

@vladak vladak force-pushed the connect_session_id branch from ce13e01 to 269d10b Compare January 2, 2025 16:48
@vladak
Copy link
Contributor Author

vladak commented Jan 2, 2025

@dhalbert rebased

@dhalbert dhalbert merged commit b47a501 into adafruit:main Jan 2, 2025
1 check passed
@vladak
Copy link
Contributor Author

vladak commented Jan 2, 2025

Retesting revealed a problem with slightly older code, @dhalbert see #232 for a fix.

adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Jan 3, 2025
Updating https://github.com/adafruit/Adafruit_CircuitPython_MLX90393 to 2.3.1 from 2.3.0:
  > Merge pull request adafruit/Adafruit_CircuitPython_MLX90393#45 from FoamyGuy/reset_sleep_ms

Updating https://github.com/adafruit/Adafruit_CircuitPython_MPRLS to 1.2.20 from 1.2.19:
  > Merge pull request adafruit/Adafruit_CircuitPython_MPRLS#20 from FoamyGuy/type_annotations

Updating https://github.com/adafruit/Adafruit_CircuitPython_PCF8575 to 1.0.7 from 1.0.6:
  > Merge pull request adafruit/Adafruit_CircuitPython_PCF8575#8 from FoamyGuy/value_return_bool

Updating https://github.com/adafruit/Adafruit_CircuitPython_VL6180X to 1.4.15 from 1.4.14:
  > Merge pull request adafruit/Adafruit_CircuitPython_VL6180X#34 from FoamyGuy/min_delay_continuous

Updating https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT to 7.11.0 from 7.10.5:
  > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#232 from vladak/send_bytes_eagain
  > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#226 from vladak/connect_session_id
  > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#229 from manchicken/patch-1
  > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#231 from dhalbert/partial-send
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants