【问题标题】:connection lost when trying to connect with aws iot mqtt broker尝试与 aws iot mqtt 代理连接时连接丢失
【发布时间】:2019-02-15 14:55:40
【问题描述】:

这是我的代码

try {
            if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath, keystoreName)) {
                if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId, keystorePath,
                        keystoreName, keystorePassword)) {
                    Log.i(LOG_TAG, "Certificate " + certificateId
                            + " found in keystore - using for MQTT.");
                    // load keystore from file into memory to pass on connection
                    clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
                            keystorePath, keystoreName, keystorePassword);
                    btnConnect.setEnabled(true);
                    mqttManager.setAutoReconnect(false);
                } else {
                    Log.i(LOG_TAG, "Key/cert " + certificateId + " not found in keystore.");
                }
            } else {
                Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName + " not found.");
            }
        } catch (Exception e) {
            Log.e(LOG_TAG, "An error occurred retrieving cert/key from keystore.", e);
        }

        if (clientKeyStore == null) {
            Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new key and certificate.");

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // Create a new private key and certificate. This call
                        // creates both on the server and returns them to the
                        // device.
                        CreateKeysAndCertificateRequest createKeysAndCertificateRequest =
                                new CreateKeysAndCertificateRequest();
                        createKeysAndCertificateRequest.setSetAsActive(true);
                        final CreateKeysAndCertificateResult createKeysAndCertificateResult;
                        createKeysAndCertificateResult =
                                mIotAndroidClient.createKeysAndCertificate(createKeysAndCertificateRequest);
                        Log.i(LOG_TAG,
                                "Cert ID: " +
                                        createKeysAndCertificateResult.getCertificateId() +
                                        " created.");

                        // store in keystore for use in MQTT client
                        // saved as alias "default" so a new certificate isn't
                        // generated each run of this application
                        AWSIotKeystoreHelper.saveCertificateAndPrivateKey(certificateId,
                                createKeysAndCertificateResult.getCertificatePem(),
                                createKeysAndCertificateResult.getKeyPair().getPrivateKey(),
                                keystorePath, keystoreName, keystorePassword);


                        // load keystore from file into memory to pass on
                        // connection
                        clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
                                keystorePath, keystoreName, keystorePassword);


                        // Attach a policy to the newly created certificate.
                        // This flow assumes the policy was already created in
                        // AWS IoT and we are now just attaching it to the
                        // certificate.
                        AttachPrincipalPolicyRequest policyAttachRequest =
                                new AttachPrincipalPolicyRequest();
                        policyAttachRequest.setPolicyName(AWS_IOT_POLICY_NAME);
                        policyAttachRequest.setPrincipal(createKeysAndCertificateResult
                                .getCertificateArn());
                        mIotAndroidClient.attachPrincipalPolicy(policyAttachRequest);

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                btnConnect.setEnabled(true);
                            }
                        });
                    } catch (Exception e) {
                        Log.e(LOG_TAG,
                                "Exception occurred when generating new private key and certificate.",
                                e);
                    }
                }
            }).start();
        }
    }

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

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

            try {
                mqttManager.connect(clientKeyStore, new AWSIotMqttClientStatusCallback() {
                    @Override
                    public void onStatusChanged(final AWSIotMqttClientStatus status,
                            final Throwable throwable) {
                        Log.d(LOG_TAG, "Status = " + String.valueOf(status));

                        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);
                                    }
                                    tvStatus.setText("Disconnected");
                                } else {
                                    tvStatus.setText("Disconnected");

                                }
                            }
                        });
                    }
                });
            } catch (final Exception e) {
                Log.e(LOG_TAG, "Connection error.", e);
                tvStatus.setText("Error! " + e.getMessage());
            }
        }
    };

当我尝试使用 android 手机与 aws iot mqtt 代理连接时,出现如下错误:

E/com.amazonaws.demo.androidpubsub.PubSubActivity:连接错误。 连接丢失 (32109) - java.io.EOFException 在 org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:146) 在 java.lang.Thread.run(Thread.java:818) 引起:java.io.EOFException 在 java.io.DataInputStream.readByte(DataInputStream.java:77) 在 org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:65) 在 org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:107) 在 java.lang.Thread.run(Thread.java:818)

【问题讨论】:

    标签: android amazon-web-services android-studio mqtt aws-iot


    【解决方案1】:

    上述异常可能是由于多种原因造成的,例如网络连接丢失、连接或订阅的策略限制等。不幸的是,Mqtt paho 客户端并不总是完美地传播连接异常,因此可能很难找到根本原因这个异常的问题。您似乎正在关注this 示例应用程序。我能够使用 README 说明使该应用程序正常工作。以下是我怀疑可能导致此问题的一些要点:

    1. 确保将以下 IAM 策略附加到作为身份池创建的一部分而创建的未经身份验证的角色

      { “版本”:“2012-10-17”, “陈述”: [ { “效果”:“允许”, “行动”: [ "iot:AttachPrincipalPolicy", “iot:CreateKeysAndCertificate” ], “资源”:[ “*” ] } ] }

    2. 确保将以下 IoT 策略附加到设备证书

      { “版本”:“2012-10-17”, “陈述”: [ { “效果”:“允许”, “行动”:“物联网:连接”, “资源”:“” }, { “效果”:“允许”, “行动”: [ “物联网:发布”, “物联网:订阅”, “物联网:接收” ], “资源”:“” } ] }

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      正如已经建议的那样,问题几乎可以肯定是由于没有附加适当的策略,但由于 AWS 示例代码中的错误处理不当,这进一步复杂化了。上面的代码首先在设备密钥库中查找已保存的证书,如果找到,则尝试使用它进行连接。如果在预期的密钥库名称下找不到证书,它会创建一个新证书,将其保存在密钥库中,然后尝试将原则策略附加到它。如果从 AWS 获取策略出现任何问题,那么您会在密钥库中留下一个配置错误的条目,并且 AWS 提供的代码永远无法从中恢复。我花了很多时间尝试策略但没有成功,直到我真正跟踪代码并意识到我指定的策略没有任何区别 - 代码忽略了它并在密钥库中使用了错误配置的策略!

      在上面代码的catch块中,添加以下内容

      AWSIotKeystoreHelper.deleteKeystoreAlias(certificateId,
                                  keystorePath, keystoreName, keystorePassword);
      

      这将确保没有错误配置的证书让您绊倒。

      就最初的错误而言,问题可能是您指定的策略的名称和上下文。我在 IAM 中创建了策略,但它们未被识别 - 您实际上需要按照 Roshan 在 IoT Core Security 上下文中的描述创建 IoT 策略,并在 PubSub 示例代码中指定您为其提供的名称。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-03
        • 1970-01-01
        • 2019-02-11
        • 1970-01-01
        • 2021-12-23
        • 2013-04-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多