Skyost / Bonsoir

A Zeroconf library that allows you to discover network services and to broadcast your own. Based on Apple Bonjour and Android NSD.
http://bonsoir.skyost.eu/
Other
100 stars 43 forks source link

Running multiple instances of BonsoirDisvoery on Android #54

Closed foxik0169 closed 7 months ago

foxik0169 commented 11 months ago

Describe the bug When multiple instances of BonsoirDiscovery with different type are running at the same time, the Android implementation doesn't correctly synchronize the resolution process. Two resolution requests can be issued to NsdManager (even for the same device name) which always fails with error 3. Resolver class is properly synchronized only when one instance is present.

To Reproduce Steps to reproduce the behavior:

  1. Edit example project to use two instances of BonsoirDiscovery with two different types.
  2. Broadcast both of the types (tested in a way that one device is broadcasting both types).
  3. Build & run on Android.
  4. One resolve of the device will work, the other will result in error 3.

Expected behavior Both instances of BonsoirDiscovery should resolve the devices correctly.

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context Looking at the code, each instance of BonsoirDiscovery creates it's own Resolver instance. This is fine but the call to nsdManager.resolve() have to be synchronized globally - only one instance can call nsdManager.resolveService() at a time.

Skyost commented 11 months ago

Thanks for reporting ! Would you mind to create a PR ?

foxik0169 commented 11 months ago

Sure. However I am not used to Kotlin language that much so It might not be the best way of doing this type of thing in this language.

I've fixed it locally by creating a companion object that contains the AtomicBoolean and also mutableSet of function references (like event in C#) that are called when any of the instances finishes processing it's queue. Maybe this could be done in a way that there is only one queue in the companion object? Not sure what are the possibilities in Kotlin.

Another way would be to keep list of all Resolver instances and just call "canProcessPending()" when instance is finished. Anyhow I will create the PR with something and we can discuss there.

Skyost commented 11 months ago

Great !

Skyost commented 7 months ago

Fixed in 63a498e2826e4fea78c62f1fe879769ce4ac3bc6.