CommunicationViewModel.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using Avalonia.Controls;
  2. using Shaker.Models;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. namespace ShakerApp.ViewModels
  13. {
  14. public sealed class CommunicationViewModel:DisplayViewModelBase<IModel>
  15. {
  16. private readonly string PlugnsPath =Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Communication");
  17. private Dictionary<bool, Type> CommunicationViewModelTypes = new Dictionary<bool, Type>();
  18. private bool enbaledServiceControl = false;
  19. private bool localIsConnect = false;
  20. private bool serviceIsStart = false;
  21. private CommunicationViewModel()
  22. {
  23. Tools.PluginsLoader.Defalut.Load<ICommunication.ICommunication>(PlugnsPath)
  24. .Select(x => (x.GetType().GetCustomAttribute<ICommunication.CommunicationTypeAttribute>()!.IsLan, x.GetType()))
  25. .ToList()
  26. .ForEach(x => CommunicationViewModelTypes[x.IsLan] =x.Item2);
  27. }
  28. public bool EnbaledServiceControl { get => enbaledServiceControl; set =>SetProperty(ref enbaledServiceControl , value); }
  29. static CommunicationViewModel()
  30. {
  31. }
  32. private async void LocalLocalCommunicationDisconnect()
  33. {
  34. await Task.Delay(1);//释放线程
  35. LogViewModel.Instance.AddLog($"{LocalCommunication.IP}:{LocalCommunication.Port}连接断开", LogType.Error);
  36. LocalIsConnect = false;
  37. MainViewModel.Default.ShowToast(App.Current?.FindResource("DisConnect") + "", Avalonia.Controls.Notifications.NotificationType.Error);
  38. GetEvent(Topic.DisConnect).Publish(this, null);
  39. }
  40. public void Connect(string ip,int port)
  41. {
  42. LogViewModel.Instance.AddLog($"连接{ip}:{port}");
  43. try
  44. {
  45. if (LocalCommunication == null)
  46. {
  47. LocalCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!;
  48. LocalCommunication.Disconnected += (_, _) => LocalLocalCommunicationDisconnect();
  49. }
  50. if (LocalCommunication!.IsLan == (ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan))
  51. {
  52. if (LocalCommunication.IsConnected) LocalCommunication.Close();
  53. }
  54. else
  55. {
  56. LocalCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!;
  57. LocalCommunication.Disconnected += (_, _) => LocalLocalCommunicationDisconnect();
  58. }
  59. LocalCommunication.Connect(ip, port);
  60. Thread.Sleep(50);
  61. if (LocalCommunication.IsConnected)
  62. {
  63. LogViewModel.Instance.AddLog($"获取控制器响应" );
  64. bool success = false;
  65. for (int i = 0; i < 3; i++)
  66. {
  67. var result = LocalCommunication.GetEvent<string>(Topic.SERVICERESULT)?.Publish(this, null);
  68. if (!string.IsNullOrEmpty(result))
  69. {
  70. success = true;
  71. break ;
  72. }
  73. }
  74. if(!success)
  75. {
  76. LogViewModel.Instance.AddLog($"获取控制器响应失败", LogType.Error);
  77. LocalCommunication.Close();
  78. LocalIsConnect = false;
  79. }
  80. else
  81. {
  82. MainViewModel.Default.SyncConfig();
  83. }
  84. }
  85. else
  86. {
  87. LogViewModel.Instance.AddLog($"{ip}:{port}连接失败", LogType.Error);
  88. }
  89. }
  90. catch(Exception ex)
  91. {
  92. LogViewModel.Instance.AddLog($"{ip}:{port}连接失败,"+ex.Message, LogType.Error);
  93. }
  94. finally
  95. {
  96. if (LocalCommunication == null) LocalIsConnect = false;
  97. else LocalIsConnect = LocalCommunication.IsConnected;
  98. }
  99. }
  100. public void DisConnect()
  101. {
  102. LocalCommunication?.Close();
  103. LocalIsConnect = false;
  104. }
  105. public void StartService(string ip,int port)
  106. {
  107. ServiceIsStart = false;
  108. if (ShakerSettingViewModel.Instance.WorkingMode == Models.WorkingMode.Remote) return;
  109. if (ServiceCommunication == null)
  110. {
  111. ServiceCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!;
  112. ServiceCommunication.Disconnected += (_, _) =>
  113. {
  114. LogViewModel.Instance.AddLog($"{ServiceCommunication.IP}:{ServiceCommunication.Port}连接断开", LogType.Error);
  115. ServiceIsStart = false;
  116. MainViewModel.Default.ShowToast(App.Current?.FindResource("DisConnect") + "", Avalonia.Controls.Notifications.NotificationType.Error);
  117. GetEvent(Topic.DisConnect).Publish(this, null);
  118. };
  119. }
  120. try
  121. {
  122. if (ServiceCommunication.IsLan == (ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan))
  123. {
  124. if (ServiceCommunication.IP != ip || ServiceCommunication.Port != port)
  125. {
  126. if (ServiceCommunication.IsConnected) ServiceCommunication.Close();
  127. ServiceCommunication.StartService(ip, port);
  128. }
  129. else
  130. {
  131. if (!ServiceCommunication.IsConnected)
  132. {
  133. ServiceCommunication.StartService(ip, port);
  134. }
  135. }
  136. }
  137. else
  138. {
  139. ServiceCommunication?.Close();
  140. ServiceCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!;
  141. ServiceCommunication.StartService(ip, port);
  142. }
  143. }
  144. catch
  145. {
  146. }
  147. if (ServiceCommunication == null) ServiceIsStart = false;
  148. else ServiceIsStart = true;
  149. if(ServiceIsStart)
  150. {
  151. MainViewModel.Default.InitServiceMsg();
  152. }
  153. }
  154. public void StopService()
  155. {
  156. ServiceIsStart = false;
  157. if (ShakerSettingViewModel.Instance.WorkingMode == Models.WorkingMode.Remote || ServiceCommunication ==null || !ServiceCommunication.IsConnected) return;
  158. ServiceCommunication?.Close();
  159. }
  160. public static CommunicationViewModel Instance { get; } = new CommunicationViewModel();
  161. [AllowNull]
  162. public ICommunication.ICommunication LocalCommunication { get; private set; }
  163. [AllowNull]
  164. public ICommunication.ICommunication ServiceCommunication { get; private set; }
  165. public bool LocalIsConnect
  166. {
  167. get => localIsConnect;
  168. set
  169. {
  170. SetProperty(ref localIsConnect, value);
  171. MenuViewModel.Instance["MenuManger"]!.IsEnabled = !value;
  172. MenuViewModel.Instance["MenuConnect"]!.IsEnabled = !value;
  173. MenuViewModel.Instance["MenuDisConnect"]!.IsEnabled = value;
  174. MenuViewModel.Instance["MenuDeviceConfig"]!.IsEnabled = value;
  175. MenuViewModel.Instance["MenuDebug"]!.IsEnabled = value;
  176. MenuViewModel.Instance["MenuTest"]!.IsEnabled = value;
  177. }
  178. }
  179. public bool ServiceIsStart
  180. {
  181. get => serviceIsStart;
  182. set
  183. {
  184. SetProperty(ref serviceIsStart, value);
  185. ShakerSettingViewModel.Instance.ServieIsStart = value;
  186. }
  187. }
  188. }
  189. }