4

Starting with the example http://developer.android.com/training/connect-devices-wirelessly/nsd.html code, I've been building up an app meant to run on multiple devices in the same subnet. Each device registers the same service and tries to discover the others in the subnet with that service. As described in the doc, each time a device registers a service, the name gets mangled with an appended "(N)" where N is an integer. Each device, when it does a discovery ala

public void discoverServices() {
  mNsdManager.discoverServices(
      SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}

finds all the services registered. I track them in a hashmap which retains the discovered NsdServiceInfo record.

The problem comes when I try to resolve them. If I iterate the hashmap and resolve each NsdServiceInfo, only the very first one is successful. I thought that maybe the problem is that a separate NsdManager.ResolveListener is needed, so I create one for each NsdServiceInfo record, but no joy.

If I block the first service in the hashmap from being resolved, the next one works. Here is DDMS output:

07-09 17:11:36.799: D/P2PServiceManager(1958): Resolving services with type : PeerDiscovery
07-09 17:11:36.799: W/P2PServiceManager(1958): Resolving PeerDiscovery services with name : PeerDiscovery (3)
07-09 17:11:36.799: W/P2PServiceManager(1958): Resolving PeerDiscovery services with name : PeerDiscovery (2)
07-09 17:11:36.807: E/P2PServiceManager(1958): RRRRRRRRRRRRRRRRRRR Resolve failed : error code 3
07-09 17:11:36.830: E/P2PServiceManager(1958): RRRRRRRRRRRRRRRRRRR  Resolve Succeeded. name: PeerDiscovery\032(3)type: ._http._udphost: /192.168.1.145port: 53221txtRecord: null

I suspect there is some non-reentrant code or some other similar problem, but am wondering if anyone else has seen this problem. Google and StackOverflow don't seem to have the answer.

[2014-07-24] In the end I stuck with iterating over the discovered services to resolve them, but wait for each result before resolving the next service. I suppose that is the proper way to do things, but it's not clear from the NsdManager doc one way or the other.

eeKnud
  • 96
  • 8

2 Answers2

1

Finally I got the same issue fixed in my app to discover multiple Bonjour devices on the same servicename in my network

What I did:

Activity > Starts Discovery Listener > Starts ResolveListener

Both of them are declared within the same activity and push back a object which i've found by adding it to the list of device objects activity.addDevice(ip, port, name, service);

Now I just get each device on itself instead of overwriting the results in the listener and getting just one or none results.

Hope it helps for someone with the same issues. I will try to prepare a code sample ASAP.

Tomasz
  • 4,847
  • 2
  • 32
  • 41
Wessel van Waas
  • 171
  • 1
  • 7
0

I got similar problem for 2 services I wanted to discover simultaneously. The solution for me was just wait for the first one to resolve or fail and start discovering the next one only afterwards. So that the discovery is not started for both at the same time. One can use for example CountDownLatch for that.

CountDownLatch latch = new CountDownLatch(1);
nsdManager.discoverServices(serviceType1,  NsdManager.PROTOCOL_DNS_SD, discoveryListener);
latch.await();
nsdManager.discoverServices(serviceType2,  NsdManager.PROTOCOL_DNS_SD, discoveryListener);

....

ResolveListener {
    public void onServiceResolved(NsdServiceInfo serviceInfo) {
         // do your stuff
         latch.countDown();
    }
}

don't forget to count down the latch in all failure cases!

akd005
  • 540
  • 4
  • 13