我正在尝试接收"通知"当一些数据发布到MQTT主题devices/device_id/messages/events/
时,来自IoT Hub。要接收数据,我使用以下主题:devices/device_id/messages/devicebound/
。我的订阅代码如下(Python):
import paho.mqtt.client as mqtt
import ssl, random
from time import sleep
root_ca = "./certs/digicertbaltimoreroot.pem"
public_crt = './certs/rsa_cert.pem'
private_key = './certs/rsa_private.pem'
iothub_name = "myhub"
device_id = "mydevice"
mqtt_url = "{}.azure-devices.net".format(iothub_name)
mqtt_port = 8883
topic = "devices/{}/messages/devicebound/#".format(device_id)
def error_str(rc):
return "Some error occurred. {}: {}".format(rc, mqtt.error_string(rc))
def on_disconnect(unused_client, unused_userdata, rc):
print("on_disconnect", error_str(rc))
def on_connect(client, userdata, flags, response_code):
print("Connected with status: {0}".format(response_code))
client.subscribe(topic, 1)
def on_subscribe(client, userdata, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_message(client, userdata, msg):
print("Topic: {0} -- Payload: {1}".format(msg.topic, str(msg.payload)))
if __name__ == "__main__":
client = mqtt.Client(device_id, protocol=mqtt.MQTTv311)
client.tls_set(root_ca,
certfile = public_crt,
keyfile = private_key,
cert_reqs = ssl.CERT_REQUIRED,
tls_version = ssl.PROTOCOL_TLSv1_2,
ciphers = None)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
print("Connecting to Azure IoT Hub...")
client.connect(mqtt_url, mqtt_port, keepalive=60)
client.loop_forever()
当我跑步时,我得到以下输出:
连接到Azure IoT Hub ...
连接状态:3
(' on_disconnect','发生了一些错误.5:连接被拒绝。')
连接状态:3
(' on_disconnect','发生了一些错误.5:连接遭到拒绝。')
任何人都可以建议我缺少什么吗?
答案 0 :(得分:1)
根据文档"Using the MQTT protocol directly",您需要
下载并参考DigiCert Baltimore Root Certificate。此证书是Azure用于保护连接的证书。
正如您在发布过程中所做的那样:
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.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=sas_token)
最后,您可以订阅,如下所示:
client.subscribe(topic=topic, qos=0)
安全密钥验证设备的示例代码:
import paho.mqtt.client as mqtt
import ssl, random
from time import sleep
path_to_root_cert = "./certs/digicertbaltimoreroot.cer"
iothub_name = "your hub name"
device_id = "device1"
sas_token = "SharedAccessSignature sr=[your hub name].azure-devices.net%2Fdevices%2Fdevice1&sig=[sig]&se=1526955728"
mqtt_url = "{}.azure-devices.net".format(iothub_name)
mqtt_port = 8883
topic = "devices/{}/messages/devicebound/#".format(device_id)
def error_str(rc):
return "Some error occurred. {}: {}".format(rc, mqtt.error_string(rc))
def on_disconnect(unused_client, unused_userdata, rc):
print("on_disconnect", error_str(rc))
def on_connect(client, userdata, flags, response_code):
print("Connected with status: {0}".format(response_code))
client.subscribe(topic, 1)
def on_subscribe(client, userdata, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_message(client, userdata, msg):
print("Topic: {0} -- Payload: {1}".format(msg.topic, str(msg.payload)))
if __name__ == "__main__":
client = mqtt.Client(device_id, protocol=mqtt.MQTTv311)
client.username_pw_set(username=iothub_name+".azure-devices.net/" + device_id, password=sas_token)
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.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
print("Connecting to Azure IoT Hub...")
client.connect(mqtt_url, mqtt_port, keepalive=60)
client.subscribe(topic=topic, qos=0)
client.loop_forever()
x509经过身份验证的设备的示例代码: (需要提供设备证书和私钥文件。不需要SAS令牌作为密码;只需将其留空。但仍需要设置用户名。)
import paho.mqtt.client as mqtt
import ssl, random
from time import sleep
root_ca = "./certs/digicertbaltimoreroot.cer"
public_crt = './certs/mydevice-public.pem'
private_key = './certs/mydevice-private.pem'
iothub_name = "your hub name"
device_id = "mydevice"
mqtt_url = "{}.azure-devices.net".format(iothub_name)
mqtt_port = 8883
topic = "devices/{}/messages/devicebound/#".format(device_id)
def error_str(rc):
return "Some error occurred. {}: {}".format(rc, mqtt.error_string(rc))
def on_disconnect(unused_client, unused_userdata, rc):
print("on_disconnect", error_str(rc))
def on_connect(client, userdata, flags, response_code):
print("Connected with status: {0}".format(response_code))
client.subscribe(topic, 1)
def on_subscribe(client, userdata, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_message(client, userdata, msg):
print("Topic: {0} -- Payload: {1}".format(msg.topic, str(msg.payload)))
if __name__ == "__main__":
client = mqtt.Client(device_id, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
client.username_pw_set(username=iothub_name+".azure-devices.net/" + device_id, password="")
client.tls_set(root_ca,
certfile = public_crt,
keyfile = private_key,
cert_reqs = ssl.CERT_REQUIRED,
tls_version = ssl.PROTOCOL_TLSv1_2,
ciphers = None)
client.tls_insecure_set(False)
print("Connecting to Azure IoT Hub...")
client.connect(mqtt_url, mqtt_port, keepalive=60)
client.subscribe(topic=topic, qos=0)
client.loop_forever()
注意:主题为" devices / {device-id} / messages / devicebound / #"。
如何创建设备证书文件,您可以参考here。
更新:这些示例代码用于接收您可以发送的D2C messages,以便进行简单测试:
来自azure portal:
Upate:接收D2C消息:
正如我在评论中指出的,Azure IoT Hub不是通用的MQTT brober,因此您无法直接订阅从设备发送的消息。 要解决此问题,您可以使用IoT Hub公开的与事件中心兼容的端点,例如" Read the telemetry from your hub "部分呢。但不幸的是,Python并不支持这种方式。您可以使用iothub-explorer CLI实用程序或创建基于Node.js或.NET或Java事件集线器的控制台应用程序来读取来自IoT Hub的设备到云消息。
答案 1 :(得分:0)
由于丽塔已经提到当前在设备端不支持D2C消息。
Azure IoT中心是物联网解决方案中的云门方式,如下图所示:
Azure IoT中心根据endpoints为支持的解决方案和设备端提供服务。目前,它提供device to cloud feature类 D2C消息, Device Twin的报告属性和文件上传。从云端,我们可以使用cloud to device feature直接方法, Twin的所需属性和云端设备消息。
当我将一些数据发布到MQTT主题设备/ device_id / messages / events /
时,我试图从IoT Hub接收“通知”
这取决于您希望接收消息的那一方。目前,Azure IoT中心支持两种方案。
在设备端发送Device-to-Cloud消息,并在云后端解决方案上接收消息(D2C消息仅支持AMQP协议)
在云后端解决方案上发送可以设备的消息,并在设备端接收消息。
如果您对Azure IoT Hub有任何想法或反馈,可以通过Azure IoT Hub - user voice提交。