This is how I have implemented explicit forced
ping as of now.
public class EnhancedMqttClient extends
MqttClient {
protected
static final String TAG_CLASS_NAME =
EnhancedMqttClient.class
.getName();
private
ExecutorService executor;
private
Object lock = new Object();
public
EnhancedMqttClient(Context context, String serverURI,
String
clientId, MqttClientPersistence persistence)
throws
MqttException {
super(serverURI,
clientId, persistence);
aClient
= new MyMqttAsyncClient(serverURI, clientId, persistence);
}
public
void ping() throws MqttException {
try
{
executor
= Executors.newSingleThreadExecutor();
executor.submit(new
PingExecutor()).get(10, TimeUnit.SECONDS);
}
catch (TimeoutException e) {
Log.e(TAG_CLASS_NAME,
"Ping Failure - Timeout");
disconnectForcibly(1000,
1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
finally {
executor.shutdownNow();
}
}
private
class PingExecutor implements Callable<Boolean> {
@Override
public
Boolean call() throws Exception {
MqttDeliveryToken
token = new MqttDeliveryToken(getClientId());
token.setActionCallback(new
IMqttActionListener() {
@Override
public
void onSuccess(IMqttToken asyncActionToken) {
System.out.println("Ping
Success");
synchronized
(lock) {
lock.notify();
}
}
@Override
public
void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.out.println("Ping
Failed");
try
{
if
(isConnected()) {
disconnectForcibly(1000,
1000);
}
}
catch (MqttException e) {
e.printStackTrace();
}
}
});
MqttPingReq
pingMsg = new MqttPingReq();
((MyMqttAsyncClient)
aClient).getClientComms().sendNoWait(pingMsg, token);
synchronized
(lock) {
lock.wait();
}
return
true;
}
}
}
There are two issues with this implementation.
1) onFailure callback MqttDeliveryToken does not
gets called every time ping fails. That's why I had to
implement timer here with the help of ExecutorService.
2) On failure I call disconnectForcibly. It
terminates all the mqtt callback threads and disconnect
client as expected, but it does not make a call to mqtt
callback connectionLost as there is no cause for shutdown
here.
Please let me know if there is any better way to
implement the same.