如何修复 AWS IOT 的重新连接代码

Posted

技术标签:

【中文标题】如何修复 AWS IOT 的重新连接代码【英文标题】:How do i fix my reconnect code for AWS IOT 【发布时间】:2021-12-31 03:59:27 【问题描述】:
import time
import paho.mqtt.client as paho
import os
import socket
import ssl

def on_connect(client, userdata, flags,rc):
    print("Connection returned result: " +str(rc) )
mqttc = paho.Client()
mqttc.on_connect = on_connect

awshost = "azl4495ut899m-ats.iot.us-east-2.amazonaws.com"
awsport = 8883
clientId = "myThingName"
thingName = "myThingName"
caPath = "/home/pi/AWSIoT/root-ca.pem"
certPath = "/home/pi/AWSIoT/certificate.pem.crt"
keyPath = "/home/pi/AWSIoT/private.pem.key"

mqttc.tls_set(caPath, certfile=certPath, 
keyfile=keyPath, 
cert_reqs=ssl.CERT_REQUIRED, 
tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)

mqttc.connect(awshost, awsport)
mqttc.loop_forever()
while True:
        if mqttc.connect(awshost, awsport)== 0:
            mqttc.connect(awshost, awsport)
            print("Connected")
            time.sleep(45)
            mqttc.disconnect(awshost,awsport)
            print("Disconnected")
        if mqttc.connect(awshost, awsport) != 0:
            mqttc.reconnect(awshost,awsport)
            print("reconnecting")

这是我失去互联网连接时的错误:

Traceback (most recent call last):
File "/home/pi/AWSIoT/awsiotcore2.1", line 
44, in <module>
if mqttc.connect(awshost, awsport) != 0:
File "/home/pi/.local/lib/python3.5/site-
packages/paho/mqtt/client.py", line 914, in 
connect
return self.reconnect()
File "/home/pi/.local/lib/python3.5/site-
packages/paho/mqtt/client.py", line 1044, 
in reconnect
sock = self._create_socket_connection()
File "/home/pi/.local/lib/python3.5/site-
packages/paho/mqtt/client.py", line 3685, 
in _create_socket_connection
return socket.create_connection(addr, 
timeout=self._connect_timeout, 
source_address=source)
File "/usr/lib/python3.5/socket.py", line 
694, in create_connection
for res in getaddrinfo(host, port, 0, 
SOCK_STREAM):
File "/usr/lib/python3.5/socket.py", line 
733, in getaddrinfo
for res in _socket.getaddrinfo(host, port, 
family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary 
failure in name resolution

如果我不添加带有断开连接的 while 循环,我将在 6 中失去与 AWS 的连接 分钟,并且必须手动重新连接。 这个循环是我能留下来的唯一方式 连接到 AWS。如果有人可以告诉我 为什么aws每6分钟断开一次我没有 愚蠢的断开循环请让我 知道

解决方案

while True:  
   mqttc.on_connect=on_connect
   print("Connected")
   time.sleep(45)
   mqttc.on_disconnect=on_disconnect
try:
    mqttc.connect(awshost,awsport)
except Exception:
    print("Error Connecting")
    pass

【问题讨论】:

请重新格式化您的代码(换行符的位置很重要)并显示无法正常工作的代码(目前看起来 mqttc.loop_forever() 由于while True: 将永远不会被调用所以你没有network loop)。显示的代码似乎每 45 秒手动断开一次? 是的,在底部我解释了为什么我手动断开连接 如果我完全去掉 while 循环,它可以工作,但只有 6 分钟,如果你能解决这个问题,那么我不需要 while 循环 看起来有一个open issue 用于此(或非常相似的问题)。问题是 here gaierrorOSError 所以没有被抓住。您可以用while True:try/catchmqttc.loop_forever() 包围起来,但可能还想看看DNS 查询失败的原因。 使用 try/catch 有效。 【参考方案1】:
while True:  
   mqttc.on_connect=on_connect
   print("Connected")
   time.sleep(45)
   mqttc.on_disconnect=on_disconnect
try:
   mqttc.connect(awshost,awsport)
 except Exception:
   print("Error Connecting")
   pass

【讨论】:

你还需要network loop。 它仍然通过该循环连接到网络。我需要添加什么? 'on_connect' 是否被调用? (这是在网络循环中完成的)。 connect 在网络连接启动但在处理来自 MQTT 代理的初始 CONNACK 之前返回。如果只是在 QOS0 上发布,您可能会侥幸逃脱,但仍有可能出现问题(例如未发送 keepalive)。 奇怪的是它连接了,但没有在函数中打印语句。我将在哪里添加循环?我会使用 loop.start() 还是 loop.forever() on_connect 仅在收到 CONNACK 数据包并在网络循环中进行处理时调用(如在此之前提到的 connect() 返回)。 loop_forever 很好 - 只要确保它在 try/catch 内(通常紧跟在 connect 之后)。

以上是关于如何修复 AWS IOT 的重新连接代码的主要内容,如果未能解决你的问题,请参考以下文章

如果AWS RDS恢复发生,如何重新连接

aws iot 使用 php sdk 订阅?

如何修复 AWS Glue 代码以显示来自 AWS S3 的分区表的计数和架构

每次设备连接并发送数据时,是不是使用带有 aws-iot (wss) 的自定义授权方创建一个新设备?

客户端重新加载页面时如何修复服务器故障?

如何修复AWS DMS到RDS的连接错误?