shamblett / mqtt_client

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

AWS IOT Core giving HandshakeException: Connection terminated during handshake #260

Closed sureace closed 3 years ago

sureace commented 3 years ago

Hi shamblett, I am trying to establish a connection with AWS IOT core. When i tried, i am getting error like HandshakeException: Connection terminated during handshake.

Code

`client = MqttServerClient.withPort("awsEndPointURL", clientId, 8883, maxConnectionAttempts: 5);

  ByteData caData = await rootBundle.load('assets/cert/AmazonRootCA1.pem');
  ByteData certData = await rootBundle.load('assets/cert/c2d9eba464-certificate.pem.crt');
  ByteData privateKeyData = await rootBundle.load('assets/cert/c2d9eba464-private.pem.key');
  SecurityContext context = SecurityContext.defaultContext;
  context.setTrustedCertificatesBytes(certData.buffer.asUint8List());
  context.setClientAuthoritiesBytes(caData.buffer.asUint8List());
  context.usePrivateKeyBytes(privateKeyData.buffer.asUint8List());
  client.securityContext = context;
  client.setProtocolV311();
  client.port = 8883;
  client.secure = true;
  client.onConnected = onConnected;
  client.onDisconnected = onDisconnected;
  await client.connect();
  if (client != null &&
      client.connectionStatus.state == MqttConnectionState.connected) {
    print("Connected to AWS Successfully!");
    isConnected = true;
  }`

Thanking You, Sureace

shamblett commented 3 years ago

Which means there's something wrong with your setup, it can be difficult to connect to amazon, see the various discussions on #246

sureace commented 3 years ago

Hi @shamblett , Thanks for the prompt response. #246 is trying to connect via socket. In my case i am trying to connect using tcp. I followed #196 but no luck. It would be helpful with some example like google iot core and others.

Thanks, Sureace

shamblett commented 3 years ago

Yes it would be helpful to have an example for AWS, I've asked AWS users for this before but to no avail, maybe if when you get your code working you could submit an example for inclusion. There is the iot_core.dart example for Google Core use, I did this as I use Google Core, not AWS or others.

sureace commented 3 years ago

Yes it would be helpful to have an example for AWS, I've asked AWS users for this before but to no avail, maybe if when you get your code working you could submit an example for inclusion. There is the iot_core.dart example for Google Core use, I did this as I use Google Core, not AWS or others.

sure @shamblett

sureace commented 3 years ago

Hi @shamblett , When i tried with MQTT fx client, it is connecting fine. I tried different ways, but no luck so far with mqtt_client. By looking at the below snapshot please tell me, am i missing anything ? Screen Shot 2021-03-19 at 3 54 17 PM

`client = MqttServerClient.withPort(".iot..amazonaws.com", clientId, 8883, maxConnectionAttempts: 5); /SecurityContext context = new SecurityContext() ..useCertificateChain('assets/cert/cert.pem') ..usePrivateKey('assets/cert/private.pem') ..setClientAuthorities('assets/cert/CA.pem'); client.secure = true; client.securityContext = context;/

  /*ByteData caData = await rootBundle.load('assets/cert/CA.pem');
  ByteData certData = await rootBundle.load('assets/cert/cert.pem');
  ByteData privateKeyData = await rootBundle.load('assets/cert/private.pem');
  SecurityContext context = SecurityContext.defaultContext;
  context.setTrustedCertificatesBytes(certData.buffer.asUint8List());
  context.setClientAuthoritiesBytes(caData.buffer.asUint8List());
  context.usePrivateKeyBytes(privateKeyData.buffer.asUint8List());*/

  SecurityContext context = SecurityContext.defaultContext;
  context.setTrustedCertificatesBytes(Config.CERT_STR.codeUnits);
  context.setClientAuthoritiesBytes(Config.CA_STR.codeUnits);
  context.usePrivateKeyBytes(Config.PRIVATE_KEY_STR.codeUnits);
  client.securityContext = context;
  client.setProtocolV311();
  //client.setProtocolV31()
  client.logging(on: true);
  client.keepAlivePeriod = 20;
  client.port = 8883;
  client.secure = true;
  client.onConnected = onConnected;
  client.onDisconnected = onDisconnected;
  final MqttConnectMessage connMess = MqttConnectMessage()
      .withClientIdentifier(clientId)
      .startClean()
      .keepAliveFor(30);

  client.connectionMessage = connMess;
  await client.connect();
  if (client != null &&
      client.connectionStatus.state == MqttConnectionState.connected) {
    print("Connected to AWS Successfully!");
    isConnected = true;
  }`

Thanks, Sureace

shamblett commented 3 years ago

I remember another user having to use port 443 for this with AWS to match the TLS that Dart uses, could be wrong here but its worth checking what TLS versions you can use on Amazon.

sureace commented 3 years ago

