Наш пользовательский модуль IoTEdge работал правильно до недавнего времени, когда он начал терять соединение, при этом наш ConnectionStatusChangeHandler сообщал о состоянии «ConnectionStatus.Disconnected» и причинах «ConnectionStatusChangeReason.Retry_Expired» и ConnectionStatusChangeReason.Communication_Error".
Обработчик запускает повторную инициализацию клиента в соответствии с рекомендуемыми практиками, но потеря соединения является постоянной, нет периодических успешных подключений к концентратору, которые указывали бы на переходное состояние.
Мы проверили. Одна вещь, которая выделяется, это то, что двойник модуля EdgeHub устройства не указывает пользовательский модуль в разделе «клиенты» его сообщаемых свойств, что, по-видимому, связано с сбоем в работе. В списке указан только модуль IoTEdgeMetricsCollector, который подключен к IoTHub и работает нормально.
}, "clients": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z", "deviceId/IoTEdgeMetricsCollector": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z", "status": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z" }, "lastConnectedTimeUtc": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z" } } }
Похоже, что локальный модуль EdgeHub игнорирует наш пользовательский модуль.
К сожалению, мы не можем воспроизвести проблему. Мы не уверены, что это послужило причиной, но подозреваем, что случайное изменение было сохранено в двойнике модуля EdgeHub с помощью Azure IoT Explorer.
Что мы пробовали до сих пор:
Удален и повторно добавлен пользовательский модуль на устройство с портала Azure, а также посредством многоуровневого развертывания.
Перезагрузил шлюз, перезапустил системные модули, запустил «перезагрузку системы iotedge».
Развернул на устройстве модуль SimulatedTemperatureSensor; он правильно регистрируется на клиентах EdgeHub и правильно работает, поэтому новые модули, кроме нашего, кажутся незатронутыми.
Команда «iotedge check» возвращает зеленый цвет с парой предупреждений о версиях пакета, ошибок нет.
После перезапуска в журналах EdgeHub или EdgeAgent нет ошибок.
Пользовательский модуль успешно развернут, запускается и работает, но не может отправить данные телеметрии в нисходящий поток, поскольку любая попытка подключения к EdgeHub завершается неудачно с вышеупомянутыми ConnectionStatus и ConnectionStatusChangeReason.
HasStack="True" ThreadID="6,006" ProcessorNumber="0" thisOrContextObject="ErrorDelegatingHandler#34683734"memberName="ExecuteWithErrorHandlingAsync" message="Обнаружено исключение: System.Net.WebSockets.WebSocketException (0x80004005): невозможно подключиться к удаленному устройству server ---> System.Net.Http.HttpRequestException: не удалось установить SSL-соединение, см. внутреннее исключение ---> System.IO.IOException: получен неожиданный EOF или 0 байтов из транспортного потока в System. Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](адаптер TIOAdapter) в System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](адаптер TIOAdapter, логическое значение полученияFirst, Byte[] reAuthenticationData, логическое значение isApm) в System.Net.Http.ConnectHelper .EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream Stream, CancellationToken cancelToken) --- Конец внутренней трассировки стека исключений --- в System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, Запрос сообщения, логическая асинхронность, Поток потока, CancellationToken cancelToken) в System.Net.Http.HttpConnectionPool.ConnectAsync (запрос HttpRequestMessage, Boolean async, CancellationToken cancelToken) в System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync (запрос HttpRequestMessage, Boolean async, CancellationToken cancelToken) в System .Net .Http.HttpConnectionPool.AddHttp11ConnectionAsync(запрос HttpRequestMessage) в System.Threading.Tasks.TaskCompletionSourceWithCancellation
1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpIotTransport.CreateClientWebSocketAsync(Uri websocketUri, CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpIotTransport.CreateClientWebSocketTransportAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpIotTransport.InitializeAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpIotConnector.OpenConnectionAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpConnectionHolder.EnsureConnectionAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpConnectionHolder.OpenSessionAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpUnit.EnsureSessionIsOpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpUnit.OpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpTransportHandler.OpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.ProtocolRoutingDelegatingHandler.OpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.<>c__DisplayClass27_0.<<ExecuteWithErrorHandlingAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func1 asyncOperation)"
Мы думали полностью удалить и переустановить среду выполнения IoTEdge на устройстве, но нам хотелось бы исчерпать все другие варианты, прежде чем приступать к этому.
На данный момент у нас заканчиваются идеи о том, как решить эту проблему, мы будем благодарны за любую помощь.
Как указано в вопросе, мы использовали два способа развертывания наших модулей на устройстве: вручную с помощью функции «Установить модули» на портале Azure и посредством многоуровневого развертывания. Образ модуля уже создан и опубликован в нашем реестре контейнеров, доступ к которому осуществляется при ручном и многоуровневом развертывании. Похоже, проблема в том, что модуль EdgeHub на устройстве не регистрирует пользовательский модуль в качестве одного из своих клиентов. Мы ищем способ заставить это произойти без необходимости удалять и переустанавливать среду выполнения IoTEdge устройства.


