Browse Source

Added network monitor pub/sub class

Grant Limberg 8 years ago
parent
commit
c4c8ea62e2

+ 9 - 2
windows/WinUI/APIHandler.cs

@@ -22,6 +22,13 @@ namespace WinUI
         private static volatile APIHandler instance;
         private static object syncRoot = new Object();
 
+        public delegate void NetworkListCallback(List<ZeroTierNetwork> networks);
+        public delegate void StatusCallback(ZeroTierStatus status);
+
+
+        private NetworkListCallback _networkCallbacks;
+        private StatusCallback _statusCallbacks;
+
         public static APIHandler Instance
         {
             get
@@ -128,7 +135,7 @@ namespace WinUI
             this.authtoken = authtoken;
         }
 
-        public delegate void StatusCallback(ZeroTierStatus status);
+        
 
         public void GetStatus(StatusCallback cb)
         {
@@ -168,7 +175,7 @@ namespace WinUI
             }
         }
 
-        public delegate void NetworkListCallback(List<ZeroTierNetwork> networks);
+        
 
         public void GetNetworks(NetworkListCallback cb)
         {

+ 159 - 0
windows/WinUI/NetworkMonitor.cs

@@ -0,0 +1,159 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace WinUI
+{
+    class NetworkMonitor
+    {
+        public delegate void NetworkListCallback(List<ZeroTierNetwork> networks);
+        public delegate void StatusCallback(ZeroTierStatus status);
+
+        private Thread runThread;
+        private NetworkListCallback _nwCb;
+        private StatusCallback _stCb;
+
+
+        private List<ZeroTierNetwork> _knownNetworks = new List<ZeroTierNetwork>();
+
+        private static NetworkMonitor instance;
+        private static object syncRoot = new object();
+
+        public static NetworkMonitor Instance
+        {
+            get
+            {
+                if (instance == null)
+                {
+                    lock (syncRoot)
+                    {
+                        if (instance == null)
+                        {
+                            instance = new NetworkMonitor();
+                        }
+                    }
+                }
+
+                return instance;
+            }
+        }
+
+        private NetworkMonitor()
+        {
+            runThread = new Thread(new ThreadStart(run));
+            loadNetworks();
+
+            runThread.Start();
+        }
+
+        ~NetworkMonitor()
+        {
+            runThread.Interrupt();
+        }
+
+        private void loadNetworks()
+        {
+            String dataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One";
+            String dataFile = Path.Combine(dataPath, "networks.dat");
+            
+            if (File.Exists(dataFile))
+            {
+                List<ZeroTierNetwork> netList;
+
+                using (Stream stream = File.Open(dataFile, FileMode.Open))
+                {
+                    var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
+                    netList = (List<ZeroTierNetwork>)bformatter.Deserialize(stream);
+                }
+
+                _knownNetworks = netList;
+            }
+        }
+
+        private void writeNetworks()
+        {
+            String dataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One";
+            String dataFile = Path.Combine(dataPath, "networks.dat");
+
+            if (!Directory.Exists(dataPath))
+            {
+                Directory.CreateDirectory(dataPath);
+            }
+
+            using (Stream stream = File.Open(dataFile, FileMode.OpenOrCreate))
+            {
+                var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
+                bformatter.Serialize(stream, _knownNetworks);
+            }
+        }
+
+        private void apiNetworkCallback(List<ZeroTierNetwork> networks)
+        {
+            _knownNetworks = _knownNetworks.Union(networks, new NetworkEqualityComparer()).ToList();
+
+            foreach (ZeroTierNetwork n in _knownNetworks)
+            {
+                if (networks.Contains(n))
+                {
+                    n.IsConnected = true;
+                }
+            }
+
+            _nwCb(_knownNetworks);
+
+            writeNetworks();
+        }
+
+        private void apiStatusCallback(ZeroTierStatus status)
+        {
+            _stCb(status);
+        }
+
+        private void run()
+        {
+            try
+            {
+                while (runThread.IsAlive)
+                {
+                    APIHandler handler = APIHandler.Instance;
+
+                    if (handler != null)
+                    {
+                        handler.GetNetworks(apiNetworkCallback);
+                        handler.GetStatus(apiStatusCallback);
+                    }
+
+                    Thread.Sleep(2000);
+                }
+            }
+            catch
+            {
+
+            }
+        }
+
+        public void SubscribeStatusUpdates(StatusCallback cb)
+        {
+            _stCb += cb;
+        }
+
+        public void UnsubscribeStatusUpdates(StatusCallback cb)
+        {
+            _stCb -= cb;
+        }
+
+        public void SubscribeNetworkUpdates(NetworkListCallback cb)
+        {
+            _nwCb += cb;
+        }
+
+        public void UnsubscribeNetworkUpdates(NetworkListCallback cb)
+        {
+            _nwCb -= cb;
+        }
+    }
+}

+ 9 - 14
windows/WinUI/ToolbarItem.xaml.cs

@@ -30,6 +30,8 @@ namespace WinUI
         private NetworkListView netListView = null;
         private List<ZeroTierNetwork> networkList = null;
 
+        private NetworkMonitor mon = NetworkMonitor.Instance;
+
         private ObservableCollection<ZeroTierNetwork> _networkCollection = new ObservableCollection<ZeroTierNetwork>();
 
         public ObservableCollection<ZeroTierNetwork> NetworkCollection
@@ -44,15 +46,14 @@ namespace WinUI
         {
             InitializeComponent();
 
-            onUpdateTimer(this, null);
-
-            timer = new Timer();
-            timer.Elapsed += new ElapsedEventHandler(onUpdateTimer);
-            timer.Interval = 2000;
-            timer.Enabled = true;
+            mon.SubscribeNetworkUpdates(updateNetworks);
+            mon.SubscribeStatusUpdates(updateStatus);
+        }
 
-            nodeIdMenuItem.Header = "OFFLINE";
-            nodeIdMenuItem.IsEnabled = false;
+        ~ToolbarItem()
+        {
+            mon.UnsubscribeNetworkUpdates(updateNetworks);
+            mon.UnsubscribeStatusUpdates(updateStatus);
         }
 
         private void updateNetworks(List<ZeroTierNetwork> networks)
@@ -92,12 +93,6 @@ namespace WinUI
             }
         }
 
-        private void onUpdateTimer(object source, ElapsedEventArgs e)
-        {
-            APIHandler.Instance.GetStatus(updateStatus);
-            APIHandler.Instance.GetNetworks(updateNetworks);
-        }
-
         private void ToolbarItem_TrayContextMenuOpen(object sender, System.Windows.RoutedEventArgs e)
         {
             Console.WriteLine("TrayContextMenuOpen");

+ 1 - 0
windows/WinUI/WinUI.csproj

@@ -101,6 +101,7 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </ApplicationDefinition>
+    <Compile Include="NetworkMonitor.cs" />
     <Compile Include="NetworkRoute.cs" />
     <Compile Include="NetworksPage.xaml.cs">
       <DependentUpon>NetworksPage.xaml</DependentUpon>

+ 13 - 0
windows/WinUI/ZeroTierNetwork.cs

@@ -158,4 +158,17 @@ namespace WinUI
             }
         }
     }
+
+     public class NetworkEqualityComparer : IEqualityComparer<ZeroTierNetwork>
+    {
+        public bool Equals(ZeroTierNetwork lhs, ZeroTierNetwork rhs)
+        {
+            return lhs.NetworkId.Equals(rhs.NetworkId);
+        }
+
+        public int GetHashCode(ZeroTierNetwork obj)
+        {
+            return obj.NetworkId.GetHashCode();
+        }
+    }
 }