From c4c8ea62e2500b13a42447a17c66359cb7b448e0 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Mon, 14 Nov 2016 14:56:36 -0800 Subject: [PATCH] Added network monitor pub/sub class --- windows/WinUI/APIHandler.cs | 11 ++- windows/WinUI/NetworkMonitor.cs | 159 ++++++++++++++++++++++++++++++ windows/WinUI/ToolbarItem.xaml.cs | 23 ++--- windows/WinUI/WinUI.csproj | 1 + windows/WinUI/ZeroTierNetwork.cs | 13 +++ 5 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 windows/WinUI/NetworkMonitor.cs diff --git a/windows/WinUI/APIHandler.cs b/windows/WinUI/APIHandler.cs index c7dc16b78..b30e89803 100644 --- a/windows/WinUI/APIHandler.cs +++ b/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 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 networks); + public void GetNetworks(NetworkListCallback cb) { diff --git a/windows/WinUI/NetworkMonitor.cs b/windows/WinUI/NetworkMonitor.cs new file mode 100644 index 000000000..b8d2c9461 --- /dev/null +++ b/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 networks); + public delegate void StatusCallback(ZeroTierStatus status); + + private Thread runThread; + private NetworkListCallback _nwCb; + private StatusCallback _stCb; + + + private List _knownNetworks = new List(); + + 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 netList; + + using (Stream stream = File.Open(dataFile, FileMode.Open)) + { + var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + netList = (List)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 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; + } + } +} diff --git a/windows/WinUI/ToolbarItem.xaml.cs b/windows/WinUI/ToolbarItem.xaml.cs index e53e4b350..991e1b4a9 100644 --- a/windows/WinUI/ToolbarItem.xaml.cs +++ b/windows/WinUI/ToolbarItem.xaml.cs @@ -30,6 +30,8 @@ namespace WinUI private NetworkListView netListView = null; private List networkList = null; + private NetworkMonitor mon = NetworkMonitor.Instance; + private ObservableCollection _networkCollection = new ObservableCollection(); public ObservableCollection NetworkCollection @@ -44,15 +46,14 @@ namespace WinUI { InitializeComponent(); - onUpdateTimer(this, null); + mon.SubscribeNetworkUpdates(updateNetworks); + mon.SubscribeStatusUpdates(updateStatus); + } - timer = new Timer(); - timer.Elapsed += new ElapsedEventHandler(onUpdateTimer); - timer.Interval = 2000; - timer.Enabled = true; - - nodeIdMenuItem.Header = "OFFLINE"; - nodeIdMenuItem.IsEnabled = false; + ~ToolbarItem() + { + mon.UnsubscribeNetworkUpdates(updateNetworks); + mon.UnsubscribeStatusUpdates(updateStatus); } private void updateNetworks(List 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"); diff --git a/windows/WinUI/WinUI.csproj b/windows/WinUI/WinUI.csproj index a301463ab..92ee586af 100644 --- a/windows/WinUI/WinUI.csproj +++ b/windows/WinUI/WinUI.csproj @@ -101,6 +101,7 @@ MSBuild:Compile Designer + NetworksPage.xaml diff --git a/windows/WinUI/ZeroTierNetwork.cs b/windows/WinUI/ZeroTierNetwork.cs index f8ebf9ac3..2bcb76e2e 100644 --- a/windows/WinUI/ZeroTierNetwork.cs +++ b/windows/WinUI/ZeroTierNetwork.cs @@ -158,4 +158,17 @@ namespace WinUI } } } + + public class NetworkEqualityComparer : IEqualityComparer + { + public bool Equals(ZeroTierNetwork lhs, ZeroTierNetwork rhs) + { + return lhs.NetworkId.Equals(rhs.NetworkId); + } + + public int GetHashCode(ZeroTierNetwork obj) + { + return obj.NetworkId.GetHashCode(); + } + } }