我正在尝试编写用于Azure IoT Edge运行时的自定义Java模块。我正在关注Tutorial: Develop a Java IoT Edge module and deploy to your simulated device
我有64位Ubuntu 18.04计算机,并按照Install the Azure IoT Edge runtime on Linux (x64)
安装了Azure IoT Edge运行时我已经使用Visual Studio代码工具编写了SampleJavaModule。我正在使用IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
MQTT作为通信协议。我的SamplejavaModule
已安装在Linux机器上,但是在3-4分钟后就退出了。
当我运行sudo iotedge list
时,它会显示以下输出
SampleJavaModule failed Failed (1) 2 minutes ago mycontainerregistry.azurecr.io/samplejavamodule:0.0.1-amd64
edgeAgent running Up 40 minutes mcr.microsoft.com/azureiotedge-agent:1.0
edgeHub running Up 40 minutes mcr.microsoft.com/azureiotedge-hub:1.0
tempSensor running Up 15 minutes mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0
下面是错误日志
java.io.IOException: Could not open the connection
at com.microsoft.azure.sdk.iot.device.DeviceIO.open(DeviceIO.java:164)
at com.microsoft.azure.sdk.iot.device.InternalClient.open(InternalClient.java:130)
at com.edgemodule.App.main(App.java:126)
Caused by: com.microsoft.azure.sdk.iot.device.exceptions.ProtocolException: Unable to establish MQTT connection
at com.microsoft.azure.sdk.iot.device.transport.mqtt.exceptions.PahoExceptionTranslator.convertToMqttException(PahoExceptionTranslator.java:40)
at com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt.connect(Mqtt.java:119)
at com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttMessaging.start(MqttMessaging.java:56)
at com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection.open(MqttIotHubConnection.java:179)
at com.microsoft.azure.sdk.iot.device.transport.IotHubTransport.openConnection(IotHubTransport.java:640)
at com.microsoft.azure.sdk.iot.device.transport.IotHubTransport.open(IotHubTransport.java:277)
at com.microsoft.azure.sdk.iot.device.DeviceIO.open(DeviceIO.java:160)
... 2 more
Caused by: MqttException (0) - java.net.SocketTimeoutException: connect timed out
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:715)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:80)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:103)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:701)
请建议我如何使其工作。
谢谢。
更新:模块代码
package com.edgemodule;
import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.transport.IotHubConnectionStatus;
import java.io.StringReader;
import java.util.concurrent.atomic.AtomicLong;
import java.util.HashMap;
import java.util.Map;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.Pair;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.Property;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.TwinPropertyCallBack;
public class App {
private static final String TEMP_THRESHOLD = "TemperatureThreshold";
private static AtomicLong tempThreshold = new AtomicLong(25);
private static MessageCallbackMqtt msgCallback = new MessageCallbackMqtt();
private static EventCallback eventCallback = new EventCallback();
private static final String INPUT_NAME = "input1";
private static final String OUTPUT_NAME = "output1";
protected static class EventCallback implements IotHubEventCallback {
@Override
public void execute(IotHubStatusCode status, Object context) {
if (context instanceof Message) {
System.out.println("Send message with status: " + status.name());
} else {
System.out.println("Invalid context passed");
}
}
}
protected static class MessageCallbackMqtt implements MessageCallback {
private int counter = 0;
@Override
public IotHubMessageResult execute(Message msg, Object context) {
this.counter += 1;
String msgString = new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET);
System.out.println(
String.format("Received message %d: %s",
this.counter, msgString));
if (context instanceof ModuleClient) {
try (JsonReader jsonReader = Json.createReader(new StringReader(msgString))) {
final JsonObject msgObject = jsonReader.readObject();
double temperature = msgObject.getJsonObject("machine").getJsonNumber("temperature").doubleValue();
long threshold = App.tempThreshold.get();
if (temperature >= threshold) {
ModuleClient client = (ModuleClient) context;
System.out.println(
String.format("Temperature above threshold %d. Sending message: %s",
threshold, msgString));
client.sendEventAsync(msg, eventCallback, msg, App.OUTPUT_NAME);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return IotHubMessageResult.COMPLETE;
}
}
protected static class ConnectionStatusChangeCallback implements IotHubConnectionStatusChangeCallback {
@Override
public void execute(IotHubConnectionStatus status,
IotHubConnectionStatusChangeReason statusChangeReason,
Throwable throwable, Object callbackContext) {
String statusStr = "Connection Status: %s";
switch (status) {
case CONNECTED:
System.out.println(String.format(statusStr, "Connected"));
break;
case DISCONNECTED:
System.out.println(String.format(statusStr, "Disconnected"));
if (throwable != null) {
throwable.printStackTrace();
}
System.exit(1);
break;
case DISCONNECTED_RETRYING:
System.out.println(String.format(statusStr, "Retrying"));
break;
default:
break;
}
}
}
protected static class DeviceTwinStatusCallBack implements IotHubEventCallback {
@Override
public void execute(IotHubStatusCode status, Object context) {
System.out.println("IoT Hub responded to device twin operation with status " + status.name());
}
}
protected static class OnProperty implements TwinPropertyCallBack {
@Override
public void TwinPropertyCallBack(Property property, Object context) {
if (!property.getIsReported()) {
if (property.getKey().equals(App.TEMP_THRESHOLD)) {
try {
long threshold = Math.round((double) property.getValue());
App.tempThreshold.set(threshold);
} catch (Exception e) {
System.out.println("Faile to set TemperatureThread with exception");
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
try {
IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
System.out.println("Start to create client with MQTT protocol");
ModuleClient client = ModuleClient.createFromEnvironment(protocol);
System.out.println("Client created");
client.setMessageCallback(App.INPUT_NAME, msgCallback, client);
client.registerConnectionStatusChangeCallback(new ConnectionStatusChangeCallback(), null);
client.open();
client.startTwin(new DeviceTwinStatusCallBack(), null, new OnProperty(), null);
Map<Property, Pair<TwinPropertyCallBack, Object>> onDesiredPropertyChange = new HashMap<Property, Pair<TwinPropertyCallBack, Object>>() {
{
put(new Property(App.TEMP_THRESHOLD, null), new Pair<TwinPropertyCallBack, Object>(new OnProperty(), null));
}
};
client.subscribeToTwinDesiredProperties(onDesiredPropertyChange);
client.getTwin();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}