我需要通过一个主题将命令发送到AWS IoT设备,并且该设备在另一个主题上发布该命令的结果。这遵循AWS IoT的常规异步发布子模型。
我正在尝试为此创建一个请求答复API,并且已经能够通过以下代码实现: 注意:使用同一主题发布和订阅模拟设备行为以进行测试。
问题是: 有没有一种方法可以摆脱Thread.sleep并使用某种future.get,它会等到对象不为null并从设备或超时中将某些值作为“ onMessage”的一部分返回,以先发生的为准。
BlockingPubSubIot.java
// This waits for the data to be received on the same topic as published to mimic the device behavior (for testing), and block the function to retrieve the result in a blocking way
public static void main(String args[]) throws InterruptedException, AWSIotException, AWSIotTimeoutException {
CommandArguments arguments = CommandArguments.parse(args);
initClient(arguments);
System.out.println("Connectionto IoT");
awsIotClient.connect();
String returnData = null;
NonBlockingListener listener =
new NonBlockingListener(TestTopic, TestTopicQos, returnData);
AWSIotTopic topic = listener;
System.out.println("Subscribing first");
awsIotClient.subscribe(topic, false);
String payload = "hello world";
System.out.println("Publishing payload to IoT now");
awsIotClient.publish(TestTopic, payload);
System.out.println("Waiting for the data via non blocking listener variable");
String data = listener.getReturnData();
/**
*
* Can we make this better or this is the right thing to do here
* like wait using some kind of future where I can just do get
* and it blocks till the value is not null before a given timeout
*
*/
for(int i =0;i<3 && data == null; i++) {
Thread.sleep(100);
System.out.println("Try " + i);
data = listener.getReturnData();
}
if(null == data) {// if its still null
// Do some exception handling
}
//Success
System.out.println("Data after subscribing synchronously is " + data);
//Disconnect at the end
awsIotClient.disconnect();
}
NonBlockingListener that sets the returnData variable on receiving the message from Iot
public class NonBlockingListener extends AWSIotTopic {
private String returnData;
public NonBlockingListener(String topic, AWSIotQos qos, String returnData) {
super(topic, qos);
this.returnData = returnData;
System.out.println("Initializing Callable");
}
public String getReturnData() {
return returnData;
}
@Override
public void onMessage(AWSIotMessage message) {
returnData = message.getStringPayload();
//System.out.println(System.currentTimeMillis() + ": <<< " + message.getStringPayload());
System.out.println("Data is "+ returnData);
}
}