【问题标题】:InvalidErrorCode when sending C2D message through IoT Hub with SAS token使用 SAS 令牌通过 IoT 中心发送 C2D 消息时出现 InvalidErrorCode
【发布时间】:2017-09-16 03:52:06
【问题描述】:

我想向 IoTHub 中已知的设备发送云到设备消息 (C2D)。我在代码中使用 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跟踪 id:fee6f860bdff42faa7cad8f81095223e-G:10-TimeStamp:04/19/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 行

我在 de service 部分查看了 Github 存储库“azure-iot-sdk-csharp”,但找不到此错误的原因。 我确实看到了错误消息的设置位置,但我不明白为什么。

谁能帮帮我?

【问题讨论】:

  • 什么是平台和操作系统版本?
  • 我的示例用于 Windows 10 和 Visual Studio 2017。

标签: azure-iot-hub azure-iot-sdk


【解决方案1】:

我想向设备发送云到设备消息 (C2D)... 我想要 使用 SAS 令牌连接到期,而不是连接 使用设备的对称密钥

您无法使用设备级凭据发送云到设备消息。您需要使用 IoT 中心级别的凭据。

因此,您需要删除 Target 中的 /devices/{sasTokenModel.DeviceId} 中的 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 消息。可以参考一下。

【讨论】:

  • 谢谢。我知道我在某个地方想错了:)
  • Use-security-tokens-from-service-components 的段落有点混乱。它说:{iot hub 主机名}/devicebound --> 发送云到设备消息。 在发送遥测消息时在 uri 后面使用 /devicebounds 时,我得到 UnknownErrorCode。在发送直接方法时使用它时没有问题。对于发送遥测消息,只有 uri 可以正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 2022-08-23
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多