Я хочу отправить сообщение «облако на устройство» (C2D) на устройство, известное в IoTHub. Я использую политику SERVICE в коде. Отправка происходит из консольного приложения (на данный момент) или более позднего WebApi. Так что код не запустится на устройстве!
Я хочу использовать SAS-токен для подключения с истечением срока действия вместо подключения с помощью симметричного ключа устройства. Я создал следующий код:
Вспомогательный класс:
..
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Common.Security;
..
public static class ServiceClientSasConnectionHelper
{
public static string GetSasConnectionString(SasTokenModel sasTokenModel)
{
var sasToken = GetSasToken(sasTokenModel);
var connectionString = string.Empty;
if (!string.IsNullOrEmpty(sasTokenModel.PolicyName))
connectionString = IotHubConnectionStringBuilder.Create(sasTokenModel.HostName, AuthenticationMethodFactory.CreateAuthenticationWithSharedAccessPolicyToken(sasTokenModel.PolicyName, sasToken)).ToString();
else
connectionString = $"HostName={sasTokenModel.HostName};DeviceId={sasTokenModel.DeviceId};SharedAccessSignature={sasToken}";
return connectionString;
}
private static string GetSasToken(SasTokenModel sasTokenModel)
{
var sasBuilder = new SharedAccessSignatureBuilder
{
Key = sasTokenModel.SigninKey,
Target = $"{sasTokenModel.HostName}/devices/{sasTokenModel.DeviceId}",
TimeToLive = TimeSpan.FromMinutes(sasTokenModel.TokenLifeTimeInMinutes)
};
var sasToken = sasBuilder.ToSignature();
if (!string.IsNullOrEmpty(sasTokenModel.PolicyName))
sasToken += $"&skn={sasTokenModel.PolicyName}";
return sasToken;
}
}
Вызывается из PROGRAM.CS:
var policyName = string.Empty;
policyName = ConfigHelper.GetPolicyName(); //service
var hostName = ConfigHelper.GetIotUri(); //companyname-Tenant2Display.azure-devices.net
var policyKey = ConfigHelper.GetPolicyKey(); // primarary key from Portal
var sasTokenModel = new SasTokenModel
{
DeviceId = WebUtility.UrlEncode(deviceKeyPair.Id), //DeviceId
SigninKey = string.IsNullOrEmpty(policyName) ? deviceKeyPair.Key : policyKey,
HostName = hostName,
PolicyName = policyName,
TokenLifeTimeInMinutes = 5
};
var connString = ServiceClientSasConnectionHelper.GetSasConnectionString(sasTokenModel);
var serviceClient = ServiceClient.CreateFromConnectionString(connString);
await serviceClient.SendAsync(deviceId, commandMessage);
При вызове SendAsync я получаю сообщение об ошибке со следующим сообщением:
\r\nИдентификатор отслеживания:fee6f860bdff42faa7cad8f81095223e-G:10-TimeStamp:19/04/2017 21:09:32
В исключении для свойства Code значение: Microsoft.Azure.Devices.Common.Exceptions.ErrorCode.InvalidErrorCode.
Трассировки стека:
в Microsoft.Azure.Devices.AmqpServiceClient.d__28.MoveNext() --- Конец трассировки стека из предыдущего места, где было выдано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(задача задачи) в System.Runtime. CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.GetResult() в TelemetrySender.Service.Sender.d__1.MoveNext() в C:\repo\TelemetrySender.cs:строка 34
Я заглянул в репозиторий Github "azure-iot-sdk-csharp" в разделе службы, но не могу найти причину этой ошибки. Я вижу, где установлено сообщение об ошибке, но я не понимаю, почему.
Любой, кто может мне помочь?