无法使用Pythonpaho.mqtt.python库通过MQTT协议连接到AmazonMQ

问题描述

import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt

USERNAME = "admin-user"
PASSWORD = "admin-user@12345"
AUTH = {"username":USERNAME,"password":PASSWORD}
HOSTNAME = "ssl://b-c7d1ea8g-f777-4c71-23a3-2d73088fdb64-1.mq.us-west-2.amazonaws.com"
PORT = 8883
TOPICNAME = "paho/test/single"
PAYLOAD = "Hope Stackoverflow Help Me Resolve This Issue!"

publish.single(TOPICNAME,payload=PAYLOAD,hostname=HOSTNAME,port=PORT,auth=AUTH,protocol=mqtt.MQTTv311,transport="tcp",client_id="",keepalive=60,will=None) # This won't work
# publish.single(TOPICNAME,hostname="localhost") # This works!

print('published message payload = ',PAYLOAD)

我能够使用Java eclipse Paho客户端连接到AmazonMQ,但无法在Python中做到这一点。它给我一个错误 gaierror:[Errno -2]名称或服务未知”。

上面的python代码与本地托管的ActiveMQ MQTT代理以及在我托管ActiveMQ MQTT代理的独立服务器中均能正常工作。但是对于AmazonMQ经纪人来说,这是不起作用的。

Github Paho的问题跟踪工具中已经提到了此问题,但是仍然没有解决方案可以帮助您。

解决方法

您需要从主机变量中删除“ ssl://”,并设置一个ssl上下文,以便使用paho连接到Amazon-MQ。

context = ssl.create_default_context()
client.tls_set_context(context=context)

这是在github问题上发布的示例的有效版本。

import paho.mqtt.client as mqttClient

import time
import ssl

context = ssl.create_default_context()

Connected = False 
broker_address= "b-xxxxxx-acbf-xxxx-xxxx-xxxxx-1.mq.us-east-1.amazonaws.com" # No ssl://
port = 8883
user = "xxxxxx"
password = "xxxxx"

def on_connect(client,userdata,flags,rc):

    if rc == 0:
        print("Connected to broker")
        global Connected                #Use global variable
        Connected = True                #Signal connection  
        client.subscribe("test/data")
    else:
        print("Connection failed")

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

client = mqttClient.Client("Test") #create new instance
client.username_pw_set(user,password=password) #set username and password
client.on_connect=on_connect
client.on_message=on_message
client.tls_set_context(context=context)
client.connect(broker_address,port=port)
client.loop_start()

while Connected != True:
    time.sleep(0.1)

client.publish("test/data","This is my test msg 123.")
time.sleep(10)