From e2b00eaf28da7e94ed8acd61d186594a64869802 Mon Sep 17 00:00:00 2001 From: Santiago Lo Coco Date: Sun, 3 Nov 2024 14:28:53 +0100 Subject: [PATCH] Create a list of mDNS services, dynamically --- Assets/Scripts/EndpointLoader.cs | 25 ++++++++-- Assets/Scripts/ServiceDiscovery.cs | 49 +++++++++----------- Assets/Scripts/ServicesListPopulator.cs | 36 ++++++++++++++ Assets/Scripts/ServicesListPopulator.cs.meta | 11 +++++ 4 files changed, 91 insertions(+), 30 deletions(-) create mode 100644 Assets/Scripts/ServicesListPopulator.cs create mode 100644 Assets/Scripts/ServicesListPopulator.cs.meta diff --git a/Assets/Scripts/EndpointLoader.cs b/Assets/Scripts/EndpointLoader.cs index c646e0d..d954010 100644 --- a/Assets/Scripts/EndpointLoader.cs +++ b/Assets/Scripts/EndpointLoader.cs @@ -11,6 +11,7 @@ public class EndpointLoader : MonoBehaviour public WebView webView1; public WebView webView2; public ServiceDiscovery serviceDiscovery; + public ServicesListPopulator servicesListPopulator; private bool triedMulticast = false; private string apiUrl = "http://windows.loca:5000/api/endpoints"; // Typo on purpose @@ -18,6 +19,7 @@ public class EndpointLoader : MonoBehaviour private const string defaultEndpoint2 = "http://windows.local:8200/mystream/"; private bool defaultEndpoint1Loaded = false; private bool defaultEndpoint2Loaded = false; + private List availableServices = new List(); private void Start() { @@ -108,14 +110,29 @@ public class EndpointLoader : MonoBehaviour Debug.Log("Starting multicast discovery for endpoints"); triedMulticast = true; - serviceDiscovery.StartListening((ipAddress, port) => + serviceDiscovery.StartListening((service) => { - Debug.Log($"Received multicast message: {ipAddress}:{port}"); - apiUrl = $"http://{ipAddress}:{port}/api/endpoints"; - StartCoroutine(LoadEndpoints()); + Debug.Log($"Received multicast message: {service.Host}"); + availableServices.Add(service); + AddServiceToTable(service); }); } + private void AddServiceToTable(MdnsService service) + { + Debug.Log($"Adding service to table: {service.Host}"); + servicesListPopulator.AddItemFromService(service, () => + { + ChangeApiUrl($"http://{service.Host}:{service.Port}{service.Path}"); + }); + } + + public void ChangeApiUrl(string newUrl) + { + apiUrl = newUrl; + StartCoroutine(LoadEndpoints()); + } + public void ReloadEndpoints() { triedMulticast = false; diff --git a/Assets/Scripts/ServiceDiscovery.cs b/Assets/Scripts/ServiceDiscovery.cs index 3483ece..e529788 100644 --- a/Assets/Scripts/ServiceDiscovery.cs +++ b/Assets/Scripts/ServiceDiscovery.cs @@ -10,20 +10,19 @@ using UnityEngine; public class ServiceDiscovery : MonoBehaviour { private UdpClient udpClient; - private Action action; + private Action action; private string receivedIp; private string receivedPort; private string receivedPath; private string receivedHost; - private bool messageReceived = false; private const string multicastAddress = "224.0.0.251"; private const int multicastPort = 5353; public List discoveredServices = new List(); - public void StartListening(Action action) + public void StartListening(Action action) { try { @@ -107,21 +106,22 @@ public class ServiceDiscovery : MonoBehaviour byte[] receivedBytes = udpClient.EndReceive(result, ref remoteEndPoint); ushort flags = BitConverter.ToUInt16(new byte[] { receivedBytes[3], receivedBytes[2] }, 0); - Debug.Log($"Flags: {flags:X2}"); + // Debug.Log($"Flags: {flags:X2}"); if (flags == 0x0100) // Standard query { - Debug.Log("Ignoring non-response packet"); + // Debug.Log("Ignoring non-response packet"); udpClient?.BeginReceive(OnReceive, null); return; } - Debug.Log($"Received message: {receivedBytes} from {remoteEndPoint}"); + // Debug.Log($"Received message: {receivedBytes} from {remoteEndPoint}"); ParseMdnsResponse(receivedBytes); if (receivedIp != null && receivedPort != null) { - // messageReceived = true; // StopListening(); + MdnsService currentService = new MdnsService(receivedIp, int.Parse(receivedPort), receivedPath, receivedHost); + /* MdnsService currentService = new MdnsService { IpAddress = receivedIp, @@ -129,21 +129,17 @@ public class ServiceDiscovery : MonoBehaviour Path = receivedPath, Host = receivedHost }; + */ discoveredServices.Add(currentService); - Debug.Log($"Added service: {currentService.IpAddress}:{currentService.Port}, " + - $"{currentService.Path}, {currentService.Host}"); + Debug.Log($"Added service: http://{currentService.Host}:{currentService.Port}{currentService.Path}"); receivedIp = null; receivedPort = null; receivedPath = null; receivedHost = null; - // receivedIp = receivedHost = receivedPort = receivedPath = null; + + // action?.Invoke(currentService); } - /* - else - { - udpClient?.BeginReceive(OnReceive, null); - } - */ + udpClient?.BeginReceive(OnReceive, null); } catch (Exception ex) @@ -159,7 +155,7 @@ public class ServiceDiscovery : MonoBehaviour ushort answerRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 6)); ushort additionalRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 10)); - Debug.Log($"Questions: {questions}, Answer RRs: {answerRRs}, Additional RRs: {additionalRRs}"); + // Debug.Log($"Questions: {questions}, Answer RRs: {answerRRs}, Additional RRs: {additionalRRs}"); for (int i = 0; i < questions; i++) { @@ -219,7 +215,7 @@ public class ServiceDiscovery : MonoBehaviour if (txtData.Contains("path")) { receivedPath = txtData.Split('=')[1]; - Debug.Log($"Received path: {receivedPath}"); + // Debug.Log($"Received path: {receivedPath}"); } } else if (recordType == 47) // NSEC Record @@ -277,13 +273,14 @@ public class ServiceDiscovery : MonoBehaviour private void Update() { - if (messageReceived) + if (discoveredServices.Count > 0) { - Debug.Log($"Invoking action with: {receivedIp}:{receivedPort}"); - action?.Invoke(receivedIp, receivedPort); - messageReceived = false; - receivedIp = null; - receivedPort = null; + foreach (MdnsService service in discoveredServices) + { + Debug.Log($"Invoking action with: {service}"); + action?.Invoke(service); + } + discoveredServices.Clear(); } } @@ -299,12 +296,12 @@ public class ServiceDiscovery : MonoBehaviour udpClient = null; } - public class MdnsService +/* public class MdnsService { public string IpAddress { get; set; } public int Port { get; set; } public string Path { get; set; } public string Host { get; set; } } -} +*/} diff --git a/Assets/Scripts/ServicesListPopulator.cs b/Assets/Scripts/ServicesListPopulator.cs new file mode 100644 index 0000000..ac105e9 --- /dev/null +++ b/Assets/Scripts/ServicesListPopulator.cs @@ -0,0 +1,36 @@ +using TMPro; +using System; +using System.Collections; +using UnityEngine; +using Microsoft.MixedReality.Toolkit.UI; +using Microsoft.MixedReality.Toolkit.Utilities; + +public class ServicesListPopulator : MonoBehaviour +{ + [SerializeField] + private ScrollingObjectCollection scrollView; + + [SerializeField] + private GameObject dynamicItem; + + [SerializeField] + private GridObjectCollection gridObjectCollection; + + public void AddItemFromService(MdnsService service, Action action) + { + GameObject itemInstance = Instantiate(dynamicItem, gridObjectCollection.transform); + itemInstance.SetActive(true); + + Debug.Log($"Adding service to table: {service}"); + TextMeshPro[] textMeshes = itemInstance.GetComponentsInChildren(); + textMeshes[0].text = service.Host + ":" + service.Port + service.Path; + textMeshes[1].text = service.IpAddress; + itemInstance.GetComponentInChildren().OnClick.AddListener(() => + { + Debug.Log($"Clicked on service: {service.Host}"); + action.Invoke(); + }); + + gridObjectCollection.UpdateCollection(); + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServicesListPopulator.cs.meta b/Assets/Scripts/ServicesListPopulator.cs.meta new file mode 100644 index 0000000..2c5e3a7 --- /dev/null +++ b/Assets/Scripts/ServicesListPopulator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be30c5115f8bf5c4bbb25e5fbb5e9c8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: