Add multicast failover

This commit is contained in:
Santiago Lo Coco 2024-10-30 23:36:02 +01:00
parent 5dbf0cc55b
commit fea0c7c29c
3 changed files with 66 additions and 30 deletions

View File

@ -1846,6 +1846,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
webView1: {fileID: 323128546}
webView2: {fileID: 781542341}
serviceDiscovery: {fileID: 1389755618}
--- !u!1 &504187403
GameObject:
m_ObjectHideFlags: 0
@ -4827,7 +4828,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c3ce81ebd33ef3d46b8bc545525b82fa, type: 3}
m_Name:
m_EditorClassIdentifier:
endpointLoader: {fileID: 491721038}
--- !u!1 &1517812034
GameObject:
m_ObjectHideFlags: 0

View File

@ -10,8 +10,10 @@ public class EndpointLoader : MonoBehaviour
{
public WebView webView1;
public WebView webView2;
public ServiceDiscovery serviceDiscovery;
private string apiUrl = "http://windows.local:5000/api/endpoints";
private bool triedMulticast = false;
private string apiUrl = "http://windows.loca:5000/api/endpoints";
private const string defaultEndpoint1 = "http://windows.local:8100/mystream/";
private const string defaultEndpoint2 = "http://windows.local:8200/mystream/";
@ -30,8 +32,9 @@ public class EndpointLoader : MonoBehaviour
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError($"Error loading endpoints: {request.error}. Using default endpoints");
UseDefaultEndpoints();
Debug.LogWarning($"Error loading endpoints: {request.error}");
StartListeningForMulticast();
yield break;
}
@ -43,8 +46,8 @@ public class EndpointLoader : MonoBehaviour
if (endpoints.Length == 0)
{
Debug.LogError("Parsed endpoints are empty. Using default endpoints");
UseDefaultEndpoints();
Debug.LogError("Parsed endpoints are empty.");
StartListeningForMulticast();
}
else
{
@ -53,8 +56,28 @@ public class EndpointLoader : MonoBehaviour
}
}
private void StartListeningForMulticast()
{
if (triedMulticast)
{
Debug.LogWarning("Multicast also failed. Using default endpoints.");
UseDefaultEndpoints();
return;
}
Debug.Log("Starting multicast discovery for endpoints");
triedMulticast = true;
serviceDiscovery.StartListening((ipAddress, port) =>
{
apiUrl = $"http://{ipAddress}:{port}/api/endpoints";
StartCoroutine(LoadEndpoints());
});
}
public void ReloadEndpoints()
{
triedMulticast = false;
StartCoroutine(LoadEndpoints());
}
@ -64,15 +87,6 @@ public class EndpointLoader : MonoBehaviour
webView2.Load(defaultEndpoint2);
}
public void UpdateApiUrl(string newApiUrl)
{
if (!string.IsNullOrEmpty(newApiUrl))
{
Debug.Log($"Updating API URL to {newApiUrl}");
apiUrl = newApiUrl;
}
}
[Serializable]
public class Endpoint
{

View File

@ -3,22 +3,22 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using UnityEngine;
public class ServiceDiscovery : MonoBehaviour
{
public EndpointLoader endpointLoader;
private UdpClient udpClient;
private const int multicastPort = 5353;
private Action<string, string> action;
private string receivedIp;
private string receivedPort;
private bool messageReceived = false;
private const string multicastAddress = "224.0.0.251";
private const int multicastPort = 5353;
private void Start()
{
// StartListening();
}
private void StartListening()
public void StartListening(Action<string, string> action)
{
try
{
@ -27,6 +27,8 @@ public class ServiceDiscovery : MonoBehaviour
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, multicastPort));
udpClient.JoinMulticastGroup(IPAddress.Parse(multicastAddress));
this.action = action;
Debug.Log("Listening for service announcements...");
udpClient.BeginReceive(OnReceive, null);
@ -39,6 +41,11 @@ public class ServiceDiscovery : MonoBehaviour
private void OnReceive(IAsyncResult result)
{
if (udpClient == null)
{
return;
}
try
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, multicastPort);
@ -51,10 +58,16 @@ public class ServiceDiscovery : MonoBehaviour
if (parts.Length == 3 && IPAddress.TryParse(parts[1], out IPAddress ip))
{
int port = int.Parse(parts[2]);
ConnectToService(ip.ToString(), port);
}
receivedIp = ip.ToString();
receivedPort = port.ToString();
messageReceived = true;
// udpClient.BeginReceive(OnReceive, null);
StopListening();
}
else
{
udpClient?.BeginReceive(OnReceive, null);
}
}
catch (Exception ex)
{
@ -62,16 +75,25 @@ public class ServiceDiscovery : MonoBehaviour
}
}
private void ConnectToService(string ipAddress, int port)
private void Update()
{
Debug.Log($"Connecting to service at {ipAddress}:{port}");
endpointLoader.UpdateApiUrl($"http://{ipAddress}:{port}/api/endpoints");
if (messageReceived)
{
action?.Invoke(receivedIp, receivedPort);
messageReceived = false;
}
}
private void OnApplicationQuit()
{
StopListening();
}
private void StopListening()
{
udpClient?.DropMulticastGroup(IPAddress.Parse(multicastAddress));
udpClient?.Close();
udpClient = null;
}
}