我正在考虑将 Azure IoT 中心用作工业生产交付的一部分。到目前为止,我遇到了大量的连接错误。在 1000 条消息中,我收到 35 个 InvalidStateErrors、16 个 ConnectionDroppedErrors 和 7 个由对等方重置的连接。我在一个高度可靠的有线以太网连接上,在同一时期没有 ICMP 数据包丢失。我的代码是否有问题,或者只是 Azure IoT 服务必须接受的问题?
Ping 输出
Ping output: no drops, 2.6 ms reply max
可靠性测试代码
import asyncio
import sys
from azure.iot.device.aio import IoTHubDeviceClient
# IoTHubDeviceClient reports errors to stderr. Using this class to grab and count them before printing
class Redirect_stderr:
stderr = sys.stderr
errors = {
"InvalidStateError": 0,
"ConnectionDroppedError": 0,
"Connection reset by peer": 0,
"Timeout": 0,
}
collect_errors = ""
def __enter__(self):
sys.stderr = self
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stderr = self.stderr
print(self.collect_errors, file=sys.stderr)
print(self.errors)
def write(self, text):
for error in self.errors.keys():
if error in text:
self.errors[error] += 1
self.collect_errors += text
self.stderr.write(text)
async def main():
with Redirect_stderr():
conn_str = "HostName=IoTHubForTest23.azure-devices.net;DeviceId=testDevice;SharedAccessKey=***redacted***"
client = IoTHubDeviceClient.create_from_connection_string(conn_str)
await client.connect()
for i in range(500):
try:
print(f"message count: {i}")
task = asyncio.create_task(client.send_message(f"Message {i}"))
await asyncio.sleep(1/2) # IoT Hub B1 has a message limit of four per second, making absolutely sure not to flood it
await asyncio.wait_for(task, 10-1/2) # In total, 5 second message timeout
except asyncio.TimeoutError:
print("Timeout", file=sys.stderr)
if __name__ == "__main__":
asyncio.run(main())
输出
{'InvalidStateError': 28, 'ConnectionDroppedError': 5, 'Connection reset by peer': 7}