shamblett / mqtt_client

A server and browser based MQTT client for dart
Other
548 stars 176 forks source link

NoConnectionException: Missing Connection Acknowledgement #538

Closed pratamarama closed 3 months ago

pratamarama commented 3 months ago

Hello, i want to ask why i cant connect to mqtt and always get exception, whereas i already put certificates that generated from the AWS console. Thank you for any help and suggestion

    _client = MqttServerClient.withPort(Constant.customerSpesificEndpoint, clientIdentifier, 8883, maxConnectionAttempts: 1);
    _client?.secure = true;
    _client?.keepAlivePeriod = 20;
    _client?.setProtocolV311();
    _client?.logging(on: kDebugMode);
    _client?.onDisconnected = () {
      print('MqttHelper: disconnected');
    };

    final SecurityContext context = SecurityContext.defaultContext;
    final ByteData authorities = await service.rootBundle.load(KeyHelper.getSourceByKey(KeyAssetNames.authorities));
    final ByteData certificate =
        await service.rootBundle.load(KeyHelper.getSourceByKey(KeyAssetNames.certificateChain));
    final ByteData privateKey = await service.rootBundle.load(KeyHelper.getSourceByKey(KeyAssetNames.privateKey));
    context.useCertificateChainBytes(certificate.buffer.asUint8List());
    context.setClientAuthoritiesBytes(authorities.buffer.asUint8List());
    context.usePrivateKeyBytes(privateKey.buffer.asUint8List());
    _client?.securityContext = context;

    final MqttConnectMessage connMess = MqttConnectMessage().withClientIdentifier(clientIdentifier).startClean();
    _client?.connectionMessage = connMess;
    try {
      print('MqttHelper: client connecting to AWS IoT using certificates....');
      await _client?.connect();
    } on Exception catch (e) {
      print('MqttHelper: client exception - $e');
      _client?.disconnect();
    }

This is the log:

flutter: MqttHelper: client connecting to AWS IoT using certificates....
flutter: 1-2024-06-13 17:36:27.922957 -- MqttClient::connect - Connection timeout period is 5000 milliseconds
flutter: 1-2024-06-13 17:36:27.930460 -- MqttClient::connect - keep alive is enabled with a value of 20 seconds
flutter: 1-2024-06-13 17:36:27.932746 -- MqttConnectionKeepAlive:: Initialised with a keep alive value of 20 seconds
flutter: 1-2024-06-13 17:36:27.932961 -- MqttConnectionKeepAlive:: Disconnect on no ping response is disabled
flutter: 1-2024-06-13 17:36:27.934650 -- MqttConnectionHandlerBase::connect - server {{server}}.amazonaws.com, port 443
flutter: 1-2024-06-13 17:36:27.936100 -- SynchronousMqttServerConnectionHandler::internalConnect entered
flutter: 1-2024-06-13 17:36:27.936495 -- SynchronousMqttServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress false
flutter: 1-2024-06-13 17:36:27.937167 -- SynchronousMqttServerConnectionHandler::internalConnect - secure selected
flutter: 1-2024-06-13 17:36:27.938126 -- SynchronousMqttServerConnectionHandler::internalConnect - calling connect
flutter: 1-2024-06-13 17:36:27.938953 -- MqttSecureConnection::connect - entered
flutter: 1-2024-06-13 17:36:28.126743 -- MqttSecureConnection::connect - securing socket
flutter: 1-2024-06-13 17:36:28.129170 -- MqttSecureConnection::connect - start listening
flutter: 1-2024-06-13 17:36:28.129712 -- MqttServerConnection::_startListening
flutter: 1-2024-06-13 17:36:28.133249 -- SynchronousMqttServerConnectionHandler::internalConnect - connection complete
flutter: 1-2024-06-13 17:36:28.133479 -- SynchronousMqttServerConnectionHandler::internalConnect sending connect message
flutter: 1-2024-06-13 17:36:28.133888 -- MqttConnectionHandlerBase::sendMessage - MQTTMessage of type MqttMessageType.connect
Header: MessageType = MqttMessageType.connect, Duplicate = false, Retain = false, Qos = MqttQos.atMostOnce, Size = 0
Connect Variable Header: ProtocolName=MQTT, ProtocolVersion=4, ConnectFlags=Connect Flags: Reserved1=false, CleanStart=true, WillFlag=false, WillQos=MqttQos.atMostOnce, WillRetain=false, PasswordFlag=false, UserNameFlag=false, KeepAlive=20
MqttConnectPayload - client identifier is : {{clientIdentifier}}
flutter: 1-2024-06-13 17:36:28.154139 -- SynchronousMqttServerConnectionHandler::internalConnect - pre sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none
flutter: 1-2024-06-13 17:36:30.301721 -- MqttConnectionBase::_onDone - calling disconnected callback
flutter: 1-2024-06-13 17:36:33.166019 -- SynchronousMqttServerConnectionHandler::internalConnect - post sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none
flutter: 1-2024-06-13 17:36:40.520356 -- MqttConnectionBase::_onDone - calling disconnected callback
flutter: 1-2024-06-13 17:36:43.432081 -- SynchronousMqttServerConnectionHandler::internalConnect - post sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none
flutter: 1-2024-06-13 17:36:43.433517 -- SynchronousMqttServerConnectionHandler::internalConnect failed
flutter: MqttHelper: client exception - mqtt-client::NoConnectionException: The maximum allowed connection attempts ({3}) were exceeded. The broker is not responding to the connection request message (Missing Connection Acknowledgement?
flutter: 1-2024-06-13 17:36:48.077650 -- MqttConnectionHandlerBase::disconnect - entered
flutter: 1-2024-06-13 17:36:48.079626 -- MqttConnectionHandlerBase::_performConnectionDisconnect entered
flutter: 1-2024-06-13 17:36:48.090131 -- MqttConnectionKeepAlive::stop - stopping keep alive
flutter: MqttHelper: disconnected
flutter: MqttHelper: ERROR client connection failed - disconnecting, state is MqttConnectionState.disconnected
flutter: MqttHelper: disconnected
shamblett commented 3 months ago

From the AWS docs -

*Using MQTT with client certificate authentication on port 443 requires the use of the ALPN TLS extension.

So you need to use this method on your security context .

Consult the AWS documentation on the page linked above to see what to put in this.

pratamarama commented 3 months ago

I set port to 443 and set the ALPN protocol based on this:

_client = MqttServerClient.withPort(Constant.customerSpesificEndpoint, clientIdentifier, 443);
context.setAlpnProtocols(<String>['x-amzn-mqtt-ca'], false);

But the result is just the same..

shamblett commented 3 months ago

Ok your only recourse then is to examine your AWS MQTT broker logs to find out why it's refusing the connection, the client can't help you any more here.

pratamarama commented 3 months ago

@shamblett Thanks for the help and suggestion. It fixes by attach the policy to the certificate on AWS console.