Skip to content

Commit 2df817a

Browse files
committed
Use zeroconf-java instead of JmDNS
1 parent 7b6fbb7 commit 2df817a

2 files changed

Lines changed: 41 additions & 60 deletions

File tree

core/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@
6363
<version>1.0.2-gdx</version>
6464
</dependency>
6565

66-
<!-- mDNS -->
66+
<!-- Zeroconf -->
6767
<dependency>
68-
<groupId>org.jmdns</groupId>
69-
<artifactId>jmdns</artifactId>
70-
<version>3.5.5</version>
68+
<groupId>xyz.gianlu.zeroconf</groupId>
69+
<artifactId>zeroconf</artifactId>
70+
<version>1.1.0</version>
7171
</dependency>
7272

7373
<!-- H2 (cache) -->

core/src/main/java/xyz/gianlu/librespot/core/ZeroconfServer.java

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
import xyz.gianlu.librespot.common.proto.Authentication;
1313
import xyz.gianlu.librespot.crypto.DiffieHellman;
1414
import xyz.gianlu.librespot.mercury.MercuryClient;
15+
import xyz.gianlu.zeroconf.Service;
16+
import xyz.gianlu.zeroconf.Zeroconf;
1517

1618
import javax.crypto.Cipher;
1719
import javax.crypto.Mac;
1820
import javax.crypto.spec.IvParameterSpec;
1921
import javax.crypto.spec.SecretKeySpec;
20-
import javax.jmdns.JmDNS;
21-
import javax.jmdns.ServiceInfo;
2222
import java.io.Closeable;
2323
import java.io.DataInputStream;
2424
import java.io.IOException;
@@ -82,9 +82,9 @@ public class ZeroconfServer implements Closeable {
8282
private final HttpRunner runner;
8383
private final Session.Inner inner;
8484
private final DiffieHellman keys;
85-
private final JmDNS[] instances;
8685
private final List<SessionListener> sessionListeners;
8786
private volatile Session session;
87+
private final Zeroconf zeroconf;
8888

8989
private ZeroconfServer(Session.Inner inner, Configuration conf) throws IOException {
9090
this.inner = inner;
@@ -97,48 +97,46 @@ private ZeroconfServer(Session.Inner inner, Configuration conf) throws IOExcepti
9797

9898
new Thread(this.runner = new HttpRunner(port), "zeroconf-http-server").start();
9999

100-
InetAddress[] bound;
100+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
101+
try {
102+
close();
103+
} catch (IOException ignored) {
104+
}
105+
}));
106+
107+
List<NetworkInterface> nics;
101108
if (conf.zeroconfListenAll()) {
102-
bound = getAllInterfacesAddresses();
109+
nics = getAllInterfaces();
103110
} else {
104111
String[] interfaces = conf.zeroconfInterfaces();
105112
if (interfaces == null || interfaces.length == 0) {
106-
bound = new InetAddress[]{InetAddress.getLoopbackAddress()};
113+
nics = getAllInterfaces();
107114
} else {
108-
List<InetAddress> list = new ArrayList<>();
109-
for (String str : interfaces) addAddressForInterfaceName(list, str);
110-
bound = list.toArray(new InetAddress[0]);
115+
nics = new ArrayList<>();
116+
for (String str : interfaces) {
117+
NetworkInterface nif = NetworkInterface.getByName(str);
118+
if (nif == null) {
119+
LOGGER.warn(String.format("Interface %s doesn't exists.", str));
120+
continue;
121+
}
122+
123+
checkInterface(nics, nif, true);
124+
}
111125
}
112126
}
113127

114-
LOGGER.debug("Registering service on " + Arrays.toString(bound));
128+
zeroconf = new Zeroconf();
129+
zeroconf.addSendListener(packet -> System.out.println("SEND: " + packet));
130+
zeroconf.addReceiveListener(packet -> System.out.println("RECV: " + packet));
131+
zeroconf.addNetworkInterfaces(nics);
115132

116133
Map<String, String> txt = new HashMap<>();
117134
txt.put("CPath", "/");
118135
txt.put("VERSION", "1.0");
136+
Service service = new Service(inner.deviceName, "spotify-connect", port);
137+
service.setText(txt);
119138

