使用 M2MQTT Paho Python 客户端连接到 Azure IoT 中心
Connecting with M2MQTT Paho Python client to Azure IoT Hub
我正在使用以下代码尝试连接到 Azure IoT 中心。它使用 SAS,因此不需要安全证书。我在 C# 中使用相同的 M2MQTT 库成功连接到 Azure IoT Hub,但此代码失败:
未能connect.Connection拒绝,未授权。错误代码= 5
我尝试了所有可能的安全参数组合,但无济于事。 SAS 令牌由 DeviceExplorer 生成。
#! /usr/bin/python3.5
import serial
import time
import datetime
import os
import socket
import ssl
import logging
import paho.mqtt.client as mqtt
import sys
print(sys.executable)
def on_disconnect(client, userdata, rc):
if rc==0:
print("client disconnected OK")
client.connected_flag=False
def on_connect(client, userdata, flags, rc):
if rc==0:
print("Connected OK")
mqtt.Client.connected_flag=True
mqtt.Client.bad_connection_params=False
else:
mqtt.Client.bad_connection_params=True
if rc==1:
print("Failed to connect. Connection refused, unacceptable
protocol version. Error Code=", rc)
elif rc==2:
print("Failed to connect.Connection refused, identifier
rejected. Error Code=", rc)
elif rc==3:
print("Failed to connect.Connection refused, server unavailable. Error Code=", rc)
elif rc==4:
print("Failed to connect.Connection refused, bad user name or password. Error Code=", rc)
elif rc==5:
print("Failed to connect.Connection refused, not authorized. Error Code=", rc)
def on_publish(client, userdata, mid):
if rc==0:
print("Data published OK: ", userdata)
else:
print("Failed to publish data. MessageID=", mid)
pass
broker="myIoTHubName.azure-devices.net"
port=8883
DeviceID="MasterTag"
DeviceKey="myDeviceKey"
IoTHubName="myIoTHubName"
SasToken="SharedAccessSignature sr=myIoTHubName.azure-devices.net&sig=..."
# Create client object
# 4 stands for MQTTv311
rpiclient = mqtt.Client("PahoClient-on-RPi-Gateway2", clean_session=True, userdata=None, protocol=4, transport="tcp")
usernameFormat="{}{}{}"
username=usernameFormat.format(IoTHubName, ".azure-devices.net/", DeviceID)
password=SasToken
rpiclient.username_pw_set(username, password)
rpiclient.tls_set(tls_version=ssl.PROTOCOL_TLSv1_2)
rpiclient.tls_insecure_set(True)
# connection flag indicates that connection was made or not
mqtt.Client.connected_flag = False
# connection parameters are incorrect: ip address, port, authentication, etc
mqtt.Client.bad_connection_params=False
#assign function to callback
rpiclient.on_connect = on_connect
#assign function to callback
rpiclient.on_publish = on_publish
# bind the disconnect callback
rpiclient.on_disconnect = on_disconnect
rpiclient.loop_start()
rpiclient.will_set("dwm/position", "Client PahoClient-on-RPi2 had unexpectedly disconnected", 1, True)
try:
print("Connecting to MQTT broker ",broker)
# Connect to the MQTT Broker
rpiclient.connect(broker, port)
time.sleep(1)
# Wait in a loop until we are connected
print("mqtt.Client.connected_flag={},
mqtt.Client.bad_connection_params={}".format(mqtt.Client.connected_flag, mqtt.Client.bad_connection_params))
而 mqtt.Client.connected_flag == False 和 mqtt.Client.bad_connection_params == False:
打印("Waiting for connection...");
time.sleep(1)
如果 mqtt.Client.bad_connection_params == 真:
rpiclient.loop_stop()
sys.exit()
except Exception as ex:
print("Connection to MQTT Broker failed: ", ex)
rpiclient.loop_stop()
# Disconnect MQTT Client
rpiclient.disconnect()
如有任何建议,我们将不胜感激。
使用MQTT直接连接Azure IoT Hub时,需要通过TLS/SSL进行连接。为了建立 TLS 连接,您可能需要下载并引用 DigiCert 巴尔的摩根证书,然后为 TLS/SSL 连接设置证书。请参阅文档 Communicate with your IoT hub using the MQTT protocol.
client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.tls_insecure_set(False)
以下是模拟 device1 使用 paho.Mqtt 客户端库连接到 Azure IoT 中心的工作示例:
from paho.mqtt import client as mqtt
import time
import ssl
def on_subscribe(client, userdata, mid, granted_qos):
print('Subscribed for m' + str(mid))
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
def on_message(client, userdata, message):
print("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos))
def on_log(client, userdata, level, buf):
print("log: ",buf)
device_id = "device1"
iot_hub_name = "myIoTHub"
sas_token = "SharedAccessSignature sr=myIoTHub.azure-devices.net%2Fdevices%2Fdevice1&sig=****&se=1586926815"
client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311, clean_session=False)
client.on_log = on_log
client.tls_set_context(context=None)
# Set up client credentials
username = "{}.azure-devices.net/{}/api-version=2018-06-30".format(iot_hub_name, device_id)
client.username_pw_set(username=username, password=sas_token)
# Connect to the Azure IoT Hub
client.on_connect = on_connect
client.connect(iot_hub_name+".azure-devices.net", port=8883)
# Publish
client.publish("devices/{device_id}/messages/events/".format(device_id=device_id), payload="{}", qos=0, retain=False)
# Subscribing on the topic ,
client.on_message = on_message
client.on_subscribe = on_subscribe
client.subscribe("devices/{device_id}/messages/devicebound/#".format(device_id=device_id))
client.subscribe("$iothub/twin/PATCH/properties/desired/#")
client.subscribe("$iothub/methods/POST/#")
client.loop_forever()
更新:
可以使用 Device Explorer 工具生成特定设备的 sas_token,请参见以下屏幕片段:
输出日志应类似于以下屏幕片段:
我正在使用以下代码尝试连接到 Azure IoT 中心。它使用 SAS,因此不需要安全证书。我在 C# 中使用相同的 M2MQTT 库成功连接到 Azure IoT Hub,但此代码失败: 未能connect.Connection拒绝,未授权。错误代码= 5
我尝试了所有可能的安全参数组合,但无济于事。 SAS 令牌由 DeviceExplorer 生成。
#! /usr/bin/python3.5
import serial
import time
import datetime
import os
import socket
import ssl
import logging
import paho.mqtt.client as mqtt
import sys
print(sys.executable)
def on_disconnect(client, userdata, rc):
if rc==0:
print("client disconnected OK")
client.connected_flag=False
def on_connect(client, userdata, flags, rc):
if rc==0:
print("Connected OK")
mqtt.Client.connected_flag=True
mqtt.Client.bad_connection_params=False
else:
mqtt.Client.bad_connection_params=True
if rc==1:
print("Failed to connect. Connection refused, unacceptable
protocol version. Error Code=", rc)
elif rc==2:
print("Failed to connect.Connection refused, identifier
rejected. Error Code=", rc)
elif rc==3:
print("Failed to connect.Connection refused, server unavailable. Error Code=", rc)
elif rc==4:
print("Failed to connect.Connection refused, bad user name or password. Error Code=", rc)
elif rc==5:
print("Failed to connect.Connection refused, not authorized. Error Code=", rc)
def on_publish(client, userdata, mid):
if rc==0:
print("Data published OK: ", userdata)
else:
print("Failed to publish data. MessageID=", mid)
pass
broker="myIoTHubName.azure-devices.net"
port=8883
DeviceID="MasterTag"
DeviceKey="myDeviceKey"
IoTHubName="myIoTHubName"
SasToken="SharedAccessSignature sr=myIoTHubName.azure-devices.net&sig=..."
# Create client object
# 4 stands for MQTTv311
rpiclient = mqtt.Client("PahoClient-on-RPi-Gateway2", clean_session=True, userdata=None, protocol=4, transport="tcp")
usernameFormat="{}{}{}"
username=usernameFormat.format(IoTHubName, ".azure-devices.net/", DeviceID)
password=SasToken
rpiclient.username_pw_set(username, password)
rpiclient.tls_set(tls_version=ssl.PROTOCOL_TLSv1_2)
rpiclient.tls_insecure_set(True)
# connection flag indicates that connection was made or not
mqtt.Client.connected_flag = False
# connection parameters are incorrect: ip address, port, authentication, etc
mqtt.Client.bad_connection_params=False
#assign function to callback
rpiclient.on_connect = on_connect
#assign function to callback
rpiclient.on_publish = on_publish
# bind the disconnect callback
rpiclient.on_disconnect = on_disconnect
rpiclient.loop_start()
rpiclient.will_set("dwm/position", "Client PahoClient-on-RPi2 had unexpectedly disconnected", 1, True)
try:
print("Connecting to MQTT broker ",broker)
# Connect to the MQTT Broker
rpiclient.connect(broker, port)
time.sleep(1)
# Wait in a loop until we are connected
print("mqtt.Client.connected_flag={},
mqtt.Client.bad_connection_params={}".format(mqtt.Client.connected_flag, mqtt.Client.bad_connection_params)) 而 mqtt.Client.connected_flag == False 和 mqtt.Client.bad_connection_params == False: 打印("Waiting for connection..."); time.sleep(1) 如果 mqtt.Client.bad_connection_params == 真: rpiclient.loop_stop() sys.exit()
except Exception as ex:
print("Connection to MQTT Broker failed: ", ex)
rpiclient.loop_stop()
# Disconnect MQTT Client
rpiclient.disconnect()
如有任何建议,我们将不胜感激。
使用MQTT直接连接Azure IoT Hub时,需要通过TLS/SSL进行连接。为了建立 TLS 连接,您可能需要下载并引用 DigiCert 巴尔的摩根证书,然后为 TLS/SSL 连接设置证书。请参阅文档 Communicate with your IoT hub using the MQTT protocol.
client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.tls_insecure_set(False)
以下是模拟 device1 使用 paho.Mqtt 客户端库连接到 Azure IoT 中心的工作示例:
from paho.mqtt import client as mqtt
import time
import ssl
def on_subscribe(client, userdata, mid, granted_qos):
print('Subscribed for m' + str(mid))
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
def on_message(client, userdata, message):
print("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos))
def on_log(client, userdata, level, buf):
print("log: ",buf)
device_id = "device1"
iot_hub_name = "myIoTHub"
sas_token = "SharedAccessSignature sr=myIoTHub.azure-devices.net%2Fdevices%2Fdevice1&sig=****&se=1586926815"
client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311, clean_session=False)
client.on_log = on_log
client.tls_set_context(context=None)
# Set up client credentials
username = "{}.azure-devices.net/{}/api-version=2018-06-30".format(iot_hub_name, device_id)
client.username_pw_set(username=username, password=sas_token)
# Connect to the Azure IoT Hub
client.on_connect = on_connect
client.connect(iot_hub_name+".azure-devices.net", port=8883)
# Publish
client.publish("devices/{device_id}/messages/events/".format(device_id=device_id), payload="{}", qos=0, retain=False)
# Subscribing on the topic ,
client.on_message = on_message
client.on_subscribe = on_subscribe
client.subscribe("devices/{device_id}/messages/devicebound/#".format(device_id=device_id))
client.subscribe("$iothub/twin/PATCH/properties/desired/#")
client.subscribe("$iothub/methods/POST/#")
client.loop_forever()
更新:
可以使用 Device Explorer 工具生成特定设备的 sas_token,请参见以下屏幕片段:
输出日志应类似于以下屏幕片段: