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

View File

@ -10,8 +10,10 @@ public class EndpointLoader : MonoBehaviour
{ {
public WebView webView1; public WebView webView1;
public WebView webView2; 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 defaultEndpoint1 = "http://windows.local:8100/mystream/";
private const string defaultEndpoint2 = "http://windows.local:8200/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) if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
{ {
Debug.LogError($"Error loading endpoints: {request.error}. Using default endpoints"); Debug.LogWarning($"Error loading endpoints: {request.error}");
UseDefaultEndpoints();
StartListeningForMulticast();
yield break; yield break;
} }
@ -43,8 +46,8 @@ public class EndpointLoader : MonoBehaviour
if (endpoints.Length == 0) if (endpoints.Length == 0)
{ {
Debug.LogError("Parsed endpoints are empty. Using default endpoints"); Debug.LogError("Parsed endpoints are empty.");
UseDefaultEndpoints(); StartListeningForMulticast();
} }
else 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() public void ReloadEndpoints()
{ {
triedMulticast = false;
StartCoroutine(LoadEndpoints()); StartCoroutine(LoadEndpoints());
} }
@ -64,15 +87,6 @@ public class EndpointLoader : MonoBehaviour
webView2.Load(defaultEndpoint2); webView2.Load(defaultEndpoint2);
} }
public void UpdateApiUrl(string newApiUrl)
{
if (!string.IsNullOrEmpty(newApiUrl))
{
Debug.Log($"Updating API URL to {newApiUrl}");
apiUrl = newApiUrl;
}
}
[Serializable] [Serializable]
public class Endpoint public class Endpoint
{ {

View File

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