开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
1 Star 0 Fork 0

SourceCodeSync/paho.mqtt.python

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
master
分支 (4)
标签 (18)
master
update-readme-and-example
stop-exposing-private-function
add-formating
v2.1.0
v2.0.0
v2.0.0rc2
v2.0.0rc1
v1.6.1
v1.6.0
v1.5.1
v1.5.0
v1.4.0
v1.3.1
v1.3.0
v1.2.3
v1.2.2
v1.2.1
v1.2
v1.1
v1.0
v0.9
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
贡献代码
同步代码
对比差异 通过 Pull Request 同步
同步更新到分支
通过 Pull Request 同步
将会在向当前分支创建一个 Pull
Request,合入后将完成同步
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
未知许可证

Eclipse PahoTM MQTT Python Client

The release notes and Eclipse Paho MQTT Python client library, which implements versions 5.0, 3.1.1, and 3.1 of the MQTT protocol.

This code provides a client class which enables applications to connect to an

Paho is an Contents

Installation

The latest stable version is available in the Python Package Index (PyPi) and can be installed using

pip install paho-mqtt

Or with virtualenv:

virtualenv paho-mqtt
source paho-mqtt/bin/activate
pip install paho-mqtt

To obtain the full code, including examples and tests, you can clone the git repository:

git clone https://github.com/eclipse/paho.mqtt.python

Once you have the code, it can be installed from your repository as well:

cd paho.mqtt.python
pip install -e .

To perform all tests (including MQTT v5 tests), you also need to clone paho.mqtt.testing in paho.mqtt.python folder:

git clone https://github.com/eclipse/paho.mqtt.testing.git
cd paho.mqtt.testing
git checkout a4dc694010217b291ee78ee13a6d1db812f9babd

Known limitations

The following are the known unimplemented MQTT features.

When clean_session is False, the session is only stored in memory and not persisted. This means that when the client is restarted (not just reconnected, the object is recreated usually because the program was restarted) the session is lost. This results in a possible message loss.

The following part of the client session is lost:

  • QoS 2 messages which have been received from the server, but have not been completely acknowledged.

    Since the client will blindly acknowledge any PUBCOMP (last message of a QoS 2 transaction), it won't hang but will lose this QoS 2 message.

  • QoS 1 and QoS 2 messages which have been sent to the server, but have not been completely acknowledged.

    This means that messages passed to publish() may be lost. This could be mitigated by taking care that all messages passed to publish() have a corresponding on_publish() call or use wait_for_publish.

    It also means that the broker may have the QoS2 message in the session. Since the client starts with an empty session it don't know it and will reuse the mid. This is not yet fixed.

Also, when clean_session is True, this library will republish QoS > 0 message across network reconnection. This means that QoS > 0 message won't be lost. But the standard says that we should discard any message for which the publish packet was sent. Our choice means that we are not compliant with the standard and it's possible for QoS 2 to be received twice.

You should set clean_session = False if you need the QoS 2 guarantee of only one delivery.

Usage and API

Detailed API documentation examples directory.

The package provides two modules, a full Client and few helpers for simple publishing or subscribing.

Getting Started

Here is a very simple example that subscribes to the broker $SYS topic tree and prints out the resulting messages:

import paho.mqtt.client as mqtt

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, reason_code, properties):
 print(f"Connected with result code {reason_code}")
 # Subscribing in on_connect() means that if we lose the connection and
 # reconnect then subscriptions will be renewed.
 client.subscribe("$SYS/#")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
 print(msg.topic+" "+str(msg.payload))

mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqttc.on_connect = on_connect
mqttc.on_message = on_message