120-
boolean atLeastOne = false;
121-
instances = new JmDNS[bound.length];
122-
for (int i = 0; i < instances.length; i++) {
123-
try {
124-
instances[i] = JmDNS.create(bound[i], bound[i].getHostName());
125-
ServiceInfo serviceInfo = ServiceInfo.create("_spotify-connect._tcp.local.", "librespot-java-" + i, port, 0, 0, txt);
126-
instances[i].registerService(serviceInfo);
127-
atLeastOne = true;
128-
} catch (SocketException ex) {
129-
LOGGER.warn("Failed creating socket for " + bound[i], ex);
130-
}
131-
}
132-
133-
if (atLeastOne) LOGGER.info("SpotifyConnect service registered successfully!");
134-
else throw new IllegalStateException("Could not register the service anywhere!");
135-
136-
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
137-
try {
138-
close();
139-
} catch (IOException ignored) {
140-
}
141-
}));
139+
zeroconf.announce(service);
142140
}
143141

144142
@NotNull
@@ -147,16 +145,6 @@ public static ZeroconfServer create(@NotNull AbsConfiguration conf) throws IOExc
147145
return new ZeroconfServer(Session.Inner.from(conf), conf);
148146
}
149147

150-
private static void addAddressForInterfaceName(List<InetAddress> list, @NotNull String name) throws SocketException {
151-
NetworkInterface nif = NetworkInterface.getByName(name);
152-
if (nif == null) {
153-
LOGGER.warn(String.format("Interface %s doesn't exists.", name));
154-
return;
155-
}
156-
157-
addAddressOfInterface(list, nif, false);
158-
}
159-
160148
private static boolean isVirtual(@NotNull NetworkInterface nif) throws SocketException {
161149
byte[] mac = nif.getHardwareAddress();
162150
if (mac == null) return true;
@@ -174,7 +162,7 @@ private static boolean isVirtual(@NotNull NetworkInterface nif) throws SocketExc
174162
return false;
175163
}
176164

177-
private static void addAddressOfInterface(List<InetAddress> list, @NotNull NetworkInterface nif, boolean checkVirtual) throws SocketException {
165+
private static void checkInterface(List<NetworkInterface> list, @NotNull NetworkInterface nif, boolean checkVirtual) throws SocketException {
178166
if (nif.isLoopback()) return;
179167

180168
if (isVirtual(nif)) {
@@ -184,18 +172,15 @@ private static void addAddressOfInterface(List<InetAddress> list, @NotNull Netwo
184172
LOGGER.warn(String.format("Interface %s is suspected to be virtual, mac: %s", nif.getName(), Utils.bytesToHex(nif.getHardwareAddress())));
185173
}
186174

187-
LOGGER.trace(String.format("Adding addresses of %s {displayName: %s, mac: %s}", nif.getName(), nif.getDisplayName(), Utils.bytesToHex(nif.getHardwareAddress())));
188-
Enumeration<InetAddress> ias = nif.getInetAddresses();
189-
while (ias.hasMoreElements())
190-
list.add(ias.nextElement());
175+
list.add(nif);
191176
}
192177

193178
@NotNull
194-
private static InetAddress[] getAllInterfacesAddresses() throws SocketException {
195-
List<InetAddress> list = new ArrayList<>();
179+
private static List<NetworkInterface> getAllInterfaces() throws SocketException {
180+
List<NetworkInterface> list = new ArrayList<>();
196181
Enumeration<NetworkInterface> is = NetworkInterface.getNetworkInterfaces();
197-
while (is.hasMoreElements()) addAddressOfInterface(list, is.nextElement(), true);
198-
return list.toArray(new InetAddress[0]);
182+
while (is.hasMoreElements()) checkInterface(list, is.nextElement(), true);
183+
return list;
199184
}
200185

201186
@NotNull
@@ -208,11 +193,7 @@ private static Map<String, String> parsePath(@NotNull String path) {
208193

209194
@Override
210195
public void close() throws IOException {
211-
for (JmDNS instance : instances) {
212-
if (instance != null) instance.unregisterAllServices();
213-
}
214-
215-
LOGGER.trace("SpotifyConnect service unregistered successfully.");
196+
zeroconf.close();
216197
runner.close();
217198
}
218199

0 commit comments

Comments
 (0)