RxAndroidBle: Coroutines — Large NOTIFY gets unbearably slow
Original topic:
Large NOTIFY gets unbearably slow
Summary
In my project, I’m connecting to a device that transfers a relatively large amount of data (up to 16MB) via a characteristic’s NOTIFY
. The equivalent code on iOS works fine, however on Android, using RxAndroidBle, it slows down to an unbearably slow speed the more data it receives.
MTU is set properly, and ends up being 247 (250 - 3b header), which is the maximum supported on the devices. iOS uses a lower MTU, 162 (165 - 3b header).
I’ve tried requesting lower MTU to see if it helps, to no avail.
The code is pretty simple, after the connection is established (using ReplayingShare
), it creates the subscription via setupNotification
.
The transfer starts out with pretty decent speed, 1MB takes around 1 minute to sync, however around 3MB received, the speed drops, and the next MB takes 2 minutes, the next MB then 3-4 minutes, and the transfer time keeps creeping up.
Initially I thought it was my fault, as I was storing the data the worst possible way:
var rawData = ByteArray(0)
// in the subscribe block:
rawData += it
However even after removing the storage of the data, the slow-down still happens.
Library version
1.10.4
Preconditions
Steps to reproduce actual result
Not sure if it’s reproducible as I have not seen any devices that use a similar technique to transfer data stored on them.
Actual result
The speed of the transfer drops exponentially (or rather, the amount of time required to transfer the same amount of data increases exponentially). The time between the logged Transferred $x out of $y
events also increases (initially it’s around 10-20ms between messages, which increases to around 100-120ms by the time I transferred ~3MB).
Expected result
Speed should be somewhat constant, with minimum variation between the times required to transfer the same sized blocks.
Minimum code snippet reproducing the issue
var transferred = 0
connection
?.flatMap { it.setupNotification(id) }
?.flatMap { it }
?.subscribe(
{
transferred += it.size
logger.i("[DataSync] Transferred $transferred out of $available")
},
{ logger.e(it, "[DataSync] Exception happened") },
{ logger.i("[DataSync] Transfer complete!") }
)
.addToEventStream(eventStream)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 31 (16 by maintainers)
Ah, indeed you’re right. Multiple sources suggested that writing the descriptor with
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
value will also triggersetCharacteristicNotification()
internally. This is not the case. All is working fine now, I will be reporting back sometime next week to see if this actually improves transfer speeds!