IoT Device Streaming не подключается

Я изучаю устройство концентратора Интернета вещей Azure Потоки.

У меня есть клиент C #, подключенный к Центру Интернета вещей (расположенный в центральной части США) и активный.

Центр Интернета вещей - Устройство подключено

Клиент использует следующий алгоритм ожидания входящего соединения (с использованием SDK версии 1.29.0-preview-004):

var buffer = new byte[1024];

using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));

DeviceStreamRequest streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token);

if (streamRequest is null)
    return;

На стороне сервера у меня есть служба приложений Azure, которая вызывается на определенной конечной точке. Он извлекает строку подключения к Центру Интернета вещей.

ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Constants.IoTHub.ConnectionString, TransportType.Amqp);

DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest("portal");

DeviceStreamResponse result = await serviceClient.CreateStreamAsync(serialNumber, deviceStreamRequest);

Я не могу установить соединение. Вызов CreateStreamAsync истекает через 1 минуту, и кажется, что клиентская сторона никогда не выходит из вызова WaitForDeviceStreamRequestAsync.

Я следил за руководство по устранению неполадок, чтобы выяснить, что происходит, но я ничего не получаю:

введите здесь описание изображения

Вопрос

Почему мне не хватает того, что может помешать подключению IoT Device Streaming?


person Kzrystof    schedule 28.05.2020    source источник


Ответы (2)


Обратите внимание, что функция потоков устройств Центра Интернета вещей Azure все еще находится в общедоступной предварительной версии (более одного года). Вы используете SDK 1.29.0-preview-004 на стороне устройства и 1.27.0-preview-004 на стороне службы и образец DeviceStreamingSample из пакета azure-iot-samples-csharp-master.

Потоки устройства используют для процесса установления связи между службой и устройством ту же концепцию связи, что и для вызова метода устройства. Эту фазу установления связи можно легко протестировать с помощью запроса REST POST.

В демонстрационных целях я буду использовать свой IoT Hub Tester, где реализована функция Device Streams, подробнее см. в разделе Приложение A2.

Шаг 1. Запустите программу DeviceClientStreamingSample для вашего устройства. Вам следует использовать Transport.Amqp. Обратите внимание, что остальные не прошли мой тест.

Шаг 2. Используйте клиентский инструмент REST для создания запроса POST. Следующий URL предназначен для моего теста:

https://xxxxxxxxxxx.azure-devices.net/twins/device1/streams/teststream?api-version=2018-08-30-preview

заголовки:

accept: application/json
iothub-streaming-response-timeout-in-seconds: 15
iothub-streaming-connect-timeout-in-seconds: 5
Authorization: sas-token

полезная нагрузка: любая или пустая

Следующий фрагмент экрана демонстрируется, когда POST был отправлен на устройство1:

введите здесь описание изображения

а в следующем фрагменте кода показана остановка программы в точке останова после метода WaitForDeviceStreamRequestAsync:

введите здесь описание изображения

Полное рукопожатие и потоковая передача между устройством и службой (в данном случае моим тестером) показаны в следующем фрагменте экрана:  введите описание изображения здесь

Как я уже упоминал, тестер Центра Интернета вещей Azure реализовал функцию потоков устройств, следующий фрагмент экрана показывает буфер потока:

введите здесь описание изображения

Обратите внимание, что запуск смоделированного устройства для TransportType.Mqtt не работает, симптом такой же, как у вас, тайм-аут. Похоже (на основе ответа REST POST) есть ошибка при подписке устройства на тему, например $ iothub / streams / POST / #

Однако, когда ваше устройство использует прямой протокол MQTT для IoT Hub, все работает нормально, см. Фрагмент экрана моего тестера, где device1 подключено к IoT Hub:  введите описание изображения  здесь

Когда на экране появится тестер Центра Интернета вещей Azure, вы можете использовать его для тестирования пакета SDK службы для потоковой передачи, например следующей строки из образца SDK:

DeviceStreamResponse result = await _serviceClient.CreateStreamAsync(_deviceId, deviceStreamRequest).ConfigureAwait(false);

и тестер покажет потоковую передачу device1:  введите описание изображения здесь

В заключение, на основании проведенного выше тестирования вы должны иметь успешную потоковую передачу с SDK, когда моделируемое устройство настроено для протокола TransportType.Amqp.

ОБНОВЛЕНИЕ:

В случае использования клиентского инструмента REST вы можете увидеть ответ от устройства в заголовках:

введите здесь описание изображения

Этот ответ генерируется следующей строкой:

await _deviceClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);

На основе заголовков ответа, таких как

iothub-streaming-is-accepted
iothub-streaming-url
iothub-streaming-auth-token

можно установить потоковую связь WebSocket между устройством и службой через Центр Интернета вещей. Обратите внимание, что после этого смоделированное устройство выйдет из строя в случае использования клиентского инструмента REST.

person Roman Kiss    schedule 29.05.2020

Проблема заключалась в экземпляре DeviceClient, который я использовал, который был построен на основе информации, поступающей от службы подготовки:

ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(Constants.IoTProvisioningService.GlobalDeviceEndpoint, Constants.IoTProvisioningService.IdScope, security, new ProvisioningTransportHandlerHttp());

var result = await provClient.RegisterAsync();

if (result.Status != ProvisioningRegistrationStatusType.Assigned)
    return;

var auth = new DeviceAuthenticationWithTpm(result.DeviceId, security);

--> DeviceClient deviceClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp);

Затем я использовал экземпляр DeviceClient для ожидания запроса:

var buffer = new byte[1024];

using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));

--> DeviceStreamRequest streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token);

Однако это не сработало.

Я понял, что в примерах (DeviceClientStreamingSample), что в строке подключения должен быть идентификатор устройства, которого у меня не было:

// String containing Hostname, Device Id & Device Key in one of the following formats:
//  "HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
//  "HostName=<iothub_host_name>;CredentialType=SharedAccessSignature;DeviceId=<device_id>;SharedAccessSignature=SharedAccessSignature sr=<iot_host>/devices/<device_id>&sig=<token>&se=<expiry_time>";

// For this sample either
// - pass this value as a command-prompt argument
// - set the IOTHUB_DEVICE_CONN_STRING environment variable 
// - create a launchSettings.json (see launchSettings.json.template) containing the variable
private static string s_deviceConnectionString = Environment.GetEnvironmentVariable("IOTHUB_DEVICE_CONN_STRING");

Поэтому я перестал повторно использовать экземпляр DeviceClient, который я получил от службы подготовки, и построил новый (код не готов к производству - это прототип):

var buffer = new byte[1024];

using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));

var deviceClient = DeviceClient.CreateFromConnectionString(Constants.IoTHub.ConnectionString + $";DeviceId={Constants.Unit.SerialNumber}", TransportType.Amqp);

DeviceStreamRequest streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token).ConfigureAwait(false);

if (streamRequest is null)
    return;

await deviceClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token);

person Kzrystof    schedule 04.06.2020