shamblett / mqtt_client

A server and browser based MQTT client for dart
Other
552 stars 179 forks source link

SocketException: Write failed (OS Error: Software caused connection abort, errno = 103), #403

Closed Tate-zwt closed 2 years ago

Tate-zwt commented 2 years ago

When running online, the exception information will be captured, but the port number will be different each time the error is reported. I set the port number to connect to the default MqttClientConstants.defaultMqttPort(port:1883). I thought it was a problem with the automatic reconnection at first, and the automatic reconnection was turned off. but this abnormal information will still be reported. I don't know how to deal with it. Occasionally, in the online environment, the information that MQTT cannot be obtained 。 I hope to get your reply. Thank you! version:mqtt_client: ^9.6.5

error: 
SocketException: Write failed (OS Error: Software caused connection abort, errno = 103), address = [47.118.XXX.XXX](http://47.118.XXX.XXX/), port = 35054 
stackTrace: 
#0      _NativeSocket.write (dart:io-patch/socket_patch.dart:1190)
#1      _RawSocket.write (dart:io-patch/socket_patch.dart:1906)
#2      _Socket._write (dart:io-patch/socket_patch.dart:2346)
#3      _SocketStreamConsumer.write (dart:io-patch/socket_patch.dart:2094)
#4      _SocketStreamConsumer.addStream.<anonymous closure> (dart:io-patch/socket_patch.dart:2068)
#13     _StreamSinkImpl.add (dart:io/io_sink.dart:136)
#14     _Socket.add (dart:io-patch/socket_patch.dart:2193)
#15     MqttServerConnection.send (package:mqtt_client/src/connectionhandling/server/mqtt_client_mqtt_server_connection.dart:95)
#16     MqttConnectionHandlerBase.sendMessage (package:mqtt_client/src/connectionhandling/mqtt_client_mqtt_connection_handler_base.dart)
#17     MqttConnectionKeepAlive.pingRequired (package:mqtt_client/src/connectionhandling/mqtt_client_mqtt_connection_keep_alive.dart:89)
SocketException: Software caused connection abort (OS Error: Software caused connection abort, errno = 103), address = [47.118.XXX.XXX](http://47.118.XXX.XXX/), port = 34780
SocketException: Software caused connection abort (OS Error: Software caused connection abort, errno = 103), address = [47.118.XXX.XXX](http://47.118.XXX.XXX/), port = 34772

connection code:

class MqttKit {
  MqttKit._privateConstructor();
  static final MqttKit _instance = MqttKit._privateConstructor();

  dynamic _config;
  MqttServerClient? client;
  final List<MqttKitMessageCallbackInterface> _messageCallbacks = [];
  bool _isConnect = false;

  static MqttKit get instance {
    return _instance;
  }

  connect() {
    _loadConfig();
  }

  destroy() {
    client?.disconnect();
    _isConnect = false;
  }

  addMessageCallback(MqttKitMessageCallbackInterface callback) {
    _messageCallbacks.add(callback);
  }

  _initMqtt() {
    if (_isConnect || _config == null) {
      return;
    }
    if (_config["ip"] == null && _config["port"] == null) {
      return;
    }
    _isConnect = true;
    client = MqttServerClient.withPort(_config["ip"], _config["client_id"],
        MqttClientConstants.defaultMqttPort);
    client?.keepAlivePeriod = 20;
    client?.autoReconnect = true;
    client?.logging(on: true);

    final connMessage = MqttConnectMessage()
        .authenticateAs(_config["username"], _config["password"])
        .withWillTopic('willtopic')
        .withWillMessage('Will message')
        .startClean()
        .withWillQos(MqttQos.atLeastOnce);
    client?.connectionMessage = connMessage;
    client?.onDisconnected = _onDisconnected;
    client?.onConnected = _onConnected;
    // client?.onAutoReconnect = _autoReconnect;

    client?.onSubscribed = (text) {
      Log.i(text);
    };

    client?.pongCallback = () {
      Log.i("pong");
    };
    client?.connect(_config["username"], _config["password"]);
  }

  _onData(List<MqttReceivedMessage<MqttMessage>> data) {
    Log.i("onData...");
    if (data.length == 1) {
      final recMess = data[0].payload as MqttPublishMessage;
      String pt = const Utf8Decoder().convert(recMess.payload.message);
      try {
        _onMessage(jsonDecode(pt));
      } catch (error, st) {
        Log.i("", error, st);
      }
    }
  }

  _onMessage(dynamic json) async {
    Log.i(json.toString() + "_onMessage");
  }

  _loadConfig() {
    _config = Api.getUserInfo()["mqtt"];
    _initMqtt();
  }

  _onConnected() {
    client?.subscribe(_config["subscribe"], MqttQos.atMostOnce);
    client?.updates?.listen(_onData);
  }

  //断开连接后的操作
  _onDisconnected() {
    Log.i("_onDisconnected");
  }
}
shamblett commented 2 years ago

I'm not sure what your issue is here, this is normal client/server behavior, you connect to the server(MQTT broker in your case) on a known port and the server allocates a port for your client to use, this will be different every time you connect(and across all other connected clients). Normally you do not need to know any of this as the platform network stack handles all this for you.

The exception you are seeing is not raised by the client, its raised by the Dart/flutter runtime so it contains what it contains, I can't affect this at all.

Tate-zwt commented 2 years ago

Thank you for your reply, will this exception affect receiving messages? MQTT is used on Andorid and iOS, and the environment used is the mobile network. Is it abnormal due to poor network?

shamblett commented 2 years ago

Well yes its an exception so if you don't handle it the client will exit, the error you are seeing is usually caused by the client socket being closed wither by the broker or the network layer so it could be down to poor connectivity.

Tate-zwt commented 2 years ago

ok thanks for your reply !