This may be an issue or just a question.
We have a situation where we have to poll a device characteristic for some data. Multiple clients may be in range and do the same polling, which could mean one phone is currently connected while another one also tries to connect. The target may also be turned off so that it's not available at all.
On Android, connecting while it's busy or turned off fails with an error after about 5 seconds. On iOS it can wait for several minutes then finally resolve as soon as the target is available again. Log example:
11:06:52 Reading...
11:06:52 Successfully read!
11:07:00 Reading...
11:09:54 Successfully read! <-- Note the timestamp
I also tried waiting for about 10 minutes; the connection seemed to actually hang there and any subsequent connection attempts resulted in an error, I'm guessing because a connection was already underway.
Android log example, what's expected:
11:24:19 Reading...
11:24:20 Successfully read!
11:24:25 Reading...
11:24:30 Unknown error: BleDisconnectedException{bluetoothDeviceAddress='ABC'}
11:24:35 Reading...
11:24:41 Unknown error: BleDisconnectedException{bluetoothDeviceAddress='ABC'}
11:24:46 Reading...
11:24:51 Unknown error: BleDisconnectedException{bluetoothDeviceAddress='ABC'}
11:24:56 Reading...
11:24:57 Successfully read!
Is this a known iOS behavior?
iOS native module doesn't contain any connection timeout. On Android it is probably defined by vendor, but I'm not sure about it (@dariuszseweryn will know). I think that we can add optional timeout property to connectionOptions object in next version of library. Until this is done you can always use cancelConnection function which will also cancel currently pending connect promises.
Thanks for the quick response! A native timeout option would definitely be welcome. We'll do the manual cancellation until then.
Android OS in direct connection mode (autoConnect=false) usually timeouts after 30 seconds (with status=133). Maybe in the above log there is a situation that the Android BLE stack notices that the peripheral to be connected is busy communicating a different device and returns prematurely?
When autoConnect=true then no timeout is applicable and the connection may succeed after an arbitrary period of time (usually much longer than in direct mode).
Background behaviour of the application is a different topic though especially on Android >= 7.0.
@dariuszseweryn Yeah I guess the behavior can differ between vendors like Cierpliwy said (we're using a mid-range Samsung for testing). So iOS seems to be in something like auto connect mode by default? Would setting autoConnect=true for Android affect anything more than the timeout, like automatic reconnect after disconnect or things like that? We only want to do a quick connect-read-disconnect.
Could you elaborate a bit on background behavior? It's something we will explore for a future version so knowing any caveats beforehand would be useful!
autoConnect=true does two things:
autoConnect=false). I have seen situations that it took more than 5-10 minutes even if devices had been right beside each other.As for the background behaviour I encourage you to read the documentation or check some other articles as this is a complex topic and it is hard to condensate everything into a single post.
I see, in that case we should not use it then. Thanks for the info!
I wonder if we could add 30 sec timeout by default and make autoConnect option to keep connection endlessly on iOS (current behaviour). @dariuszseweryn
We have two options to make the behaviour similar:
autoConnect or equavilent as an option but mark that on Android it takes a lot longer time to connect this way and it is more susceptible to bugs on the system side)Since 0.9 there is timeout option in connectToDevice function.