(重新)连接设备失败,并出现订阅异常

时间:2017-06-12 18:12:28

标签: java azure

我使用azure iot设备SDK(1.3.31)连接模拟设备。 对于某些设备我在拨打此电话时收到此异常:

//pseudo code    
deviceInfo.device = registryManager.getDevice(deviceId);
String deviceConnectionString = new StringBuilder()
                .append("HostName=").append(hubHostname)
                .append(";DeviceId=").append(device.getDeviceId())
                .append(";SharedAccessKey=").append(device.getPrimaryKey())
                .toString();

DeviceClient deviceClient = new DeviceClient(deviceConnectionString, IotHubClientProtocol.MQTT);

deviceClient.open();

起泡的例外:

java.io.IOException: Unable to subscribe to topic :devices/sim3_0001/messages/devicebound/# because java.io.EOFExceptionConnection lost
    at com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection.open(MqttIotHubConnection.java:142) ~[iot-device-client-1.2.30.jar:na]
    at com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttTransport.open(MqttTransport.java:83) ~[iot-device-client-1.2.30.jar:na]
    at com.microsoft.azure.sdk.iot.device.DeviceIO.open(DeviceIO.java:212) ~[iot-device-client-1.2.30.jar:na]
    at com.microsoft.azure.sdk.iot.device.DeviceClient.open(DeviceClient.java:188) ~[iot-device-client-1.2.30.jar:na]

我对库代码进行了一些挖掘,发现我的连接在订阅获得响应之前就被删除了;这是消耗并变成IOException的异常:

Connection lost (32109) - java.io.EOFException
    at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:146)
    at java.lang.Thread.run(Thread.java:745)
Lost connection to the server. Reconnecting 0 time.
Caused by: java.io.EOFException
    at java.io.DataInputStream.readByte(DataInputStream.java:267)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:65)
    at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:107)

另外,我联系了iothub-explorer,看看我是否有任何额外的有用信息。这就是我在公开电话中吐出的内容:

    body: 
  protocol:      Mqtt
  authType:      { "scope": "device", "type": "sas", "issuer": "iothub" }
  time:          2017-06-13T21:13:48.2406702Z
  operationName: deviceConnect
  category:      Connections
  level:         Information
  deviceId:      sim3_0001
  ipAddress:     xx.xx.xxx.XXX
enqueuedTimeUtc:       Tue Jun 13 2017 17:13:53 GMT-0400 (EDT)
offset:                355136
applicationProperties: 
  category:      Connections
  level:         Information
  operationName: deviceConnect
sequenceNumber:        705
annotations: 
  x-opt-sequence-number: 705
  x-opt-offset:          355136
  x-opt-enqueued-time:   Tue Jun 13 2017 17:13:53 GMT-0400 (EDT)
offset:                355536
enqueuedTimeUtc:       Tue Jun 13 2017 17:13:53 GMT-0400 (EDT)
body: 
  protocol:          Mqtt
  authType:          { "scope": "device", "type": "sas", "issuer": "iothub" }
  time:              2017-06-13T21:13:48.3656729Z
  operationName:     deviceDisconnect
  category:          Connections
  level:             Error
  statusCode:        404
  statusType:        404104
  statusDescription: DeviceConnectionClosedRemotely
  deviceId:          sim3_0001
  ipAddress:         xx.xx.xxx.XXX
annotations: 
  x-opt-sequence-number: 706
  x-opt-offset:          355536
  x-opt-enqueued-time:   Tue Jun 13 2017 17:13:53 GMT-0400 (EDT)
applicationProperties: 
  category:      Connections
  level:         Error
  operationName: deviceDisconnect
sequenceNumber:        706

另一个注意事项:新设备成功连接/订阅,似乎它们在重新连接时更经常失败。如果我将开放呼叫置于循环中并在1秒钟休眠后重试,则设备最终会成功连接。

2 个答案:

答案 0 :(得分:0)

根据您的错误信息java.io.IOException: Unable to subscribe to topic :devices/sim3_0001/messages/devicebound/# because java.io.EOFExceptionConnection lost,我认为您尝试通过使用devices/{device_id}/messages/devicebound/#作为主题过滤器进行订阅来接收云到设备的消息。 Migrating a device app from AMQP to MQTT&小节Azure官方文档Communicate with your IoT hub using the MQTT protocolReceiving cloud-to-device messages已解释了您的问题原因,如下所示。

  

接收云端设备消息

     

要从IoT Hub接收消息,设备应使用devices/{device_id}/messages/devicebound/#作为主题过滤器进行订阅。主题过滤器中的多级通配符 仅用于允许设备在主题名称中接收其他属性。 IoT Hub不允许使用 通配符来过滤子主题。由于IoT Hub不是通用的pub-sub消息传递代理,因此它仅支持记录的主题名称和主题过滤器。

对于Azure IoT Hub," MQTT不支持放弃/拒绝,因此我们只显示从IoTHub收到的消息并返回COMPLETE"。 GitHub上有一个官方sample code,您可以参考该代码来更改代码并使其与MQTT一起使用。

答案 1 :(得分:0)

对此的真正答案是,MQTT协议的azure iot集线器设备库仅允许每个应用程序一个连接。该库只创建一个MQTT连接,因此如果您创建第二个设备并尝试连接其中一个将被强行断开连接。