-
Notifications
You must be signed in to change notification settings - Fork 198
Description
When using Peripheral.monitorCharacteristic(...) we get a Stream.
When we cancel that stream, the monitoring should be fully cancelled (ie, native resources cleaned up) after we await on the cancelling of the stream. However, the actual cleanup of resources is performed asynchronously.
final notification = device.monitorCharacteristic(
SERVICE,
CHARACTERISTIC,
)
.first; // This turns the Stream into a Future. Upon completion of the future, the stream subscription is canceled.
final result = await notification;
print('after cancel');
Log output:
D/com.polidea.flutter_ble_lib.FlutterBleLibPlugin(29627): on native side observed method: monitorCharacteristicForDevice
D/BluetoothGatt(29627): setCharacteristicNotification() - uuid: 0000ac49-53a6-4f72-96c8-fd6e6964bae3 enable: true
I/flutter (29627): after cancel
D/com.polidea.flutter_ble_lib.FlutterBleLibPlugin(29627): on native side observed method: cancelTransaction
Note that the after cancel message is logged before the cancelTransaction was observed, whereas it should be logged after.
The root cause is that the stream returned from monitorCharacteristic is a broadcast stream, not a single subscription stream.
characteristics_mixin.dart - _createMonitoringStream:
StreamController<CharacteristicWithValue> streamController =
StreamController.broadcast(
onListen: onListen,
onCancel: () => cancelTransaction(transactionId),
);
This means that the onCancel callback does not return a Future - it just asynchronously tries to clean up resources.
I believe that the monitoring stream should be a single subscription stream. If consumers wish to have multiple subscribers, they can always convert the single subscription stream into a broadcast stream in their application logic.