Hi @shamblett , I tried with 443 and got error like The broker is not responding to the connection request message (Missing Connection Acknowledgement. Another user had same issue, then he tried with secure port 8883. 443 for socket communication right. I tried with 8443 as well but not working. There is open ssl command to check certificates with 8443. openssl s_client -connect .......-ats.iot.us-east-1.amazonaws.com:8443 -CAfile CA.pem -cert cert.pem -key private.pem

Thanks, Sureace

shamblett commented 3 years ago

Ah OK, IIRC the user who used 8883 did get it working but I'm not sure how, I can't see anything obviously wrong, maybe you ned to look at your Amazon broker logs to see what it thinks is happening.

sureace commented 3 years ago

Ah OK, IIRC the user who used 8883 did get it working but I'm not sure how, I can't see anything obviously wrong, maybe you ned to look at your Amazon broker logs to see what it thinks is happening.

Let me check and update you @shamblett

Obaidiaa commented 3 years ago

@sureace did you configure AWS IoT policy correctly? Also did you attached the certificate to IoT thing and attached policy to certificate ?

Configure CloudWatch to see the logs.

sureace commented 3 years ago

@sureace did you configure AWS IoT policy correctly? Also did you attached the certificate to IoT thing and attached policy to certificate ?

Configure CloudWatch to see the logs.

Hi @Obaidiaa , I configured policy and attached it to certificate. It is perfectly working when i tested with other mqtt clients like MQTT fx and AWS IOT test client. Thanks, Sureace

xukangmin commented 3 years ago

@sureace I have the same issue, for device cert file, I changed context.setTrustedCertificates to context.useCertificateChain. Now it works fine,

context.useCertificateChain(currDir + 'awsiot-certificate.pem.crt'); context.setClientAuthorities(currDir + 'AmazonRootCA.pem'); context.usePrivateKey(currDir + 'awsiot-private.pem.key');

xukangmin commented 3 years ago

Also note, AWS only accept Qos0 (atLeastOnce) and Qos1 (atMostOnce), MqttQos.exactlyOnce is not supported. you won't get the message.

saranyajeyaraman03 commented 8 months ago

import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart' show rootBundle; import 'package:mqtt_client/mqtt_client.dart'; import 'package:mqtt_client/mqtt_server_client.dart';

void main() { runApp(MyApp()); }

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'AWS IoT MQTT Example', home: MQTTScreen(), ); } }

class MQTTScreen extends StatefulWidget { @override _MQTTScreenState createState() => _MQTTScreenState(); }

class _MQTTScreenState extends State { late MqttServerClient client; bool isConnected = false;

@override void initState() { super.initState(); _connectToMQTT(); }

Future _connectToMQTT() async { try { client = MqttServerClient.withPort('a3bd9ic9v4dpst-ats.iot.ap-southeast-1.amazonaws.com', 'things-demo',8883,maxConnectionAttempts: 5); ByteData caData = await rootBundle.load('assets/certificate/root-CA.crt'); ByteData certData = await rootBundle.load('assets/certificate/things-demo.cert.pem'); ByteData privateKeyData = await rootBundle.load('assets/certificate/things-demo.private.key');

  SecurityContext context = SecurityContext.defaultContext;
  context.setTrustedCertificatesBytes(certData.buffer.asUint8List());
  context.setClientAuthoritiesBytes(caData.buffer.asUint8List());
  context.usePrivateKeyBytes(privateKeyData.buffer.asUint8List());
  client.securityContext = context;

  client.setProtocolV311();
  client.port = 8883;
  client.secure = true;
  client.logging(on: true);

  client.onConnected = _onConnected;
  client.onDisconnected = _onDisconnected;

  await client.connect();

  if (client != null &&
      client.connectionStatus?.state == MqttConnectionState.connected) {
    print("Connected to AWS Successfully!");
    setState(() {
      isConnected = true;
    });
  }
} catch (e) {
  print('Error connecting to AWS IoT: $e');
}

}

void _onConnected() { print('Connected to AWS IoT'); }

void _onDisconnected() { print('Disconnected from AWS IoT'); setState(() { isConnected = false; }); }

@override void dispose() { client.disconnect(); super.dispose(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('AWS IoT MQTT Example'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( isConnected ? 'Connected to AWS IoT MQTT' : 'Not Connected', style: const TextStyle(fontSize: 20), ), const SizedBox(height: 20), ElevatedButton( onPressed: () { // Your logic for sending messages or other actions }, child: Text('Perform Action'), ), ], ), ), ); } } can you please tell me what i ma missing above code.i got error I/flutter (11354): Error connecting to AWS IoT: HandshakeException: Connection terminated during handshake

shamblett commented 8 months ago

A you can read in the above on this issue I'm not an AWS user, your better off contacting the people contributing to this thread as they do use AWS and would know far more about it than me.