使用 Java Paho 连接到 Azure IoT 中心

Connect to Azure IoT Hub with Java Paho

我们已经启动了一个 PoC,通过 MQTT 将我们现有的一些代码连接到 Azure 物联网中心,以测试 Azure 对标准协议和工具的支持。我们正在使用 Paho 客户端,但得到的是 return 代码为 5 – 未授权的 CONNACK。

我们按照 instructions on how to setup an IoT Hub and created one using the F1 (free) scale tier. We then followed another Azure document 下载了 Device Explorer,创建了一个设备并生成了一个 SAS 令牌。然后我们将所有内容插入 Paho:

public static void main( String[] args ) {
  String deviceId = "device-fcbd127a";
  String sasToken = "SharedAccessSignature sr=CoyoteIoT.azure-devices.net%2fdevices%2fdevice-fcbd127a&sig=3acRHQXXXXXXXXXXX‌​Zg%3d&se=1468067737";
  String brokerUri = "ssl://CoyoteIoT.azure-devices.net:8883";
  String clientId = deviceId;
  System.out.println( "Connecting to " + brokerUri +" as "+clientId);

  MqttAsyncClient client = null;
  try {
    client = new MqttAsyncClient( brokerUri, clientId );
    if ( client != null ) {
      MqttConnectOptions options = new MqttConnectOptions();
      client.setCallback( new AzureCallback() );
      options.setUserName( "CoyoteIoT.azure-devices.net/device-fcbd127a"     );
      options.setPassword( sasToken.toCharArray() );
      IMqttToken token = client.connect( options );
      token.waitForCompletion( 5000 );
      if ( client.isConnected() ) {
        System.out.println( "Success!" );
      } else {
        System.out.println( "Could not connect to Azure IoT hub, timed-out" );
      }
    }
  } catch ( MqttException e ) {
    client.getDebug().dumpBaseDebug();
    e.printStackTrace();
  } finally {
    if ( client != null ) {
      try {
        client.disconnect();
      } catch ( MqttException ignore ) {}
    }
  }
}

我们已通过 Wireshark 确认与 Azure 建立了 SSL 连接并发送了 CONNECT 数据包。然后,我们看到带有 return 代码 5 的 CONNACK 被发送到 Paho,而 Azure 很快就断开了连接。然后我们研究了“共享访问策略”并尝试了不同的设置。审计日志中没有任何内容,我们为所有内容都打开了“详细”。

有人将 Paho(或其他第三方 Java 客户端)连接到 Azure 物联网中心吗?

我们在哪里可以找到任何诊断信息以便我们自己进行故障排除?

附带说明一下,我们搁置了这种 (MQTT) 方法,并尝试通过 ReST 服务进行连接,并收到更加模糊的“500-内部服务器错误”作为响应。这使我们认为这里存在更基本的访问问题。 F1 scale hub 是否只支持 Microsoft SDK?是否缺少一些隐藏的访问控制设置?名称格式是否严格,不允许某些字符或大小写?

您的 SAS 令牌看起来有点不正常。

"SharedAccessSignature=Share[snipped]%3d&se=1468067737"

对比文档中有什么:

"SharedAccessSignature sr=iothubname.azure-devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501"

,包括空格。

参见:https://github.com/Azure/azure-content/blob/master/articles/iot-hub/iot-hub-devguide.md#example

我在为输入密码苦苦挣扎了半天后发布了那个 PR,我向你保证它会成功:)

@SCote,我的建议是Java的设备可以参考Azure IoTHub SDK的源码MqttIotHubConnection.java,也是基于Paho

我查看了代码,然后在第 346 行发现 UserName at the 128 line and set up all properties in the function updateConnectionOptions 的差异。

String clientIdentifier = "DeviceClientType=" + URLEncoder.encode(TransportUtils.javaDeviceClientIdentifier + TransportUtils.clientVersion, "UTF-8");
this.iotHubUserName = this.config.getIotHubHostname() + "/" + this.config.getDeviceId() + "/" + clientIdentifier;

所以我觉得你可以尝试按照官方的实现重写你的部分代码

希望对解决您的问题有所帮助。

我尝试使用您在代码中指定的凭据从 Paho GUI 客户端(我已经验证已经使用我的凭据连接到 azure - 有效!!)进行连接。我最终收到一条显示 "org.eclipse.paho.client.mqttv3.MqttException: Connection lost" 的错误消息。我希望,您没有删除或修改您的凭据的任何部分。尝试使用此 paho GUI 应用程序验证您的凭据。

Paho GUI Client.

显然我们在使用 Device Explorer 实用程序时遇到了问题。它没有生成有效期为 365 天的 SAS 令牌,而是生成了一个有效期仅为 365 秒的令牌。

注意 SAS 令牌中的 se=1468067737,它的计算结果为 2016 年美国东部时间 7 月 9 日 08:35:37 到期,远远超过了我们的测试执行。