From 5175e68b994b8b9407896f0b587dff0994be00b5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 17 Aug 2015 22:38:01 -0700 Subject: [PATCH] Fix some issues with the new behavior of jmDNS 3.4.2 --- .../nvstream/mdns/MdnsDiscoveryAgent.java | 95 +++++++++++-------- 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/moonlight-common/src/com/limelight/nvstream/mdns/MdnsDiscoveryAgent.java b/moonlight-common/src/com/limelight/nvstream/mdns/MdnsDiscoveryAgent.java index b85484a2..97d340ca 100644 --- a/moonlight-common/src/com/limelight/nvstream/mdns/MdnsDiscoveryAgent.java +++ b/moonlight-common/src/com/limelight/nvstream/mdns/MdnsDiscoveryAgent.java @@ -1,6 +1,5 @@ package com.limelight.nvstream.mdns; -import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.Inet4Address; import java.net.InetAddress; @@ -13,6 +12,7 @@ import java.util.TimerTask; import javax.jmdns.JmmDNS; import javax.jmdns.ServiceEvent; +import javax.jmdns.ServiceInfo; import javax.jmdns.ServiceListener; import com.limelight.LimeLog; @@ -29,11 +29,15 @@ public class MdnsDiscoveryAgent { public void serviceAdded(ServiceEvent event) { LimeLog.info("mDNS: Machine appeared: "+event.getInfo().getName()); - // This machine is pending resolution until we get the serviceResolved callback - pendingResolution.add(event.getInfo().getName()); + ServiceInfo[] infos = resolver.getServiceInfos(SERVICE_TYPE, event.getInfo().getName(), 500); + if (infos == null || infos.length == 0) { + // This machine is pending resolution + pendingResolution.add(event.getInfo().getName()); + return; + } - // We call this to kick the resolver - resolver.requestServiceInfo(SERVICE_TYPE, event.getInfo().getName()); + LimeLog.info("mDNS: Resolved (blocking) with "+infos.length+" service entries"); + handleResolvedServiceInfo(infos[0]); } public void serviceRemoved(ServiceEvent event) { @@ -52,42 +56,45 @@ public class MdnsDiscoveryAgent { } public void serviceResolved(ServiceEvent event) { - MdnsComputer computer; - - LimeLog.info("mDNS: Machine resolved: "+event.getInfo().getName()); - - pendingResolution.remove(event.getInfo().getName()); - - try { - computer = parseMdnsResponse(event); - if (computer == null) { - LimeLog.info("mDNS: Invalid response for machine: "+event.getInfo().getName()); - return; - } - } catch (UnsupportedEncodingException e) { - // Invalid DNS response - LimeLog.info("mDNS: Invalid response for machine: "+event.getInfo().getName()); - return; - } - - synchronized (computers) { - if (computers.put(computer.getAddress(), computer) == null) { - // This was a new entry - listener.notifyComputerAdded(computer); - } - } + LimeLog.info("mDNS: Machine resolved (callback): "+event.getInfo().getName()); + handleResolvedServiceInfo(event.getInfo()); } }; - private static MdnsComputer parseMdnsResponse(ServiceEvent event) throws UnsupportedEncodingException { - Inet4Address addrs[] = event.getInfo().getInet4Addresses(); + private void handleResolvedServiceInfo(ServiceInfo info) { + MdnsComputer computer; + + pendingResolution.remove(info.getName()); + + try { + computer = parseServerInfo(info); + if (computer == null) { + LimeLog.info("mDNS: Invalid response for machine: "+info.getName()); + return; + } + } catch (UnsupportedEncodingException e) { + // Invalid DNS response + LimeLog.info("mDNS: Invalid response for machine: "+info.getName()); + return; + } + + synchronized (computers) { + if (computers.put(computer.getAddress(), computer) == null) { + // This was a new entry + listener.notifyComputerAdded(computer); + } + } + } + + private static MdnsComputer parseServerInfo(ServiceInfo info) throws UnsupportedEncodingException { + Inet4Address addrs[] = info.getInet4Addresses(); if (addrs.length == 0) { - LimeLog.info("Missing addresses"); + LimeLog.info("mDNS: "+info.getName()+" is missing addresses"); return null; } Inet4Address address = addrs[0]; - String name = event.getInfo().getName(); + String name = info.getName(); return new MdnsComputer(name, address); } @@ -100,8 +107,6 @@ public class MdnsDiscoveryAgent { public void startDiscovery(final int discoveryIntervalMs) { stop = false; - resolver = JmmDNS.Factory.getInstance(); - resolver.addServiceListener(SERVICE_TYPE, nvstreamListener); final Timer t = new Timer(); t.schedule(new TimerTask() { @@ -113,16 +118,22 @@ public class MdnsDiscoveryAgent { // There will be no further timer invocations now t.cancel(); - // Close the resolver if (resolver != null) { - try { - resolver.close(); - } catch (IOException e) {} + resolver.removeServiceListener(SERVICE_TYPE, nvstreamListener); resolver = null; } return; } + // Perform initialization + if (resolver == null) { + resolver = JmmDNS.Factory.getInstance(); + + // This will cause the listener to be invoked for known hosts immediately. + // We do this in the timer callback to be off the main thread when this happens. + resolver.addServiceListener(SERVICE_TYPE, nvstreamListener); + } + // Send another mDNS query resolver.requestServiceInfo(SERVICE_TYPE, null, discoveryIntervalMs); @@ -130,7 +141,11 @@ public class MdnsDiscoveryAgent { ArrayList pendingNames = new ArrayList(pendingResolution); for (String name : pendingNames) { LimeLog.info("mDNS: Retrying service resolution for machine: "+name); - resolver.requestServiceInfo(SERVICE_TYPE, name); + ServiceInfo[] infos = resolver.getServiceInfos(SERVICE_TYPE, name, 500); + if (infos != null && infos.length != 0) { + LimeLog.info("mDNS: Resolved (retry) with "+infos.length+" service entries"); + handleResolvedServiceInfo(infos[0]); + } } } }