Azure IoT中心-“订阅"代码不起作用:“连接被拒绝"; [英] Azure IoT Hub - "Subscribe" code not working: "connection was refused"

查看:237
本文介绍了Azure IoT中心-“订阅"代码不起作用:“连接被拒绝";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一些数据发布到MQTT主题devices/device_id/messages/events/时,我试图从IoT中心接收通知".为了接收数据,我使用以下主题:devices/device_id/messages/devicebound/.我的订阅代码如下(Python):

I am trying to receive "notifications" from IoT Hub when some data is published to the MQTT topic devices/device_id/messages/events/. To receive data, I am using the following topic: devices/device_id/messages/devicebound/. My subscribe code is below (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()

运行时,我得到以下输出:

When I run, I am getting the following output:

连接到Azure IoT中心...
关联状态:3
("on_disconnect",发生某些错误.5:连接被拒绝.")
关联状态:3
("on_disconnect",发生某些错误.5:连接被拒绝.")

Connecting to Azure IoT Hub...
Connected with status: 3
('on_disconnect', 'Some error occurred. 5: The connection was refused.')
Connected with status: 3
('on_disconnect', 'Some error occurred. 5: The connection was refused.')

任何人都可以建议我所缺少的吗?

Can anyone suggest what I am missing?

推荐答案

基于文档,您需要

下载并参考DigiCert巴尔的摩根证书.该证书是Azure用于保护连接的证书.

to download and reference the DigiCert Baltimore Root Certificate. This certificate is the one that Azure uses to secure the connection.

就像您在发布过程中所做的那样:

As you did in the publishing process like this:

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令牌作为密码;只需将其保留为空即可.但仍需要设置用户名.)

Sample code for x509 authenticated device: (Need provide device certificate and private key files. No need SAS token as password; just leave it empty. But still need set username.)

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()

注意:主题为设备/{device-id}/消息/设备绑定/#".

Note: The topic is "devices/{device-id}/messages/devicebound/#".

如何创建设备证书文件,您可以参考

How to create device certificate files you can reference here.

更新:这些示例代码用于接收

Update: These sample code used to receive D2C messages that you can send like this for simple test:

来自设备浏览器 :

从azure门户网站:

From azure portal:

更新::接收D2C消息:

正如我在评论中所指出的那样,Azure IoT Hub不是通用的MQTT强盗,因此您不能直接订阅从设备发送的消息. 要解决此问题,您可以使用物联网中心公开的事件中心兼容的终结点,例如"

As I pointed out in my comments, Azure IoT Hub is not generic MQTT brober, so you can't directly subscribe messages sent from the device. To workaround it, you can use the Event Hubs-compatible endpoint exposed by the IoT Hub like "Read the telemetry from your hub " part does. But unfortunately, Python doesn't support this way. You can use the iothub-explorer CLI utility or either create a Node.js or a .NET or Java event hub-based console app to read the device-to-cloud messages from IoT Hub.

这篇关于Azure IoT中心-“订阅"代码不起作用:“连接被拒绝";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