IoT Device Streaming не подключается - PullRequest
0 голосов
/ 28 мая 2020

Я изучаю функциональность Azure IoT Hub Device Streams .

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

IoT Hub - Device connected

Клиент использует следующий алгоритм для ожидания входящего соединения (с использованием 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, которая называется на указанной конечной точке c. Он получает строку подключения к Центру Интернета вещей

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

DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest("portal");

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

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

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

enter image description here

Вопрос

Почему мне не хватает того, что могло бы помешать Потоковая передача устройства IoT от подключения?

Ответы [ 2 ]

1 голос
/ 29 мая 2020

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

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

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

Шаг 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:

enter image description here

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

enter image description here

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

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

enter image description here

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

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

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

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

и тестер покажет устройство1 потоковую передачу: enter image description here

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

ОБНОВЛЕНИЕ:

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

* 10 89 *enter image description here

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

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

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

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

может быть установлена ​​потоковая связь через webSocket между устройством и сервисом через IoT Hub. Обратите внимание, что после этого смоделированное устройство выйдет из строя в случае использования клиентского инструмента REST.

0 голосов
/ 04 июня 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);

...