From 4c45d71ab39e02d4e6a9aabdd12124a7d7b310e7 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sun, 9 Jun 2024 10:37:13 -0400 Subject: [PATCH] mdn advertise --- src/dist/conf/config.yml | 1 + .../googolplex_theater/ServiceDiscovery.java | 20 +++++++++++++++++-- .../ServiceDiscoveryTest.java | 9 ++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/dist/conf/config.yml b/src/dist/conf/config.yml index e885d71..58e91f9 100644 --- a/src/dist/conf/config.yml +++ b/src/dist/conf/config.yml @@ -12,3 +12,4 @@ # retry-interval: 15s # devices-path: conf/devices.yml # preferred-interface: eth0 +# advertise: true diff --git a/src/main/java/com/jyuzawa/googolplex_theater/ServiceDiscovery.java b/src/main/java/com/jyuzawa/googolplex_theater/ServiceDiscovery.java index 3d68c4c..995cf76 100644 --- a/src/main/java/com/jyuzawa/googolplex_theater/ServiceDiscovery.java +++ b/src/main/java/com/jyuzawa/googolplex_theater/ServiceDiscovery.java @@ -15,10 +15,13 @@ import javax.annotation.PostConstruct; import javax.jmdns.JmDNS; import javax.jmdns.ServiceEvent; +import javax.jmdns.ServiceInfo; import javax.jmdns.ServiceListener; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; /** @@ -30,16 +33,21 @@ @Component public final class ServiceDiscovery implements Closeable { public static final String MDNS_SERVICE_NAME = "_googlecast._tcp.local."; + private static final String MDNS_ADVERTISE_NAME = "_http._tcp.local."; + private static final String MDNS_NAME = "googolplex-theater"; private final GoogolplexService service; private final JmDNS mdns; + private final boolean advertise; @Autowired public ServiceDiscovery( GoogolplexService service, - @Value("${googolplex-theater.preferred-interface:#{null}}") String preferredInterface) + @Value("${googolplex-theater.preferred-interface:#{null}}") String preferredInterface, + @Value("${googolplex-theater.advertise:#{false}}") boolean advertise) throws IOException { this.service = service; + this.advertise = advertise; InetAddress inetAddress = getInterfaceAddress(preferredInterface); if (inetAddress == null) { log.warn("No IP address for service discovery found. Falling back to JmDNS library default."); @@ -49,10 +57,18 @@ public ServiceDiscovery( } @PostConstruct - public void start() { + public void start() throws IOException { this.mdns.addServiceListener(MDNS_SERVICE_NAME, new ServiceDiscoveryListener()); } + @EventListener + public void onApplicationEvent(WebServerInitializedEvent event) throws IOException { + if (advertise) { + int port = event.getWebServer().getPort(); + this.mdns.registerService(ServiceInfo.create(MDNS_ADVERTISE_NAME, MDNS_NAME, port, MDNS_NAME)); + } + } + static InetAddress getInterfaceAddress(String preferredInterface) throws SocketException, UnknownHostException { if (preferredInterface != null) { return getBestInetAddress(getPreferredInterface(preferredInterface)); diff --git a/src/test/java/com/jyuzawa/googolplex_theater/ServiceDiscoveryTest.java b/src/test/java/com/jyuzawa/googolplex_theater/ServiceDiscoveryTest.java index c6606b3..cab9fc6 100644 --- a/src/test/java/com/jyuzawa/googolplex_theater/ServiceDiscoveryTest.java +++ b/src/test/java/com/jyuzawa/googolplex_theater/ServiceDiscoveryTest.java @@ -12,6 +12,8 @@ import java.net.NetworkInterface; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.boot.web.server.WebServer; class ServiceDiscoveryTest { @@ -30,7 +32,12 @@ void preferredInterfaceTest() throws Exception { @Test void instantiationTest() throws IOException { GoogolplexService controller = Mockito.mock(GoogolplexService.class); - ServiceDiscovery sd = new ServiceDiscovery(controller, null); + ServiceDiscovery sd = new ServiceDiscovery(controller, null, true); + WebServerInitializedEvent event = Mockito.mock(WebServerInitializedEvent.class); + WebServer webServer = Mockito.mock(WebServer.class); + Mockito.when(event.getWebServer()).thenReturn(webServer); + Mockito.when(webServer.getPort()).thenReturn(8080); + sd.onApplicationEvent(event); sd.close(); } }