flutter_reactive_ble
flutter_reactive_ble copied to clipboard
Disconnect and Reconnect to device using Notification causes multiple instances of same device
This issue happens after connecting, enabling notifications, then disabling notifications and disconnecting. When reconnecting to the same device, it looks like there are multiple instances of the same device connected. See the screenshot below where I connect and disconnect to the same device three times.
![Screen Shot 2021-05-01 at 7 17 12 PM](https://user-images.githubusercontent.com/76078821/116797266-e69e4f00-aab1-11eb-85b8-258faacbc359.png)
I am turning off notifications and awaiting a timer before disconnecting, but this has no effect:
class BleDeviceConnector extends ReactiveState<ConnectionStateUpdate> {
BleDeviceConnector(this._ble);
final FlutterReactiveBle _ble;
final _deviceConnection = StreamController<ConnectionStateUpdate>.broadcast();
@override
Stream<ConnectionStateUpdate> get state => _deviceConnection.stream;
StreamSubscription<ConnectionStateUpdate> _connection;
StreamSubscription<List<int>> _notifications;
Future<void> connect(String deviceId) async {
_deviceConnection.add(ConnectionStateUpdate(
deviceId: deviceId,
connectionState: DeviceConnectionState.connecting,
failure: null));
if (_connection != null) {
await _connection.cancel();
}
_connection = _ble
.connectToDevice(id: deviceId)
.listen((update) => _deviceConnection.add(update));
}
Future<StreamSubscription<List<int>>> startNotification(
QualifiedCharacteristic characteristic) async {
if (_notifications != null) {
await _notifications.cancel();
}
_notifications =
_ble.subscribeToCharacteristic(characteristic).listen((data) {},
onDone: () => print('stream event done'),
onError: (dynamic error) {
print('Start Notification returns Error: $error');
});
return _notifications;
}
Future<void> disconnect(String deviceId) async {
_deviceConnection.add(ConnectionStateUpdate(
deviceId: deviceId,
connectionState: DeviceConnectionState.disconnecting,
failure: null));
if (_connection != null) {
try {
if (_notifications != null) {
await _notifications.cancel().whenComplete(() async {
_notifications = null;
await Future.delayed(Duration(milliseconds: 5000));
});
}
await _connection.cancel().whenComplete(() {
_connection = null;
});
} on Exception catch (e, _) {
print("Error disconnecting from a device: $e");
} finally {
// Since [_connection] subscription is terminated, the "disconnected" state cannot be received and propagated
_deviceConnection.add(
ConnectionStateUpdate(
deviceId: deviceId,
connectionState: DeviceConnectionState.disconnected,
failure: null,
),
);
}
}
}
Future<void> discoverServices(String deviceId) async {
await _ble.discoverServices(deviceId).then(
(value) => print('Services discovered: $value'),
);
}
Future<void> dispose() async {
await _deviceConnection.close();
}
}
Is there something I may be missing as far as closing out stream subscriptions?
Thanks for reporting! I can reproduce this behavior on the example app looks like something is going wrong.
Are there any updates on this? I am experiencing the same behaviour
I think this issue may be related to the issue I am experiencing: When I disconnect from a peripheral i cannot instantly reconnect to it, it takes about 15-20 seconds to work again. But if I close the app completely and reopen it it works in an instant.
is there anything new here? unfortunately, i am observing the same behavior right now.
looks like the problem is:
flutterReactiveBle
.connectToAdvertisingDevice(
id: discoveredDevice.id,
withServices: <Uuid>[deviceInformationService],
prescanDuration: scanAndConnectionTime,
connectionTimeout: scanAndConnectionTime)
Returns a stream. Cancel the stream does not disconnect from device (see also: #597 ). so it is necessary to reuse the subscription for the same device, otherwise there will be a second subscription to the device and you will receive all events multiple times.