"MqttException (0) - java.io.IOException: Already connected"

0 votes

I'm trying to run an Android Things application integrated with AWS Iot cloud services over the MQTT broker. I've been getting an error while I am trying to integrate My Cognito user pool authentication based on the JSON Web Tokens with my Pub/Sub based application. 

Upon running the application now, it throws this exception: MqttException (0) - java.io.IOException: Already connected 
I basically want to authenticate using Cognito-Identity with Cognito user pool in my Android application. 

Here's what I have been getting:

W/System.err: MqttException (0) - java.io.IOException: Already connected
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:664)
W/System.err:     at java.lang.Thread.run(Thread.java:761)
W/System.err: Caused by: java.io.IOException: Already connected
W/System.err:     at java.io.PipedOutputStream.connect(PipedOutputStream.java:100)
W/System.err:     at java.io.PipedInputStream.connect(PipedInputStream.java:195)
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketReceiver.<init>(WebSocketReceiver.java:42)
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketSecureNetworkModule.start(WebSocketSecureNetworkModule.java:78)
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650)
W/System.err:   ... 1 more


This where I've done the Authentication(Cognito user pool authentication) activity and Connect activity!

AmazonCognitoIdentityProviderClient identityProviderClient = new 
AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), new ClientConfiguration());
identityProviderClient.setRegion(Region.getRegion(Regions.US_WEST_2));
CognitoUserPool userPool = new CognitoUserPool(getApplicationContext(), "us-west-2_ghtcc6ho9", "4t0mk45hNso69dp2j4jvel5ghm", "1jmq0lhhq721oif9k6nug31c29i760vihua8hvrgu5umfr2a1vd7", identityProviderClient);
cogUser = userPool.getUser();
authenticationHandler = new AuthenticationHandler() {

        @Override
        public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
            String ids = userSession.getIdToken().getJWTToken();
            Log.d("MyToken","session id___"+userSession.getIdToken().getExpiration()+"___"+userSession.getIdToken().getIssuedAt());
            Intent pubSub = new Intent(MainActivity.this, PubSubActivity.class);
            pubSub.putExtra("token",""+ids);
            startActivity(pubSub);
            //MainActivity.this.finish();

        }

        @Override
        public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
            Log.d("MyToken","getAuthenticationDetails");
            AuthenticationDetails authenticationDetails = new AuthenticationDetails("shone", "172737", null);
            authenticationContinuation.setAuthenticationDetails(authenticationDetails);
            // Allow the sign-in to continue
            authenticationContinuation.continueTask();
        }

        @Override
        public void getMFACode(MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation) {
            Log.d("MyToken","getMFACode");
            multiFactorAuthenticationContinuation.continueTask();
        }

        @Override
        public void authenticationChallenge(ChallengeContinuation continuation) {
            Log.d("MyToken","authenticationChallenge"+continuation.getChallengeName());
            newPasswordContinuation.continueTask();
        }

        @Override
        public void onFailure(Exception exception) {
            exception.printStackTrace();
            Log.d("MyToken","onFailure");
        }
    };
     cogUser.getSessionInBackground(authenticationHandler); 


The connect activity and the session token. I launch them when the "OnSuccess" comes in and instruct to move with the next activity.

private static final String COGNITO_POOL_ID = "us-west-2:a153a090-508c-44c0-a9dd-efd450298c4b";
private static final Regions MY_REGION = Regions.US_WEST_2;
AWSIotMqttManager mqttManager;
String clientId;
AWSCredentials awsCredentials;
CognitoCachingCredentialsProvider credentialsProvider;
 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Intent intent = getIntent();
if(null == intent){
    Toast.makeText(getApplicationContext(), "Token is null", Toast.LENGTH_SHORT).show();
}else {
    token = intent.getStringExtra("token");
}
 clientId = UUID.randomUUID().toString();
    credentialsProvider = new CognitoCachingCredentialsProvider(
            getApplicationContext(), 
            COGNITO_POOL_ID, 
            MY_REGION 
    );
