【问题标题】:Python MQTT connection to Azure Iot HubPython MQTT 连接到 Azure IoT 中心
【发布时间】:2016-09-17 00:25:04
【问题描述】:

我想使用 Python MQTT 连接到 Azure IoT Hub。

Iot Hub 需要用户名和 SAS 令牌。这是我的代码:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("$SYS/#")

def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.username_pw_set("myHub.azure-devices.net/device1", "mySASToken")

client.connect("myHub.azure-devices.net", 1883, 60)

client.loop_forever()

但是运行一段时间后,抛出了这个异常:

TimeoutError: [WinError 10060] 连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应

有人知道我为什么无法连接到 IoT 中心吗?

【问题讨论】:

标签: python azure mqtt azure-iot-hub


【解决方案1】:

现在有一个官方 Python SDK 可以将设备连接到 Azure IoT Hub: https://github.com/Azure/azure-iot-sdks/tree/master/python/device

This sample 演示如何使用 MQTT 协议进行连接。

基本上,它是这样工作的:

  1. 创建设备客户端并为协议指定 MQTT
  2. 设置收到消息时将调用的回调
  3. 使用 send_event_async 将消息发送到您的 Azure IoT 中心实例。
from iothub_client import *

def send_confirmation_callback(message, result, userContext):
    print "Confirmation[%d] received for message with result = %s" % (userContext, result)

def receive_message_callback(message, counter):
    buffer = message.get_bytearray()
    size = len(buffer)
    print "Received Message"
    print "    Data: <<<%s>>> & Size=%d" % (buffer[:size], size)
    return IoTHubMessageDispositionResult.ACCEPTED

iotHubClient = IoTHubClient(connectionString, IoTHubTransportProvider.MQTT)
iotHubClient.set_message_callback(receive_message_callback, 0)
iotHubClient.send_event_async(message, send_confirmation_callback, 0)

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • 感谢您的反馈。我添加了代码示例的要点。
【解决方案2】:

正如@FarukCelik 所说,没有适用于 Python 的 Azure IoT SDK。

但是,根据我的经验,我认为在 Python 中使用现有 SDK for Azure IoTHub 有四种可行的方法。

  1. 使用Azure IoT SDK for C扩展Python,可以尝试参考https://docs.python.org/2/extending/extending.html实现。
  2. 使用Azure IoT SDK for Java作为Jython包导入,可以尝试参考http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html了解如何操作。
  3. 与第二种方式类似,将 IronPython 与 Azure IoT SDK for C#/.Net 集成,请参考http://ironpython.net/documentation/dotnet/
  4. Azure IoT SDK for NodeJS 通过同一个Eclipse 项目Paho for JavaScript Client 支持MQTT,所以我想你可以尝试参考Azure NodeJS IoT SDK on GitHub 的源代码来了解如何正确使用paho Python client for Azure IoTHub。

同时,GitHub https://github.com/bechynsky/AzureIoTDeviceClientPY 上有一个用于 Azure IoTHub 设备的非官方 Python 库。您可以关注这个项目存储库,但它现在仍处于开发阶段。

希望对您有所帮助。最好的问候。

【讨论】:

  • 感谢您回复有用的答案。我去看看 Ironpython。
【解决方案3】:

以下是如何使用 paho (mosquitto) 通过标准 MQTT 连接到 Azure IoT Hub:

from paho.mqtt import client as mqtt


def on_connect(client, userdata, flags, rc):
    print "Connected with result code: %s" % rc
    client.subscribe("devices/<YOUR DEVICE ID>/messages/devicebound/#")


def on_disconnect(client, userdata, rc):
    print "Disconnected with result code: %s" % rc


def on_message(client, userdata, msg):
    print " - ".join((msg.topic, str(msg.payload)))
    # Do this only if you want to send a reply message every time you receive one
    client.publish("devices/<YOUR DEVICE ID>/messages/events", "REPLY", qos=1)


def on_publish(client, userdata, mid):
    print "Sent message"


client = mqtt.Client(cleint_id=<YOUR DEVICE ID>, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.on_publish = on_publish
client.username_pw_set(username="<YOUR NAMESPACE>.azure-devices.net/<YOUR DEVICE ID>",
                       password="<YOUR SHARED ACCESS SIGNATURE FOR THE DEVICE>")
client.tls_insecure_set(True) # You can also set the proper certificate using client.tls_set()
client.connect("<YOUR NAMESPACE>.azure-devices.net", port=8883)
client.loop_forever()

【讨论】:

    【解决方案4】:

    【讨论】:

    • 确实,目前还没有 Python SDK。但是应该可以通过 Python 直接使用 MQTT 协议将消息发送到 Iot Hub。