DeviceMangerViewModel.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using Avalonia.Controls;
  2. using Shaker.Models;
  3. using ShakerApp.Tools;
  4. using SukiUI.Toasts;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.Diagnostics.CodeAnalysis;
  9. using System.Linq;
  10. using System.Net;
  11. using System.Text;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. using System.Windows.Input;
  15. namespace ShakerApp.ViewModels
  16. {
  17. public class DeviceMangerViewModel : ViewModelBase<IModel>
  18. {
  19. public override bool CanResize => false;
  20. public override double Width => 960;
  21. public override double Height => 660;
  22. private object locker = new object();
  23. private DeviceMangerViewModel()
  24. {
  25. ButtonVisibily = false;
  26. Content = typeof(Views.DeviceMangerView);
  27. }
  28. static DeviceMangerViewModel()
  29. {
  30. }
  31. public static DeviceMangerViewModel Instance { get; } = new DeviceMangerViewModel();
  32. [AllowNull]
  33. private DeviceInfoViewModel? currentDevice;
  34. public ObservableCollection<IndexValueItemViewModel<DeviceInfoViewModel>> Devices { get; } = new ObservableCollection<IndexValueItemViewModel<DeviceInfoViewModel>>();
  35. public ICommand SearchDeviceCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(() =>
  36. {
  37. SearchEnabled = false;
  38. Task.Run(() => SearchDevice());
  39. });
  40. public override void InitData()
  41. {
  42. base.InitData();
  43. Devices.Clear();
  44. CurrentDevice = null;
  45. PopupVisibily = false;
  46. }
  47. public bool SearchEnabled { get => searchEnabled; set => SetProperty(ref searchEnabled, value); }
  48. private CancellationTokenSource source = new CancellationTokenSource();
  49. private void WaitMsg(int timeout, CancellationTokenSource source)
  50. {
  51. Task.Run(async () =>
  52. {
  53. await Task.Delay(timeout, source.Token);
  54. source.Cancel();
  55. });
  56. }
  57. public string Msg { get => msg; set =>SetProperty(ref msg , value); }
  58. private void SearchDevice()
  59. {
  60. int timeout = 5000;
  61. Tools.DispatherInovke.Inovke(() =>
  62. {
  63. Devices.Clear();
  64. CurrentDevice = null;
  65. });
  66. Msg = App.Current?.FindResource("DeviceSearching") + "";
  67. PopupVisibily = true;
  68. DateTime start = DateTime.Now;
  69. LogViewModel.Instance.AddLog(App.Current?.FindResource("DeviceSearch") + "");
  70. System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(Topic.DISCOVERYPORT - 1);
  71. udpClient.JoinMulticastGroup(IPAddress.Parse("239.1.0.2"));
  72. source = new CancellationTokenSource();
  73. var tast = Task.Run(() =>
  74. {
  75. System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
  76. .SelectMany(x => x.GetIPProperties().UnicastAddresses.Where(x => x.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork))
  77. .ToList()
  78. .ForEach(x =>
  79. {
  80. Task.Run(async () =>
  81. {
  82. try
  83. {
  84. System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(new IPEndPoint(x.Address, Topic.DISCOVERYPORT - 1));
  85. udpClient.JoinMulticastGroup(IPAddress.Parse("239.1.0.2"));
  86. SearchDeviceModel search = new Shaker.Models.SearchDeviceModel();
  87. udpClient.Send(search.GetBytes(), new System.Net.IPEndPoint(IPAddress.Broadcast, Topic.DISCOVERYPORT));
  88. while (!source.IsCancellationRequested)
  89. {
  90. var result = await udpClient.ReceiveAsync(source.Token);
  91. if (!source.IsCancellationRequested && result.Buffer != null && result.Buffer.Length > 0)
  92. {
  93. try
  94. {
  95. var deviceinfo = result.Buffer.GetValue<ResultDeviceModel>();
  96. if (deviceinfo != null && deviceinfo.Success)
  97. {
  98. Tools.DispatherInovke.Inovke(() =>
  99. {
  100. lock (locker)
  101. {
  102. if (Devices.Any(x => x.Value.IP == deviceinfo.DeviceInfoModel.IP)) return;
  103. Devices.Add(new IndexValueItemViewModel<DeviceInfoViewModel>(Devices.Count + 1, new DeviceInfoViewModel(deviceinfo.DeviceInfoModel)));
  104. Msg = string.Format(App.Current?.FindResource("DeviceFoundCount") + "", Devices.Count);
  105. LogViewModel.Instance.AddLog($"{App.Current?.FindResource("FindedDeviceInfo")}:{deviceinfo.DeviceInfoModel}");
  106. }
  107. });
  108. }
  109. }
  110. catch
  111. {
  112. }
  113. }
  114. }
  115. udpClient.Close();
  116. }
  117. catch
  118. {
  119. }
  120. });
  121. });
  122. });
  123. Task.Delay(timeout, source.Token).Wait();
  124. source?.Cancel();
  125. PopupVisibily = false;
  126. udpClient.Close();
  127. Tools.DispatherInovke.Inovke(() =>
  128. {
  129. SearchEnabled = true;
  130. if (Devices.Count == 0)
  131. {
  132. LogViewModel.Instance.AddLog(App.Current?.FindResource("DeviceNoFound") + "");
  133. ShowToast(App.Current?.FindResource("DeviceNoFound") + "", Avalonia.Controls.Notifications.NotificationType.Error);
  134. }
  135. });
  136. }
  137. private bool popupVisibily = false;
  138. public bool PopupVisibily { get => popupVisibily; set => SetProperty(ref popupVisibily, value); }
  139. [AllowNull]
  140. private bool searchEnabled = true;
  141. private string msg = string.Empty;
  142. public ICommand ConnectDeviceCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(ConnectDevice);
  143. private async void ConnectDevice()
  144. {
  145. if (CurrentDevice == null) return;
  146. Msg = App.Current?.FindResource("DeviceConnecting") + "";
  147. PopupVisibily = true;
  148. await Task.Run(() => CommunicationViewModel.Instance.Connect(CurrentDevice.IP, CurrentDevice.Port));
  149. if (CommunicationViewModel.Instance.LocalIsConnect)
  150. {
  151. CloseWindowAction?.Invoke();
  152. ShowToast(App.Current?.FindResource("DeviceConnectSuccess") + "", Avalonia.Controls.Notifications.NotificationType.Error);
  153. return;
  154. }
  155. MainPageViewModel.Instance.ShowToast(App.Current?.FindResource("DeviceNoFound") + "", Avalonia.Controls.Notifications.NotificationType.Success);
  156. }
  157. public ICommand DisConnectDeviceCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(DisConnectDevice);
  158. private void DisConnectDevice()
  159. {
  160. CommunicationViewModel.Instance.DisConnect();
  161. CurrentDevice = null;
  162. }
  163. public DeviceInfoViewModel? CurrentDevice
  164. {
  165. get => currentDevice;
  166. set => SetProperty(ref currentDevice, value);
  167. }
  168. }
  169. }