Проблему, из-за которой ваш пользовательский модуль IoT Edge не может подключиться к IoT Hub из-за ошибок связи, можно решить, выполнив следующие шаги:
modulesContent, чтобы убедиться, что ваш пользовательский модуль указан правильно и нужные свойства правильно установлены.iotedge check, чтобы проверить конфигурацию развертывания.Я настроил среду разработки, создал модуль IoT Edge, обновил его с помощью специального кода, собрал и отправил модуль в реестр контейнеров и, наконец, развернул модуль на устройстве IoT Edge.
Ctrl+Shift+P) и запустите Azure IoT Edge: New IoT Edge Solution.
Выберите папку для создания решения и введите имя вашего решения.
Выберите шаблон модуля (например, C#, Node.js, Python) и введите имя вашего модуля.<registry_name>.azurecr.io/<module_name>
Обновите модуль с помощью пользовательского кода:
async Task<MessageResponse> FilterMessages(Message message, object userContext)
{
var counterValue = Interlocked.Increment(ref _counter);
try
{
var moduleClient = (ModuleClient)userContext;
var messageBytes = message.GetBytes();
var messageString = Encoding.UTF8.GetString(messageBytes);
Console.WriteLine($"Received message {counterValue}: [{messageString}]");
var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
{
Console.WriteLine($"Machine temperature {messageBody.machine.temperature} exceeds threshold {temperatureThreshold}");
using (var filteredMessage = new Message(messageBytes))
{
foreach (var prop in message.Properties)
{
filteredMessage.Properties.Add(prop.Key, prop.Value);
}
filteredMessage.Properties.Add("MessageType", "Alert");
await moduleClient.SendEventAsync("output1", filteredMessage);
}
}
return MessageResponse.Completed;
}
catch (Exception ex)
{
Console.WriteLine($"Error in sample: {ex.Message}");
return MessageResponse.Abandoned;
}
}
Обновите файл deployment.template.json: {
"modulesContent": {
"$edgeAgent": {
"properties.desired": {
"modules": {
"tempSensor": {
"type": "docker",
"settings": {
"image": "<registry_name>.azurecr.io/tempSensor:1.0",
"createOptions": "{}"
},
"env": {
"SimulatedData": {
"value": "true"
}
}
},
"filtermodule": {
"type": "docker",
"settings": {
"image": "<registry_name>.azurecr.io/filtermodule:0.0.1",
"createOptions": "{}"
}
}
}
}
},
"$edgeHub": {
"properties.desired": {
"routes": {
"sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/inputFromSensor\")",
"filtermoduleToIoTHub": "FROM /messages/modules/filtermodule/outputs/output1 INTO $upstream"
}
}
},
"filtermodule": {
"properties.desired": {
"TemperatureThreshold": 25
}
}
}
}
Щелкните правой кнопкой мыши файл deployment.template.json в обозревателе кода Visual Studio и выберите Build and Push IoT Edge Solution.
При этом образ Docker будет создан и отправлен в реестр контейнеров Azure.


Решено. Проблема возникла из-за ошибочного удаления базового развертывания, которое помещает системные модули на устройство, а затем последующего многоуровневого/ручного развертывания. Модули EdgeAgent и EdgeHub работали, но не видели новых развернутых пользовательских модулей. Как ни странно, EdgeHub с радостью зарегистрировал бы другие нестандартные модули с рынка, например, Имитированный датчик температуры. Восстановление базового размещения вернуло все в рабочее состояние.
Добавьте к приведенному выше вопросу ссылку, которую вы использовали для добавления модулей в Azure IoT Edge.