dotintent / FlutterBleLib

Bluetooth Low Energy library for Flutter with support for simulating peripherals
Apache License 2.0
535 stars 195 forks source link

how to cleanup graciously #520

Open Matrix-Zhang opened 3 years ago

Matrix-Zhang commented 3 years ago

my code, often have exception

  Future<void> _doDisconnect() async {
    if (null != _dataMonitor) {
      await _dataMonitor.cancel();
    }

    if (await widget._bleDevice.isConnected()) {
      await widget._bleDevice.disconnect();
    }
E/flutter (22646): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: BleError (Error code: 201, ATT error code: 0, iOS error code: null, Android error code: null, reason: Disconnected from 55:B0:4C:0F:54:C2 with status 0 (GATT_SUCCESS), internal message: null, device ID: 55:B0:4C:0F:54:C2, service UUID: null, characteristic UUID: null, descriptor UUID: null)
E/flutter (22646): #0      CharacteristicsMixin._throwErrorIfMatchesWithTransactionId (package:flutter_ble_lib/src/bridge/characteristics_mixin.dart:287:7)
E/flutter (22646): #1      CharacteristicsMixin._createMonitoringStream.<anonymous closure> (package:flutter_ble_lib/src/bridge/characteristics_mixin.dart:247:13)
E/flutter (22646): #2      _invokeErrorHandler (dart:async/async_error.dart:16:24)
E/flutter (22646): #3      _HandleErrorStream._handleError (dart:async/stream_pipe.dart:282:9)
E/flutter (22646): #4      _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:161:13)
E/flutter (22646): #5      _rootRunBinary (dart:async/zone.dart:1214:47)
E/flutter (22646): #6      _CustomZone.runBinary (dart:async/zone.dart:1107:19)
E/flutter (22646): #7      _CustomZone.runBinaryGuarded (dart:async/zone.dart:1013:7)
E/flutter (22646): #8      _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:376:15)
E/flutter (22646): #9      _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:394:16)
E/flutter (22646): #10     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:294:7)
E/flutter (22646): #11     _ForwardingStreamSubscription._addError (dart:async/stream_pipe.dart:132:11)
E/flutter (22646): #12     _ForwardingStream._handleError (dart:async/stream_pipe.dart:97:10)
E/flutter (22646): #13     _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:161:13)
E/flutter (22646): #14     _rootRunBinary (dart:async/zone.dart:1214:47)
E/flutter (22646): #15     _CustomZone.runBinary (dart:async/zone.dart:1107:19)
E/flutter (22646): #16     _CustomZone.runBinaryGuarded (dart:async/zone.dart:1013:7)
E/flutter (22646): #17     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:376:15)
E/flutter (22646): #18     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:394:16)
E/flutter (22646): #19     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:294:7)
E/flutter (22646): #20     _ForwardingStreamSubscription._addError (dart:async/stream_pipe.dart:132:11)
E/flutter (22646): #21     _ForwardingStream._handleError (dart:async/stream_pipe.dart:97:10)
E/flutter (22646): #22     _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:161:13)
E/flutter (22646): #23     _rootRunBinary (dart:async/zone.dart:1214:47)
E/flutter (22646): #24     _CustomZone.runBinary (dart:async/zone.dart:1107:19)
E/flutter (22646): #25     _CustomZone.runBinaryGuarded (dart:async/zone.dart:1013:7)
E/flutter (22646): #26     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:376:15)
E/flutter (22646): #27     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:394:16)
E/flutter (22646): #28     _DelayedError.perform (dart:async/stream_impl.dart:622:14)
E/flutter (22646): #29     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:730:11)
E/flutter (22646): #30     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:687:7)
E/flutter (22646): #31     _rootRun (dart:async/zone.dart:1182:47)
E/flutter (22646): #32     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (22646): #33     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (22646): #34     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/flutter (22646): #35     _rootRun (dart:async/zone.dart:1190:13)
E/flutter (22646): #36     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (22646): #37     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (22646): #38     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/flutter (22646): #39     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (22646): #40     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/flutter (22646): 
ride4sun commented 3 years ago

I have the same problem and it would be cool to get some advice on good design. I also have a problem when I do disconnect that 50% of the times I can not connect anymore and I get a PlatformError. The examples are not really helpful with a normal setup.

mikolak commented 3 years ago

Hi!

We have a bug with some of the streams. I've made a bad, uninformed decision making the streams asynchronous, which causes the cancel function to be asynchronous as well (it returns immediately without awaiting the proper clean up). This needs to be fixed, while maintaining potential back compatibility (possible optional argument asBroadcast defaulting to true), but sadly I have we don't have free processing power right now.

@ride4sun can you paste the platform error? Is it possible that you're destroying the client? What platform are you testing on?

Could you guys add some thoughts as to what would be a good, simple example to this issue https://github.com/Polidea/FlutterBleLib/issues/443 ?

ride4sun commented 3 years ago

This what I am seeing very often. A fast fix for that would be very appreciated because this renders our app almost not useable. PlatformException(2, null, {"errorCode":2,"attErrorCode":null,"androidErrorCode":null})

This is the Callstack

StandardMethodCodec.decodeEnvelope (message_codecs.dart:572)
MethodChannel._invokeMethod (platform_channel.dart:161)
<asynchronous gap>
MethodChannel.invokeMethod (platform_channel.dart:334)
CharacteristicsMixin.writeCharacteristicForIdentifier (characteristics_mixin.dart:82)
InternalBleManager.writeCharacteristicForIdentifier (internal_ble_manager.dart:233)
Characteristic.write (characteristic.dart:78)
BLELibBloc.init.<anonymous closure>.<anonymous closure> (flutter_ble_lib_bloc.dart:58)
_AsyncAwaitCompleter.start (async_patch.dart:55)
BLELibBloc.init.<anonymous closure>.<anonymous closure> (flutter_ble_lib_bloc.dart:52)
_rootRunUnary (zone.dart:1198)
_rootRunUnary (zone.dart:1)
_CustomZone.runUnary (zone.dart:1100)
_CustomZone.runUnaryGuarded (zone.dart:1005)
_BufferingStreamSubscription._sendData (stream_impl.dart:357)
_DelayedData.perform (stream_impl.dart:611)
_StreamImplEvents.handleNext (stream_impl.dart:730)
_PendingEvents.schedule.<anonymous closure> (stream_impl.dart:687)
_rootRun (zone.dart:1182)
_rootRun (zone.dart:1)
_CustomZone.run (zone.dart:1093)
_CustomZone.runGuarded (zone.dart:997)
_CustomZone.bindCallbackGuarded.<anonymous closure> (zone.dart:1037)
_rootRun (zone.dart:1190)
_rootRun (zone.dart:1)
_CustomZone.run (zone.dart:1093)
_CustomZone.runGuarded (zone.dart:997)
_CustomZone.bindCallbackGuarded.<anonymous closure> (zone.dart:1037)
_microtaskLoop (schedule_microtask.dart:41)
_startMicrotaskLoop (schedule_microtask.dart:50)
_startMicrotaskLoop (schedule_microtask.dart:1)
LEMUSADR000 commented 3 years ago

@mikolak were you able to get a fix for this? If not, is there any 'good enough' catch alls that will allow it to at least not throw an exception?

LEMUSADR000 commented 3 years ago

I can help, if needed. But I'll need some understanding of the bug and what it affects.

ride4sun commented 3 years ago

I am still see the defect and desperately waiting for a fix. Did the info I provided help?

On Mon, Mar 1, 2021, 18:05 Adrian Lemus notifications@github.com wrote:

I can help, if needed. But I'll need some understanding of the bug and what it affects.

ā€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Polidea/FlutterBleLib/issues/520#issuecomment-788518546, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB3BZ23ZO7BRQOFXPMBKXWDTBRBXDANCNFSM4QRKRSTA .

mikolak commented 3 years ago

Hi!

The proper fix is to make data streams single subscription, which will make cancel() awaitable. On a broadcast stream the cancel is immediately finished, even if the underlying cleanup is still in progress. This is a breaking change and to avoid breaking it there should be an option for the user to choose which stream they get and default it to true, ie. adding a book asBroadcast = true parameter to all functions that need it. I can think of scanning for peripherals and monitoring functions.

This does not address the issue @ride4sun has, I have no idea why an uncaught Dart exception would make a peripheral not able to connect. Code 2 is operation cancelled and it can happen to all async operation that do not have the pair stopX. This is business as usual. You should probably add catchError/onError to your calls and handle any BleErrors.

I won't have as much time for the library right now as Polidea has been sold and can no longer maintain the libraries. I'll try to keep maintaining this, but I'll have a limited time. Transition is possibly in progress.

LEMUSADR000 commented 3 years ago

@mikolak thanks for all of your help/work. It's a shame this package might not be getting maintained anymore.

mikolak commented 3 years ago

Stay tuned, it should be fine and maintained. šŸ™‚

ride4sun commented 3 years ago

@mikolak Is there any news on this. Can not wait to have this work better.

LEMUSADR000 commented 3 years ago

@ride4sun I moved over to https://github.com/PhilipsHue/flutter_reactive_ble.
This current package worked well but there were too many gotchas that I didn't know how to handle well enough. This other package seems pretty plug-and-play and I haven't really had any issues so far with it.

mikolak commented 3 years ago

Related to #487