shamblett / mqtt_client

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

Connection failed but it did not give me reasons to failure. #417

Closed Linorman closed 1 year ago

Linorman commented 1 year ago

These are my codes.

class MyMqttClient {
  late String _ClientId;
  late final int _ServerPort;
  late final String _IP;

  late MqttServerClient client_in;

  MyMqttClient(String id, int port, String ip) {
    this._ClientId = id;
    this._ServerPort = port;
    this._IP = ip;

    connect();
  }

  void connect() async {
    client_in = MqttServerClient(_IP, _ServerPort.toString());
    client_in.logging(on: true);
    client_in.keepAlivePeriod = 60;
    client_in.onDisconnected = onDisconnected;
    client_in.onConnected = onConnected;
    client_in.onSubscribed = onSubscribed;
    client_in.pongCallback = pong;

    MqttConnectMessage connMessage = MqttConnectMessage()
        .withClientIdentifier("${_ClientId}_client")
        .withWillTopic('willtopic')
        .withWillMessage('My Will message')
        .startClean()
        .withWillQos(MqttQos.atLeastOnce);
    print('Client connecting....');
    client_in.connectionMessage = connMessage;

    try {
      await client_in.connect();
    } on NoConnectionException catch (e) {
      print('Client exception: $e');
      client_in.disconnect();
    } on SocketException catch (e) {
      print('Socket exception: $e');
      client_in.disconnect();
    }

    if (client_in.connectionStatus!.state == MqttConnectionState.connected) {
      print('Client connected');
    } else {
      print(
          'Client connection failed - disconnecting, status is ${client_in.connectionStatus}');
      client_in.disconnect();
      exit(-1);
    }

   SubTopic("myproject");
  }

void SubTopic(String topic) {
    print('Subscribing to the $topic topic');
    client_in.subscribe(topic, MqttQos.atMostOnce);
    client_in.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) {
      final recMess = c![0].payload as MqttPublishMessage;

      final pt =
          MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
      print('Received message: topic is ${c[0].topic}, payload is $pt');
    });
  }
}

In the main method I did this:

late MyMqttClient client;
client = MyMqttClient('${user}_client', 1883, < ip >);

And the log goes:

flutter: Client connecting....
flutter: 1-2022-10-17 15:46:23.319421 -- MqttClient::connect - Connection timeout period is 5000 milliseconds
flutter: 1-2022-10-17 15:46:23.322399 -- MqttClient::connect - keep alive is enabled with a value of 60 seconds
flutter: 1-2022-10-17 15:46:23.323089 -- MqttConnectionKeepAlive:: Initialised with a keep alive value of 60 seconds
flutter: 1-2022-10-17 15:46:23.323219 -- MqttConnectionKeepAlive:: Disconnect on no ping response is disabled
flutter: 1-2022-10-17 15:46:23.323736 -- MqttConnectionHandlerBase::connect - server < ip > port 1883
flutter: 1-2022-10-17 15:46:23.324635 -- SynchronousMqttServerConnectionHandler::internalConnect entered
flutter: 1-2022-10-17 15:46:23.324810 -- SynchronousMqttServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress false
flutter: 1-2022-10-17 15:46:23.325040 -- SynchronousMqttServerConnectionHandler::internalConnect - insecure TCP selected
flutter: 1-2022-10-17 15:46:23.325465 -- SynchronousMqttServerConnectionHandler::internalConnect - calling connect
flutter: 1-2022-10-17 15:46:23.325869 -- MqttNormalConnection::connect - entered
flutter: Subscribing to the myproject topic

Then it came the exception:

Unhandled Exception: mqtt-client::ConnectionException: The connection must be in the Connected state in order to perform this operation. Current state is connecting

It did not connect successfully to the server but I did not know why it happened.

shamblett commented 1 year ago

You don't seem to be waiting for connect to complete, your connect(); in the constructor should be awaited not async void. However don't do this in a constructor, make your connect a separate method call it from main and await it, only proceed when you know you are connected.

Linorman commented 1 year ago

Ok, thanks, it worked.