/// <summary>
 /// Starts the broadcaster background thread for discovery
 /// </summary>
 private void StartBroadcaster()
 {
     _broadcastThread = new Thread(async() =>
     {
         try
         {
             BroadcasterUDP = new UdpClient();
             BroadcasterUDP.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
             BroadcasterUDP.ExclusiveAddressUse = false;
             BroadcasterUDP.Client.Bind(new IPEndPoint(IPAddress.Any, BroadcastPort));
             IPEndPoint broadcastAddress = new IPEndPoint(IPAddress.Broadcast, BroadcastPort);
             byte[] broadcastMsg         = Encoding.UTF8.GetBytes($"BLENDFARM||||{Environment.MachineName}||||{Port}");
             while (Active)
             {
                 try
                 {
                     BroadcasterUDP.Send(broadcastMsg, broadcastMsg.Length, broadcastAddress);
                     Thread.Sleep(BROADCAST_INTERVAL);
                 }
                 catch (Exception ex)
                 {
                     Console.WriteLine($"Failed to send broadcast due to:" + ex.Message);
                     Thread.Sleep(1000);
                 }
             }
         }
         catch (Exception ex)
         {
             OnBroadcastException?.Invoke(this, ex);
         }
     });
     _broadcastThread.Start();
 }
        /// <summary>
        /// Starts the broadcast listener for discovery
        /// </summary>
        private void StartBroadcastListener()
        {
            _listenerUDPThread = new Thread(async() =>
            {
                try
                {
                    ListenerUDP = new UdpClient();
                    ListenerUDP.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    ListenerUDP.ExclusiveAddressUse = false;
                    ListenerUDP.Client.Bind(new IPEndPoint(IPAddress.Any, BroadcastPort));
                    IPEndPoint broadcastAddress = new IPEndPoint(IPAddress.Broadcast, BroadcastPort);
                    string myIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();
                    while (Active)
                    {
                        try
                        {
                            UdpReceiveResult received = await ListenerUDP.ReceiveAsync();
                            string ip = received.RemoteEndPoint.ToString();
                            if (ip.Contains(":"))
                            {
                                ip = ip.Substring(0, ip.IndexOf(':'));
                            }

                            if (ip != myIP)
                            {
                                string msg = Encoding.UTF8.GetString(received.Buffer);
                                if (msg.StartsWith("BLENDFARM||||"))
                                {
                                    string[] broadcastParts = msg.Split("||||");
                                    string name             = broadcastParts[1];
                                    int port = int.Parse(broadcastParts[2]);
                                    OnServerDiscovered?.Invoke(name, ip, port);
                                }
                            }
                            Thread.Sleep(100);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"Failed to receive broadcast due to:" + ex.Message);
                            Thread.Sleep(1000);
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnBroadcastException?.Invoke(this, ex);
                }
            });
            _listenerUDPThread.Start();
        }
        public static void Start()
        {
            if (Available)
            {
                return;
            }

            if (_server == null)
            {
                _server = new RenderServer(ServerPort, BroadcastPort, false);
                _server.OnServerException    += (a, b) => OnServerException?.Invoke(a, b);
                _server.OnBroadcastException += (a, b) => OnBroadcastException?.Invoke(a, b);
                _server.OnServerDiscovered   += (a, b, c) => OnDiscoveredServer?.Invoke(a, b, c);
            }
            _server.Start();
        }