using Avalonia.Controls; using Shaker.Models; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ShakerApp.ViewModels { public sealed class CommunicationViewModel:DisplayViewModelBase { private readonly string PlugnsPath =Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Communication"); private Dictionary CommunicationViewModelTypes = new Dictionary(); private bool enbaledServiceControl = false; private bool localIsConnect = false; private bool serviceIsStart = false; private CommunicationViewModel() { Tools.PluginsLoader.Defalut.Load(PlugnsPath) .Select(x => (x.GetType().GetCustomAttribute()!.IsLan, x.GetType())) .ToList() .ForEach(x => CommunicationViewModelTypes[x.IsLan] =x.Item2); } public bool EnbaledServiceControl { get => enbaledServiceControl; set =>SetProperty(ref enbaledServiceControl , value); } static CommunicationViewModel() { } private async void LocalLocalCommunicationDisconnect() { await Task.Delay(1);//释放线程 LogViewModel.Instance.AddLog($"{LocalCommunication.IP}:{LocalCommunication.Port}连接断开", LogType.Error); LocalIsConnect = false; MainViewModel.Default.ShowToast(App.Current?.FindResource("DisConnect") + "", Avalonia.Controls.Notifications.NotificationType.Error); GetEvent(Topic.DisConnect).Publish(this, null); } public void Connect(string ip,int port) { LogViewModel.Instance.AddLog($"连接{ip}:{port}"); try { if (LocalCommunication == null) { LocalCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!; LocalCommunication.Disconnected += (_, _) => LocalLocalCommunicationDisconnect(); } if (LocalCommunication!.IsLan == (ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan)) { if (LocalCommunication.IsConnected) LocalCommunication.Close(); } else { LocalCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!; LocalCommunication.Disconnected += (_, _) => LocalLocalCommunicationDisconnect(); } LocalCommunication.Connect(ip, port); Thread.Sleep(50); if (LocalCommunication.IsConnected) { LogViewModel.Instance.AddLog($"获取控制器响应" ); bool success = false; for (int i = 0; i < 3; i++) { var result = LocalCommunication.GetEvent(Topic.SERVICERESULT)?.Publish(this, null); if (!string.IsNullOrEmpty(result)) { success = true; break ; } } if(!success) { LogViewModel.Instance.AddLog($"获取控制器响应失败", LogType.Error); LocalCommunication.Close(); LocalIsConnect = false; } else { MainViewModel.Default.SyncConfig(); } } else { LogViewModel.Instance.AddLog($"{ip}:{port}连接失败", LogType.Error); } } catch(Exception ex) { LogViewModel.Instance.AddLog($"{ip}:{port}连接失败,"+ex.Message, LogType.Error); } finally { if (LocalCommunication == null) LocalIsConnect = false; else LocalIsConnect = LocalCommunication.IsConnected; } } public void DisConnect() { LocalCommunication?.Close(); LocalIsConnect = false; } public void StartService(string ip,int port) { ServiceIsStart = false; if (ShakerSettingViewModel.Instance.WorkingMode == Models.WorkingMode.Remote) return; if (ServiceCommunication == null) { ServiceCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!; ServiceCommunication.Disconnected += (_, _) => { LogViewModel.Instance.AddLog($"{ServiceCommunication.IP}:{ServiceCommunication.Port}连接断开", LogType.Error); ServiceIsStart = false; MainViewModel.Default.ShowToast(App.Current?.FindResource("DisConnect") + "", Avalonia.Controls.Notifications.NotificationType.Error); GetEvent(Topic.DisConnect).Publish(this, null); }; } try { if (ServiceCommunication.IsLan == (ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan)) { if (ServiceCommunication.IP != ip || ServiceCommunication.Port != port) { if (ServiceCommunication.IsConnected) ServiceCommunication.Close(); ServiceCommunication.StartService(ip, port); } else { if (!ServiceCommunication.IsConnected) { ServiceCommunication.StartService(ip, port); } } } else { ServiceCommunication?.Close(); ServiceCommunication = (ICommunication.ICommunication)Activator.CreateInstance(CommunicationViewModelTypes[ShakerSettingViewModel.Instance.RemoteControlModel == Models.RemoteControlModel.Lan])!; ServiceCommunication.StartService(ip, port); } } catch { } if (ServiceCommunication == null) ServiceIsStart = false; else ServiceIsStart = true; if(ServiceIsStart) { MainViewModel.Default.InitServiceMsg(); } } public void StopService() { ServiceIsStart = false; if (ShakerSettingViewModel.Instance.WorkingMode == Models.WorkingMode.Remote || ServiceCommunication ==null || !ServiceCommunication.IsConnected) return; ServiceCommunication?.Close(); } public static CommunicationViewModel Instance { get; } = new CommunicationViewModel(); [AllowNull] public ICommunication.ICommunication LocalCommunication { get; private set; } [AllowNull] public ICommunication.ICommunication ServiceCommunication { get; private set; } public bool LocalIsConnect { get => localIsConnect; set { SetProperty(ref localIsConnect, value); MenuViewModel.Instance["MenuManger"]!.IsEnabled = !value; MenuViewModel.Instance["MenuConnect"]!.IsEnabled = !value; MenuViewModel.Instance["MenuDisConnect"]!.IsEnabled = value; MenuViewModel.Instance["MenuDeviceConfig"]!.IsEnabled = value; MenuViewModel.Instance["MenuDebug"]!.IsEnabled = value; MenuViewModel.Instance["MenuTest"]!.IsEnabled = value; } } public bool ServiceIsStart { get => serviceIsStart; set { SetProperty(ref serviceIsStart, value); ShakerSettingViewModel.Instance.ServieIsStart = value; } } } }