Skip to content

Commit

Permalink
Some additional protections against concurrent connections
Browse files Browse the repository at this point in the history
  • Loading branch information
christianrowlands committed Apr 29, 2021
1 parent 3835acd commit 506e124
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class DefaultMqttConnection
protected String mqttClientId;
private CompletableFuture<Mqtt3ConnAck> connectFuture;
private volatile boolean userCanceled = false;
private volatile boolean disconnecting = false;

protected DefaultMqttConnection()
{
Expand All @@ -64,6 +65,20 @@ public synchronized void connect(Context applicationContext, BrokerConnectionInf
{
try
{
if (mqtt3Client != null && mqtt3Client.getState().isConnectedOrReconnect())
{
Timber.i("Disconnect in progress, delaying the new connection");
try
{
final CompletableFuture<Void> disconnectFuture = mqtt3Client.disconnect();
disconnectFuture.get(3, TimeUnit.SECONDS);
} catch (Throwable t)
{
Timber.e(t, "Could not properly close the old connection before starting a new one.");
}
Timber.i("Disconnect complete, resuming the new connection");
}

userCanceled = false;
mqttClientId = connectionInfo.getMqttClientId();

Expand Down Expand Up @@ -91,8 +106,18 @@ public synchronized void connect(Context applicationContext, BrokerConnectionInf
.automaticReconnect().maxDelay(60, TimeUnit.SECONDS).applyAutomaticReconnect()

.addConnectedListener(context -> {
Timber.i("MQTT Broker Connected!!!!");
notifyConnectionStateChange(ConnectionState.CONNECTED);
if (userCanceled)
{
Timber.i("The user canceled the MQTT connection prior to the connection attempt completing, closing the new connection");
synchronized (this)
{
mqtt3Client.disconnect();
}
} else
{
Timber.i("MQTT Broker Connected!!!!");
notifyConnectionStateChange(ConnectionState.CONNECTED);
}
})

.addDisconnectedListener(context -> {
Expand Down Expand Up @@ -141,14 +166,17 @@ public synchronized void disconnect()
}

// Just in case the connection completed between calling isDone() and cancel(), we go through the disconnect to be sure
disconnecting = true;
final CompletableFuture<Void> disconnect = mqtt3Client.disconnect();
disconnect.whenComplete((aVoid, throwable) -> {
Timber.d(throwable, "The MQTT disconnect request completed");
notifyConnectionStateChange(ConnectionState.DISCONNECTED);
disconnecting = false;
});
} catch (Exception e)
{
Timber.e(e, "An exception occurred when disconnecting from the MQTT broker");
disconnecting = false;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,19 @@ private void onConnectionSwitchToggled()
{
if (!hasInternetPermission()) return;

mqttConnectionToggleSwitch.setEnabled(false);
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(() -> {
try
{
Timber.v("Enabling the toggle switch");
mqttConnectionToggleSwitch.setEnabled(true);
} catch (Throwable t)
{
Timber.wtf(t, "Something went really wrong when trying to re-enable the MQTT Connection Toggle Switch");
}
}, 1_000);

if (mqttConnectionToggleSwitch.isChecked())
{
connectToMqttBroker();
Expand Down Expand Up @@ -407,7 +420,6 @@ protected void updateUiState(ConnectionState connectionState)
case CONNECTING:
connectionStatusCardView.setCardBackgroundColor(getResources().getColor(R.color.connectionStatusConnecting, null));
connectionStatusText.setText(getString(R.string.status_connecting));
mqttConnectionToggleSwitch.setEnabled(true);
mqttConnectionToggleSwitch.setChecked(true);
setConnectionInputFieldsEditable(false, false);
break;
Expand Down

0 comments on commit 506e124

Please sign in to comment.