shamblett / mqtt_client

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

Unhandled exception when trying to reconnect #55

Closed DaveLan closed 5 years ago

DaveLan commented 5 years ago
import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';

Future<int> main() async {

  final MqttClient client = MqttClient('test.mosquitto.org', '');
  client.logging(on: false);
  client.keepAlivePeriod = 60;

  /// Add the unsolicited disconnection callback
  client.onDisconnected = onDisconnected;

  client.onSubscribed = onSubscribed;

  final MqttConnectMessage connMess = MqttConnectMessage()
      .withClientIdentifier('Mqtt_spl_id')
      .keepAliveFor(60) // Must agree with the keep alive set above or not set
      .withWillTopic('willtopic') // If you set this you must set a will message
      .withWillMessage('My Will message')
      .startClean() // Non persistent session for testing
      .withWillQos(MqttQos.atLeastOnce);
  print('EXAMPLE::Mosquitto client connecting....');
  client.connectionMessage = connMess;

  try {
    await client.connect();
  } on Exception catch (e) {
    print('EXAMPLE::client exception - $e');
    client.disconnect();
  }

  if (client.connectionStatus.state == ConnectionState.connected) {
    print('EXAMPLE::Mosquitto client connected');
  } else {
    print(
        'EXAMPLE::ERROR Mosquitto client connection failed - disconnecting, status is ${client.connectionStatus}');
    client.disconnect();
    exit(-1);
  }

  const String topic = 'com/spl/mqtt/connect'; // Not a wildcard topic
  client.subscribe(topic, MqttQos.atLeastOnce);

  client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
    final MqttPublishMessage recMess = c[0].payload;
    final String pt =
    MqttPublishPayload.bytesToStringAsString(recMess.payload.message);

    print(
        'EXAMPLE::Change notification:: topic is <${c[0].topic}>, payload is <-- $pt -->');
    print('');
  });

  print('EXAMPLE::Publishing our topic');

  final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
  builder.addString('Hello from sql connnect');
  /// Subscribe to it
  client.subscribe(topic, MqttQos.exactlyOnce);
  /// Publish it
  client.publishMessage(topic, MqttQos.exactlyOnce, builder.payload);
  await MqttUtilities.asyncSleep(20);
  print('EXAMPLE::Sleeping....');
  await MqttUtilities.asyncSleep(20);
  print('EXAMPLE::Disconnecting');
  client.disconnect();
  await MqttUtilities.asyncSleep(10);

  print("EXAMPLE::Connecting again");
  await client.connect();
  print('EXAMPLE::Publishing our topic again');
  await MqttUtilities.asyncSleep(2);
  client.publishMessage(topic, MqttQos.exactlyOnce, builder.payload);
  print('EXAMPLE::Sleeping....');
  await MqttUtilities.asyncSleep(20);
  print("end exc");
  return 0;
}

/// The subscribed callback
void onSubscribed(String topic) {
  print('EXAMPLE::Subscription confirmed for topic $topic');
}

/// The unsolicited disconnect callback
void onDisconnected() {
  print('EXAMPLE::OnDisconnected client callback - Client disconnection');
}
EXAMPLE::Mosquitto client connecting....
EXAMPLE::Mosquitto client connected
EXAMPLE::Publishing our topic
EXAMPLE::Subscription confirmed for topic com/spl/mqtt/connect
EXAMPLE::Change notification:: topic is <com/spl/mqtt/connect>, payload is <-- Hello from sql connnect -->

EXAMPLE::Sleeping....
EXAMPLE::Disconnecting
EXAMPLE::Connecting again
EXAMPLE::OnDisconnected client callback - Client disconnection
EXAMPLE::OnDisconnected client callback - Client disconnection
Unhandled 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
#0      SynchronousMqttConnectionHandler.internalConnect (file:///Users/lengxr/.pub-cache/hosted/pub.flutter-io.cn/mqtt_client-4.0.0/lib/src/connectionhandling/mqtt_client_synchronous_mqtt_connection_handler.dart:72:7)
<asynchronous suspension>
#1      MqttConnectionHandler.connect (file:///Users/lengxr/.pub-cache/hosted/pub.flutter-io.cn/mqtt_client-4.0.0/lib/src/connectionhandling/mqtt_client_mqtt_connection_handler.dart:56:13)
<asynchronous suspension>
#2      MqttClient.connect (file:///Users/lengxr/.pub-cache/hosted/pub.flutter-io.cn/mqtt_client-4.0.0/lib/src/mqtt_client.dart:163:37)
<asynchronous suspension>
#3      main (file:///Users/lengxr/Documents/FlutterProject/mqtt_demo/lib/connect_main.dart:71:16)
<asynchronous suspension>
#4      _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:289:19)
#5      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
shamblett commented 5 years ago

Yep I can reproduce this, I'll have a look

shamblett commented 5 years ago

OK, should be fixed in version 5.1.0, note disconnection is a hard disconnect as we send a disconnect message to the broker so on reconnect you will need to resubscribe and re-listen for the publish. I've updated the disconnect methods API doc to state this clearly, please retest.

DaveLan commented 5 years ago

Thanks Steve! The issue has been solved! 👍