杰瑞科技汇

Python如何用mosquitto实现sub订阅?

Of course! Here’s a comprehensive guide on how to use the mosquitto_sub command-line tool with Python, covering the most common scenarios.

Python如何用mosquitto实现sub订阅?-图1
(图片来源网络,侵删)

There are two main ways to approach this:

  1. Method 1: Using Python as a Client (Recommended): You use a Python MQTT library like paho-mqtt to act as a subscriber directly. This is the most common, flexible, and powerful method.
  2. Method 2: Calling the mosquitto_sub Command from Python: You use Python's subprocess module to run the mosquitto_sub command-line tool and capture its output. This is useful if you need to leverage a specific feature of the command-line tool or prefer not to install a library.

Method 1: Using Python as a Client with paho-mqtt (Recommended)

This is the standard way to interact with an MQTT broker from Python. You'll write a Python script that connects to the broker and subscribes to topics.

Step 1: Install the Library

First, you need to install the Paho MQTT client library. Open your terminal or command prompt and run:

pip install paho-mqtt

Step 2: Write the Python Subscriber Script

Here is a basic, well-commented Python script that subscribes to a single topic.

Python如何用mosquitto实现sub订阅?-图2
(图片来源网络,侵删)
# subscriber.py
import paho.mqtt.client as mqtt
import time
# --- Configuration ---
BROKER_ADDRESS = "test.mosquitto.org"  # Public test broker
PORT = 1883
TOPIC = "my_home/temperature"         # The topic to subscribe to
QOS = 1                                # Quality of Service level
# --- Callback Functions ---
# This function is called when the client successfully connects to the broker.
def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Successfully connected to broker!")
        # Subscribe to the topic after connecting
        client.subscribe(TOPIC, qos=QOS)
        print(f"Subscribed to topic: '{TOPIC}' with QoS {QOS}")
    else:
        print(f"Failed to connect, return code {rc}\n")
# This function is called when a message is received from the broker.
def on_message(client, userdata, msg):
    # The msg object contains topic, payload, and qos
    print(f"Received message from '{msg.topic}':")
    # The payload is in bytes, so we need to decode it (e.g., to UTF-8)
    print(f"Payload: {msg.payload.decode('utf-8')}")
    print("-" * 20)
# --- Main Script Logic ---
# 1. Create a new MQTT client instance
client = mqtt.Client("python_subscriber_1")
# 2. Assign the callback functions
client.on_connect = on_connect
client.on_message = on_message
# 3. Connect to the broker
print(f"Connecting to {BROKER_ADDRESS}...")
try:
    client.connect(BROKER_ADDRESS, PORT, 60)
except ConnectionRefusedError:
    print("Connection refused. Is the broker running?")
    exit()
# 4. Start a background thread to handle network traffic and callbacks
# This is non-blocking, so your script can continue to run.
client.loop_start()
# 5. Keep the script running to receive messages
try:
    while True:
        time.sleep(1) # Do other things here
except KeyboardInterrupt:
    print("Unsubscribing and disconnecting...")
    client.unsubscribe(TOPIC)
    client.loop_stop()  # Stop the network loop
    client.disconnect()
    print("Disconnected.")

Step 3: Run the Script

Save the code as subscriber.py and run it from your terminal:

python subscriber.py

You will see:

Connecting to test.mosquitto.org...
Successfully connected to broker!
Subscribed to topic: 'my_home/temperature' with QoS 1

The script will now wait for messages. To test it, you need a publisher. You can use another Python script or the mosquitto_pub command-line tool.

Test with mosquitto_pub: Open a new terminal and run this command a few times to send messages:

Python如何用mosquitto实现sub订阅?-图3
(图片来源网络,侵删)
mosquitto_pub -h test.mosquitto.org -p 1883 -t "my_home/temperature" -m "It's 22 degrees Celsius"
mosquitto_pub -h test.mosquitto.org -p 1883 -t "my_home/temperature" -m "It's 23 degrees Celsius"

You will see the output in your subscriber.py terminal:

Received message from 'my_home/temperature':
Payload: It's 22 degrees Celsius
--------------------
Received message from 'my_home/temperature':
Payload: It's 23 degrees Celsius
--------------------

Method 2: Calling mosquitto_sub from Python with subprocess

This method runs the mosquitto_sub command as a separate process and reads its output. This is less efficient for continuous message streams but can be useful for simple, one-off tasks.

Step 1: Ensure mosquitto-clients is Installed

You need the mosquitto_sub executable on your system.

  • On Debian/Ubuntu:
    sudo apt-get update
    sudo apt-get install mosquitto-clients
  • On macOS (using Homebrew):
    brew install mosquitto
  • On Windows: Download the installer from the Mosquitto download page and make sure the mosquitto_sub.exe is in your system's PATH.

Step 2: Write the Python Script to Call the Command

This script will construct the command and run it.

# call_subscriber.py
import subprocess
import time
# --- Configuration ---
BROKER_ADDRESS = "test.mosquitto.org"
PORT = 1883
TOPIC = "my_home/humidity"
USERNAME = None # Optional: if your broker requires authentication
PASSWORD = None # Optional: if your broker requires authentication
# --- Construct the command ---
# The command is a list of strings, which is safer than a single string
command = [
    "mosquitto_sub",
    "-h", BROKER_ADDRESS,
    "-p", str(PORT),
    "-t", TOPIC
]
# Add username and password if they are provided
if USERNAME and PASSWORD:
    command.extend(["-u", USERNAME, "-P", PASSWORD])
print(f"Executing command: {' '.join(command)}")
# --- Run the command ---
# Use Popen for non-blocking execution or run() for blocking.
# We'll use Popen to show how to read line by line.
try:
    # Popen starts the process and immediately returns
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    # Read output line by line as it becomes available
    while True:
        # readline() will block until a full line is received or the process ends
        output = process.stdout.readline()
        if output == '' and process.poll() is not None:
            # The process has finished
            break
        if output:
            print(f"Received: {output.strip()}")
    # Check for any errors after the process has finished
    stderr = process.stderr.read()
    if stderr:
        print(f"Error output:\n{stderr}")
except FileNotFoundError:
    print("Error: 'mosquitto_sub' command not found.")
    print("Please ensure the Mosquitto clients are installed and in your system's PATH.")
except Exception as e:
    print(f"An error occurred: {e}")

Step 3: Run the Script

Save the code as call_subscriber.py and run it:

python call_subscriber.py

It will execute the mosquitto_sub command and print any messages it receives to the console. Again, you can test it by publishing messages from another terminal using mosquitto_pub.


Comparison: Method 1 vs. Method 2

Feature Method 1: Python Client (paho-mqtt) Method 2: subprocess with mosquitto_sub
Dependencies Requires paho-mqtt library. Requires mosquitto-clients installed on the system.
Integration Excellent. Native Python, easy to integrate with other libraries and logic. Poor. Requires parsing command-line output, which can be brittle.
Performance High. Runs in the same process, efficient for high-throughput or long-running connections. Lower. Creates a new process for each call, which has overhead. Not ideal for continuous streams.
Features Full access to MQTT features (last will, retained messages, QoS levels, etc.) via the API. Limited to the features exposed by the mosquitto_sub command-line flags.
Use Case Recommended for almost all applications. Building robust, integrated MQTT services. Quick scripts, simple tasks, or when you need a feature specific to the CLI tool.

Conclusion

For any serious Python application that needs to subscribe

分享:
扫描分享到社交APP
上一篇
下一篇