mqttManager = new AWSIotMqttManager(clientId, CUSTOMER_SPECIFIC_ENDPOINT);
 Map loginsMap = new HashMap();
    loginsMap.put("cognito-idp.us-west-2.amazonaws.com/us-west-2_ghtcc6ho9", token);
    credentialsProvider.setLogins(loginsMap);
    Log.d("SESSION_ID", ""+token);
    new Thread(new Runnable() {
        @Override
        public void run() {
            credentialsProvider.refresh();
            awsCredentials = credentialsProvider.getCredentials();
            Log.d("SESSION_ID B: ", ""+awsCredentials.getAWSAccessKeyId());
            Log.d("SESSION_ID C: ", ""+awsCredentials.getAWSSecretKey());
        }
    }).start();
}

 View.OnClickListener connectClick = new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        Log.d(LOG_TAG, "clientId = " + clientId);

        try {
            mqttManager.connect(credentialsProvider, new AWSIotMqttClientStatusCallback() {
                @Override
                public void onStatusChanged(final AWSIotMqttClientStatus status,
                        final Throwable throwable) {
                    Log.d(LOG_TAG, "Status = " + String.valueOf(status)+"______"+((null !=throwable)?throwable.getMessage():""));

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (status == AWSIotMqttClientStatus.Connecting) {
                                tvStatus.setText("Connecting...");

                            } else if (status == AWSIotMqttClientStatus.Connected) {
                                tvStatus.setText("Connected");

                            } else if (status == AWSIotMqttClientStatus.Reconnecting) {
                                if (throwable != null) {
                                    Log.e(LOG_TAG, "Connection error.", throwable);
                                }
                                tvStatus.setText("Reconnecting");
                            } else if (status == AWSIotMqttClientStatus.ConnectionLost) {
                                if (throwable != null) {
                                    Log.e(LOG_TAG, "Connection error.", throwable);
                                    throwable.printStackTrace();
                                }
                                tvStatus.setText("Disconnected");
                            } else {
                                tvStatus.setText("Disconnected");

                            }
                        }
                    });
                }
            });
        } catch (final Exception e) {
            Log.e(LOG_TAG, "Connection error.", e);
        }
    }
};

That's the entire thing. They run fine separetly, but throws exception when a connection is invoked with the MQTT.
Please guide me on what I could be doing wrong, or am I missing something? 
THANK YOU!  

Jul 17, 2018 in IoT (Internet of Things) by Bharani
• 4,550 points
300 views

1 answer to this question.

Your answer

Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.
0 votes

Oh man, that was a heck of a task! But I finally got it together! 

So,
 After your login, there will be a jwt(json web token), this one:

String idToken = cognitoUserSession.getIdToken().getJWTToken();

get it inside a map like this

Map<String, String> logins = new HashMap<String, String>(); 
//fill it with Cognito User token
logins.put("cognito-idp.<REGION>.amazonaws.com/<COGNITO_USER_POOL_ID>", idToken);

and, use it to set in the following two places,

first, set in here:
CognitoCachingCredentialsProvider credentialsProvider = new 
CognitoCachingCredentialsProvider(context, IDENTITY_POOL_ID, REGION);
credentialsProvider.setLogins(logins);

then, set in here 
AmazonCognitoIdentity cognitoIdentity = new AmazonCognitoIdentityClient(credentialsProvider);
GetIdRequest getIdReq = new GetIdRequest();
getIdReq.setLogins(logins); //or if you have already set provider logins just use credentialsProvider.getLogins()
getIdReq.setIdentityPoolId(COGNITO_POOL_ID);
GetIdResult getIdRes = cognitoIdentity.getId(getIdReq);

just some methods to call now:

AttachPrincipalPolicyRequest attachPolicyReq = new AttachPrincipalPolicyRequest(); //in docs it called AttachPolicyRequest but it`s wrong
attachPolicyReq.setPolicyName("allAllowed"); //name of your IOTAWS policy
attachPolicyReq.setPrincipal(getIdRes.getIdentityId());
new AWSIotClient(credentialsProvider).attachPrincipalPolicy(attachPolicyReq);

So, now you'll be able to enable the connect button and proceed with the MQTT broker:

mqttManager.connect(credentialsProvider, new AWSIotMqttClientStatusCallback() {

Should work like a charm now! At least, I really hope so. Keep me posted!

answered Jul 17, 2018 by DataKing99
• 8,100 points

Related Questions In IoT (Internet of Things)

0 votes
1 answer

Publishing commands to device in IBM IoT using MQTT in Java

If you are publishing from an application, ...READ MORE

answered Jul 27, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
347 views
0 votes
1 answer
0 votes
1 answer

Control LED Blinking Using Java in Azure IoT Hub

Your description of what you did is ...READ MORE

answered Sep 5, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
91 views
0 votes
1 answer

Java No Class Def Found error

I solved this issue by updating my ...READ MORE

answered Oct 8, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
107 views
0 votes
1 answer

Connect to external server through Socket.IO from Node.js

I think the server you're connecting to ...READ MORE

answered Nov 21, 2018 in IoT (Internet of Things) by nirvana
• 3,060 points
507 views
0 votes
1 answer

Cygnus : I'm getting this exception "curl/7.29.0 user agent not supported"

Cygnus version <= 0.8.2 controls the HTTP ...READ MORE

answered Nov 23, 2018 in IoT (Internet of Things) by Shubham
• 12,790 points
32 views
0 votes
1 answer

AWS IoT login from android MQTT client using IAM is not working

Seeing your comments and questions. I had ...READ MORE

answered Jul 24, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
220 views
0 votes
1 answer

aws iot describe-endpoint::You must specify a region

This fixed the problem: Browse to https://console.aws.amazon.com/iam/home?region=us-west-2#security_credentialand then if ...READ MORE

answered Jul 11, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
155 views

© 2018 Brain4ce Education Solutions Pvt. Ltd. All rights Reserved.
"PMP®","PMI®", "PMI-ACP®" and "PMBOK®" are registered marks of the Project Management Institute, Inc. MongoDB®, Mongo and the leaf logo are the registered trademarks of MongoDB, Inc.