我想将设备消息(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 \ nTracking Id:fee6f860bdff42faa7cad8f81095223e-G:10-TimeStamp:04/19/2017 21:09:32
在属性Code的de exception中,值为: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”,但我找不到此错误的原因。 我确实看到了错误信息的设置位置,但我不明白为什么。
任何可以帮助我的人?
答案 0 :(得分:0)
我想将云设备消息(C2D)发送到设备......我想要 使用SAS令牌连接到期,而不是连接 使用设备的对称密钥
您无法使用设备级凭据发送Cloud-To-Device消息。您需要使用IoT中心级凭据。
因此,您需要删除/devices/{sasTokenModel.DeviceId}
Target
中的GetSasToken()
。最后的SAS-token will have this format:
SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
我无法重现您的问题。我在桌面上测试,操作系统版本是10.0.14393。
但我可以使用您的完整代码和纠正SAS令牌格式(之前提到的)成功发送Cloud-To-Device消息。你可以参考一下。