Flutter : NoSuchMethodError: The method 'connect' was called on null

Flutter : NoSuchMethodError: The method 'connect' was called on null

我正在尝试使用 Flutter 连接到 mosquitto MQTT 测试代理。它一直给我 nosuchmethoderror,说我试图在 null 上调用连接,即使我认为我已经根据包[文档]正确设置了所有内容。

这是我的代码:

import 'dart:io';

import 'package:flutter/material.dart';
import 'converter.dart';
import 'constants.dart' as Constants;
import 'package:location/location.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'models.dart';
import 'package:mqtt_client/mqtt_server_client.dart';

class MQTTClientWrapper {

  MqttClient client;
  LocationToJsonConverter locationToJsonConverter = LocationToJsonConverter();
  JsonToLocationConverter jsonToLocationConverter = JsonToLocationConverter();

  MqttCurrentConnectionState connectionState = MqttCurrentConnectionState.IDLE;
  MqttSubscriptionState subscriptionState = MqttSubscriptionState.IDLE;

  final VoidCallback onConnectedCallback;
  final Function(LocationData) onLocationReceivedCallback;
  

  MQTTClientWrapper(this.onConnectedCallback, this.onLocationReceivedCallback);

  void prepareMqttClient() async {
    _setupMqttClient();
    await _connectClient();
    _subscribeToTopic(Constants.topicName);
  }

  void publishLocation(LocationData locationData) {
    String locationJson = locationToJsonConverter.convert(locationData);
    _publishMessage(locationJson);
  }

  Future<void> _connectClient() async {
    try {
      print('MQTTClientWrapper::Mosquitto client connecting....');
      connectionState = MqttCurrentConnectionState.CONNECTING;
      await client.connect();
    } on NoConnectionException catch (e) {
      print('MQTTClientWrapper::client exception - $e');
      connectionState = MqttCurrentConnectionState.ERROR_WHEN_CONNECTING;
      client.disconnect();
    } on SocketException catch (e) {
      print('EXAMPLE::socket exception - $e');
      client.disconnect();
    }

    if (client.connectionStatus.state == MqttConnectionState.connected) {
      connectionState = MqttCurrentConnectionState.CONNECTED;
      print('MQTTClientWrapper::Mosquitto client connected');
    } else {
      print(
          'MQTTClientWrapper::ERROR Mosquitto client connection failed - disconnecting, status is ${client.connectionStatus}');
      connectionState = MqttCurrentConnectionState.ERROR_WHEN_CONNECTING;
      client.disconnect();
      exit(-1);
    }
  }

  void _setupMqttClient() {
    final client = MqttServerClient('test.mosquitto.org', '');
    client.logging(on: false);
    client.keepAlivePeriod = 20;
    client.onDisconnected = _onDisconnected;
    client.onConnected = _onConnected;
    client.onSubscribed = _onSubscribed;
    final connMess = MqttConnectMessage()
    .withClientIdentifier('sisterClient_publishHp')
    .keepAliveFor(20)
    .startClean()
    .withWillQos(MqttQos.atLeastOnce);
    client.connectionMessage = connMess;
  }

  void _subscribeToTopic(String topicName) {
    print('MQTTClientWrapper::Subscribing to the $topicName topic');
    client.subscribe(topicName, MqttQos.atMostOnce);

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

      print("MQTTClientWrapper::GOT A NEW MESSAGE $newLocationJson");
      LocationData newLocationData = _convertJsonToLocation(newLocationJson);
      if (newLocationData != null) onLocationReceivedCallback(newLocationData);
  });
  }

  LocationData _convertJsonToLocation(String newLocationJson) {
    try {
      return jsonToLocationConverter.convert(
          newLocationJson);
    } catch (exception) {
      print("Json can't be formatted ${exception.toString()}");
    }
    return null;
  }

  void _publishMessage(String message) async {
    client.published.listen((MqttPublishMessage message) {
      print(
        'EXAMPLE::Published notification:: topic is ${message.variableHeader.topicName}, with Qos ${message.header.qos}');
      });
    
    final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
    builder.addString(message);

    print('EXAMPLE::Subscribing to topic');
    client.subscribe(Constants.topicName, MqttQos.exactlyOnce);

    print('MQTTClientWrapper::Publishing message $message to topic ${Constants.topicName}');
    client.publishMessage(Constants.topicName, MqttQos.exactlyOnce, builder.payload);
  
    print('EXAMPLE::Sleeping....');
    await MqttUtilities.asyncSleep(120);
  
    print('EXAMPLE::Unsubscribing');
    client.unsubscribe(Constants.topicName);

    await MqttUtilities.asyncSleep(2);
    print('EXAMPLE::Disconnecting');
    client.disconnect();
  }

  void _onSubscribed(String topic) {
    print('MQTTClientWrapper::Subscription confirmed for topic $topic');
    subscriptionState = MqttSubscriptionState.SUBSCRIBED;
  }

  void _onDisconnected() {
    print('MQTTClientWrapper::OnDisconnected client callback - Client disconnection');
    if (client.connectionStatus.disconnectionOrigin == MqttDisconnectionOrigin.solicited) {
      print('MQTTClientWrapper::OnDisconnected callback is solicited, this is correct');
    }
    connectionState = MqttCurrentConnectionState.DISCONNECTED;
    exit(-1);
  }

  void _onConnected() {
    connectionState = MqttCurrentConnectionState.CONNECTED;
    print(
        'MQTTClientWrapper::OnConnected client callback - Client connection was sucessful');
    onConnectedCallback();
  }

}

这是我得到的错误:

Launching lib\main.dart on Android SDK built for x86 in debug mode...
package:publish_hp/main.dart:1
√ Built build\app\outputs\flutter-apk\app-debug.apk.
Connecting to VM Service at ws://127.0.0.1:56651/pQyStOIm6Cw=/ws
D/EGL_emulation(17695): eglMakeCurrent: 0xe6fb7d40: ver 2 0 (tinfo 0xdbb4fcc0)
D/eglCodecCommon(17695): setVertexArrayObject: set vao to 0 (0) 1 0
I/flutter (17695): MQTTClientWrapper::Mosquitto client connecting....
E/flutter (17695): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'connect' was called on null.
E/flutter (17695): Receiver: null
E/flutter (17695): Tried calling: connect()

我的应用基于此:

https://medium.com/swlh/using-mqtt-with-flutter-to-build-a-location-sharing-app-24e7307b21d3

但我将其更改为 mqttserverclient,因为我在尝试按原样阅读文章时遇到了不正确的实例化错误。

关于如何解决这个问题有什么建议吗?

首先,您需要初始化 MqttClient。现在,那是空的,问题是。您可以使用以下示例修复它:

 MqttServerClient client = MqttServerClient.withPort('yourServer.com', 'clientIdentifier', maxConnectionAttempts);

更多可以看here.