mqttc.connect("mqtt.eclipseprojects.io", 1883, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
mqttc.loop_forever()

Client

You can use the client class as an instance, within a class or by subclassing. The general usage flow is as follows:

  • Create a client instance
  • Connect to a broker using one of the connect*() functions
  • Call one of the loop*() functions to maintain network traffic flow with the broker
  • Use subscribe() to subscribe to a topic and receive messages
  • Use publish() to publish messages to the broker
  • Use disconnect() to disconnect from the broker

Callbacks will be called to allow the application to process events as necessary. These callbacks are described below.

Network loop

These functions are the driving force behind the client. If they are not called, incoming network data will not be processed and outgoing network data will not be sent. There are four options for managing the network loop. Three are described here, the fourth in "External event loop support" below. Do not mix the different loop functions.

loop_start() / loop_stop()
mqttc.loop_start()

while True:
 temperature = sensor.blocking_read()
 mqttc.publish("paho/temperature", temperature)

mqttc.loop_stop()

These functions implement a threaded interface to the network loop. Calling loop_start() once, before or after connect*(), runs a thread in the background to call loop() automatically. This frees up the main thread for other work that may be blocking. This call also handles reconnecting to the broker. Call loop_stop() to stop the background thread. The loop is also stopped if you call disconnect().

loop_forever()
mqttc.loop_forever(retry_first_connection=False)

This is a blocking form of the network loop and will not return until the client calls disconnect(). It automatically handles reconnecting.

Except for the first connection attempt when using connect_async, use retry_first_connection=True to make it retry the first connection.

Warning: This might lead to situations where the client keeps connecting to an non existing host without failing.

loop()
run = True
while run:
 rc = mqttc.loop(timeout=1.0)
 if rc != 0:
 # need to handle error, possible reconnecting or stopping the application

Call regularly to process network events. This call waits in select() until the network socket is available for reading or writing, if appropriate, then handles the incoming/outgoing data. This function blocks for up to timeout seconds. timeout must not exceed the keepalive value for the client or your client will be regularly disconnected by the broker.

Using this kind of loop, require you to handle reconnection strategie.

Callbacks

The interface to interact with paho-mqtt include various callback that are called by the library when some events occur.

The callbacks are functions defined in your code, to implement the require action on those events. This could be simply printing received message or much more complex behaviour.

Callbacks API is versioned, and the selected version is the CallbackAPIVersion you provided to Client constructor. Currently two version are supported:

  • CallbackAPIVersion.VERSION1: it's the historical version used in paho-mqtt before version 2.0. It's the API used before the introduction of CallbackAPIVersion. This version is deprecated and will be removed in paho-mqtt version 3.0.
  • CallbackAPIVersion.VERSION2: This version is more consistent between protocol MQTT 3.x and MQTT 5.x. It's also much more usable with MQTT 5.x since reason code and properties are always provided when available. It's recommended for all user to upgrade to this version. It's highly recommended for MQTT 5.x user.

The following callbacks exists:

  • on_connect(): called when the CONNACK from the broker is received. The call could be for a refused connection, check the reason_code to see if the connection is successful or rejected.
  • on_connect_fail(): called by loop_forever() and loop_start() when the TCP connection failed to establish. This callback is not called when using connect() or reconnect() directly. It's only called following an automatic (re)connection made by loop_start() and loop_forever()
  • on_disconnect(): called when the connection is closed.
  • on_message(): called when a MQTT message is received from the broker.
  • on_publish(): called when an MQTT message was sent to the broker. Depending on QoS level the callback is called at different moment:
    • For QoS == 0, it's called as soon as the message is sent over the network. This could be before the corresponding publish() return.
    • For QoS == 1, it's called when the corresponding PUBACK is received from the broker
    • For QoS == 2, it's called when the corresponding PUBCOMP is received from the broker
  • on_subscribe(): called when the SUBACK is received from the broker
  • on_unsubscribe(): called when the UNSUBACK is received from the broker
  • on_log(): called when the library log a message
  • on_socket_open, on_socket_close, on_socket_register_write, on_socket_unregister_write: callbacks used for external loop support. See below for details.

For the signature of each callback, see the Subscriber example

import paho.mqtt.client as mqtt

def on_subscribe(client, userdata, mid, reason_code_list, properties):
 # Since we subscribed only for a single channel, reason_code_list contains
 # a single entry
 if reason_code_list[0].is_failure:
 print(f"Broker rejected you subscription: {reason_code_list[0]}")
 else:
 print(f"Broker granted the following QoS: {reason_code_list[0].value}")

def on_unsubscribe(client, userdata, mid, reason_code_list, properties):
 # Be careful, the reason_code_list is only present in MQTTv5.
 # In MQTTv3 it will always be empty
 if len(reason_code_list) == 0 or not reason_code_list[0].is_failure:
 print("unsubscribe succeeded (if SUBACK is received in MQTTv3 it success)")
 else:
 print(f"Broker replied with failure: {reason_code_list[0]}")
 client.disconnect()

def on_message(client, userdata, message):
 # userdata is the structure we choose to provide, here it's a list()
 userdata.append(message.payload)
 # We only want to process 10 messages
 if len(userdata) >= 10:
 client.unsubscribe("$SYS/#")

def on_connect(client, userdata, flags, reason_code, properties):
 if reason_code.is_failure:
 print(f"Failed to connect: {reason_code}. loop_forever() will retry connection")
 else:
 # we should always subscribe from on_connect callback to be sure
 # our subscribed is persisted across reconnections.
 client.subscribe("$SYS/#")

mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqttc.on_connect = on_connect
mqttc.on_message = on_message
mqttc.on_subscribe = on_subscribe
mqttc.on_unsubscribe = on_unsubscribe

mqttc.user_data_set([])
mqttc.connect("mqtt.eclipseprojects.io")
mqttc.loop_forever()
print(f"Received the following message: {mqttc.user_data_get()}")
publisher example
import time
import paho.mqtt.client as mqtt

def on_publish(client, userdata, mid, reason_code, properties):
 # reason_code and properties will only be present in MQTTv5. It's always unset in MQTTv3
 try:
 userdata.remove(mid)
 except KeyError:
 print("on_publish() is called with a mid not present in unacked_publish")
 print("This is due to an unavoidable race-condition:")
 print("* publish() return the mid of the message sent.")
 print("* mid from publish() is added to unacked_publish by the main thread")
 print("* on_publish() is called by the loop_start thread")
 print("While unlikely (because on_publish() will be called after a network round-trip),")
 print(" this is a race-condition that COULD happen")
 print("")
 print("The best solution to avoid race-condition is using the msg_info from publish()")
 print("We could also try using a list of acknowledged mid rather than removing from pending list,")
 print("but remember that mid could be re-used !")

unacked_publish = set()
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqttc.on_publish = on_publish

mqttc.user_data_set(unacked_publish)
mqttc.connect("mqtt.eclipseprojects.io")
mqttc.loop_start()

# Our application produce some messages
msg_info = mqttc.publish("paho/test/topic", "my message", qos=1)
unacked_publish.add(msg_info.mid)

msg_info2 = mqttc.publish("paho/test/topic", "my message2", qos=1)
unacked_publish.add(msg_info2.mid)

# Wait for all message to be published
while len(unacked_publish):
 time.sleep(0.1)

# Due to race-condition described above, the following way to wait for all publish is safer
msg_info.wait_for_publish()
msg_info2.wait_for_publish()

mqttc.disconnect()
mqttc.loop_stop()

Logger

The Client emit some log message that could be useful during troubleshooting. The easiest way to enable logs is the call enable_logger(). It's possible to provide a custom logger or let the default logger being used.

Example:

import logging
import paho.mqtt.client as mqtt

logging.basicConfig(level=logging.DEBUG)

mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqttc.enable_logger()

mqttc.connect("mqtt.eclipseprojects.io", 1883, 60)
mqttc.loop_start()

# Do additional action needed, publish, subscribe, ...
[...]

It's also possible to define a on_log callback that will receive a copy of all log messages. Example:

import paho.mqtt.client as mqtt

def on_log(client, userdata, paho_log_level, messages):
 if paho_log_level == mqtt.LogLevel.MQTT_LOG_ERR:
 print(message)

mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqttc.on_log = on_log

mqttc.connect("mqtt.eclipseprojects.io", 1883, 60)
mqttc.loop_start()

# Do additional action needed, publish, subscribe, ...
[...]

The correspondence with Paho logging levels and standard ones is the following:

Paho logging
MQTT_LOG_ERR logging.ERROR
MQTT_LOG_WARNING logging.WARNING
MQTT_LOG_NOTICE logging.INFO (no direct equivalent)
MQTT_LOG_INFO logging.INFO
MQTT_LOG_DEBUG logging.DEBUG

External event loop support

To support other network loop like asyncio (see while run: if need_read: mqttc.loop_read() if need_write: mqttc.loop_write() mqttc.loop_misc() if not need_read and not need_write: # But don't wait more than few seconds, loop_misc() need to be called regularly wait_for_change_in_need_read_or_write() updated_need_read_and_write()

The tricky part is implementing the update of need_read / need_write and wait for condition change. To support this, the following method exists:

  • socket(): which return the socket object when the TCP connection is open. This call is particularly useful for Global helper functions

    The client module also offers some global helper functions.

    topic_matches_sub(sub, topic) can be used to check whether a topic matches a subscription.

    For example:

    the topic foo/bar would match the subscription foo/# or +/bar

    the topic non/matching would not match the subscription non/+/+

    Publish

    This module provides some helper functions to allow straightforward publishing of messages in a one-shot manner. In other words, they are useful for the situation where you have a single/multiple messages you want to publish to a broker, then disconnect with nothing else required.

    The two functions provided are single() and multiple().

    Both functions include support for MQTT v5.0, but do not currently let you set any properties on connection or when sending messages.

    Single

    Publish a single message to a broker, then disconnect cleanly.

    Example:

    import paho.mqtt.publish as publish
    
    publish.single("paho/test/topic", "payload", hostname="mqtt.eclipseprojects.io")
    

    Multiple

    Publish multiple messages to a broker, then disconnect cleanly.

    Example:

    from paho.mqtt.enums import MQTTProtocolVersion
    import paho.mqtt.publish as publish
    
    msgs = [{'topic':"paho/test/topic", 'payload':"multiple 1"},
     ("paho/test/topic", "multiple 2", 0, False)]
    publish.multiple(msgs, hostname="mqtt.eclipseprojects.io", protocol=MQTTProtocolVersion.MQTTv5)
    

    Subscribe

    This module provides some helper functions to allow straightforward subscribing and processing of messages.

    The two functions provided are simple() and callback().

    Both functions include support for MQTT v5.0, but do not currently let you set any properties on connection or when subscribing.

    Simple

    Subscribe to a set of topics and return the messages received. This is a blocking function.

    Example:

    import paho.mqtt.subscribe as subscribe
    
    msg = subscribe.simple("paho/test/topic", hostname="mqtt.eclipseprojects.io")
    print("%s %s" % (msg.topic, msg.payload))
    

    Using Callback

    Subscribe to a set of topics and process the messages received using a user provided callback.

    Example:

    import paho.mqtt.subscribe as subscribe
    
    def on_message_print(client, userdata, message):
     print("%s %s" % (message.topic, message.payload))
     userdata["message_count"] += 1
     if userdata["message_count"] >= 5:
     # it's possible to stop the program by disconnecting
     client.disconnect()
    
    subscribe.callback(on_message_print, "paho/test/topic", hostname="mqtt.eclipseprojects.io", userdata={"message_count": 0})
    

    Reporting bugs

    Please report bugs in the issues tracker at More information

    Discussion of the Paho clients takes place on the MQTT Google Group.

    There is much more information available via the /source-code-sync/paho.mqtt.python

README
未知许可证
查看未知开源许可协议
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/source-code-sync/paho.mqtt.python.git
git@gitee.com:source-code-sync/paho.mqtt.python.git
source-code-sync
paho.mqtt.python
paho.mqtt.python
master
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /