/// <summary> /// 启动所有自启单元 /// </summary> /// <param name="unitSettingsDictionary"></param> private void StartAllAutoStartUnits() { if (!this.CanStartAllAutoStartUnits) { return; } this.CanStartAllAutoStartUnits = false; Program.LoggerModule.Log("Modules.UnitControlModule.StartAllAutoStartUnits", "正在启动所有自启单元"); if (this.UnitSettingsDictionary == null || this.UnitSettingsDictionary.Count < 1) { Program.LoggerModule.Log("Modules.UnitControlModule.StartAllAutoStartUnits", "没有任何单元配置"); return; } foreach (KeyValuePair <String, Entities.UnitSettings> item in this.UnitSettingsDictionary) { Entities.UnitSettings unitSettings = item.Value; if (!unitSettings.AutoStart) { continue; } Task.Factory.StartNew(() => { if (unitSettings.AutoStartDelay > 0) { Thread.Sleep(unitSettings.AutoStartDelay * 1000); } this.StartUnit(item.Key); }); } }
/// <summary> /// 读取所有单元文件 /// </summary> /// <returns></returns> private Boolean LoadAllUnits() { if (!this.CanLoadAllUnits) { return(false); } this.CanLoadAllUnits = false; Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits", "开始读取所有单元的配置文件"); //目录不存在或首次启动 DirectoryInfo directoryInfo = null; if (!Directory.Exists(Program.AppEnvironment.UnitsDirectory)) { Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Warning]", $"单元配置文件存放目录\"{Program.AppEnvironment.UnitsDirectory}\"不存在,正在尝试创建"); try { directoryInfo = Directory.CreateDirectory(Program.AppEnvironment.UnitsDirectory); }catch (Exception exception) { Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Error]", $"单元配置文件存放目录\"{Program.AppEnvironment.UnitsDirectory}\"不存在,且创建失败,{exception.Message},{exception.StackTrace}"); return(false); } Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Warning]", $"单元配置文件存放目录\"{Program.AppEnvironment.UnitsDirectory}\"不存在,已创建成功"); return(false); } if (directoryInfo == null) { try { directoryInfo = new DirectoryInfo(Program.AppEnvironment.UnitsDirectory); }catch (Exception exception) { Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Error]", $"单元配置文件存放目录\"{Program.AppEnvironment.UnitsDirectory}\"拒绝读取,{exception.Message},{exception.StackTrace}"); return(false); } } //查找单元 FileInfo[] fileInfoArray = null; try{ fileInfoArray = directoryInfo.GetFiles("*.json", SearchOption.TopDirectoryOnly); }catch (Exception exception) { Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Error]", $"单元配置文件存放目录\"{Program.AppEnvironment.UnitsDirectory}\"拒绝读取,{exception.Message},{exception.StackTrace}"); return(false); } if (fileInfoArray == null || fileInfoArray.Length < 1) { Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Warning]", $"未读取到任何有效单元"); return(false); } //遍历单元 foreach (FileInfo fileInfo in fileInfoArray) { Entities.UnitSettings unitSettings = this.ParseUnitFile(fileInfo); if (unitSettings == null || String.IsNullOrWhiteSpace(unitSettings.Name)) { Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits[Warning]", $"单元\"{fileInfo.FullName}\"读取失败,已跳过"); continue; } this.UnitSettingsDictionary.Add(unitSettings.Name, unitSettings); Program.LoggerModule.Log("Modules.UnitControlModule.LoadAllUnits", $"单元\"{fileInfo.FullName}\"读取成功,已加入单元列表"); } return(true); }
/// <summary> /// 刷新单元配置 /// </summary> /// <param name="unitName"></param> /// <param name="restartIfUpdate">是否刷新后重启单元</param> public void ReloadUnit(String unitName, Boolean restartIfUpdate = true) { Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit", $"开始刷新单元\"{unitName}\"的配置"); String unitFIlePath = Program.AppEnvironment.UnitsDirectory + Path.DirectorySeparatorChar + unitName + ".json"; //单元配置文件已丢失,将正在运行的单元退出并删除该单元配置 if (!File.Exists(unitFIlePath)) { Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit", $"单元\"{unitName}\"配置文件不存在,进行退出操作"); if (this.UnitSettingsDictionary.ContainsKey(unitName)) { this.UnitSettingsDictionary.Remove(unitName); } this.StopUnit(unitName); return; } //单元配置文件可供更新 Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit", $"单元\"{unitName}\"配置文件存在,重新读取"); FileInfo fileInfo = null; try { fileInfo = new FileInfo(unitFIlePath); }catch (Exception exception) { Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit[Error]", $"单元\"{unitName}\"配置文件无法读取,{exception.Message},{exception.StackTrace}"); return; } if (fileInfo == null) { Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit[Error]", $"单元\"{unitName}\"配置文件无效"); return; } Entities.UnitSettings unitSettings = this.ParseUnitFile(fileInfo); if (unitSettings == null) { Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit[Error]", $"单元\"{unitName}\"配置文件解析失败"); return; } if (!this.UnitSettingsDictionary.ContainsKey(unitName)) { Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit[Error]", $"单元\"{unitName}\"配置已失效,进行退出操作"); this.StopUnit(unitName); return; } this.UnitSettingsDictionary[unitName] = unitSettings; Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit", $"单元\"{unitName}\"配置已更新"); //通知客户端单元配置刷新 Program.WebSocketServerModule.NotifyClientsReloadUnitAsync(unitName, unitSettings); if (restartIfUpdate) { this.StopUnit(unitName); Task.Factory.StartNew(() => { Thread.Sleep(1000); this.StartUnit(unitName); Program.LoggerModule.Log("Modules.UnitControlModule.ReloadUnit", $"单元\"{unitName}\"已重启"); }); } }
/// <summary> /// 启动单元 /// </summary> /// <param name="unitName"></param> public void StartUnit(String unitName) { if (this.UnitSettingsDictionary.Count < 1) { Program.LoggerModule.Log("Modules.UnitControlModule.StartUnit[Warning]", "当前没有任何单元配置"); Program.WebSocketServerModule.NotifyClientsStartUnitFailedAsync(unitName); return; } if (!this.UnitSettingsDictionary.ContainsKey(unitName)) { Program.LoggerModule.Log("Modules.UnitControlModule.StartUnit[Warning]", $"单元\"{unitName}\"配置不存在"); Program.WebSocketServerModule.NotifyClientsStartUnitFailedAsync(unitName); return; } if (this.UnitProcessDictionary.ContainsKey(unitName)) { Program.LoggerModule.Log("Modules.UnitControlModule.StartUnit[Warning]", $"单元\"{unitName}\"已在运行中"); //Program.WebSocketServerModule.NotifyClientsStartUnitFailedAsync(unitName); return; } Entities.UnitSettings unitSettings = this.UnitSettingsDictionary[unitName]; Entities.UnitProcess unitProcess = new Entities.UnitProcess(); unitProcess.SetName(unitSettings.Name); unitProcess.ProcessStartInfo = new ProcessStartInfo { UseShellExecute = false, FileName = unitSettings.ExecuteAbsolutePath, WorkingDirectory = unitSettings.WorkAbsoluteDirectory, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }; if (!String.IsNullOrWhiteSpace(unitSettings.ExecuteParams)) { unitProcess.ProcessStartInfo.Arguments = unitSettings.ExecuteParams; } unitProcess.Process = new Process { StartInfo = unitProcess.ProcessStartInfo, EnableRaisingEvents = true }; unitProcess.Process.Exited += OnUnitProcessExited; Program.LoggerModule.Log("Modules.UnitControlModule.StartUnit", $"单元\"{unitSettings.Name}\"所需数据已构造完成,进入启动队列"); unitProcess.State = Enums.UnitProcess.State.正在启动; try { unitProcess.Process.Start(); }catch (Exception exception) { Program.LoggerModule.Log("Modules.UnitControlModule.StartUnit[Error]", $"单元\"{unitSettings.Name}\"启动失败,{exception.Message},{exception.StackTrace}"); unitProcess.State = Enums.UnitProcess.State.停止; unitProcess.ProcessStartInfo = null; unitProcess.Process.Dispose(); } Program.LoggerModule.Log("Modules.UnitControlModule.StartUnit", $"单元\"{unitSettings.Name}\"已启动"); unitProcess.State = Enums.UnitProcess.State.运行中; unitProcess.ProcessId = unitProcess.Process.Id; this.UnitProcessDictionary.Add(unitProcess.Name, unitProcess); //通知客户端单元启动 Program.WebSocketServerModule.NotifyClientsStartUnitAsync(unitName, unitProcess); }
public async void NotifyClientsReloadUnitAsync(String unitName, Entities.UnitSettings unitSettings) { Program.LoggerModule.Log("Modules.WebSocketServerModule.NotifyClientsReloadUnit", "通知所有客户端指定单元正在刷新配置"); if (this.WebSocketConnectionDictionary.Count < 1) { Program.LoggerModule.Log("Modules.WebSocketServerModule.NotifyClientsReloadUnit", "没有需要通知的客户端"); return; } foreach (KeyValuePair <Guid, IWebSocketConnection> item in this.WebSocketConnectionDictionary) { if (!item.Value.IsAvailable) { return; } await item.Value.Send($"{item.Key.ToString()}{this.SplitChar}NotifyReloadUnit{this.SplitChar}{unitName}{this.SplitChar}{JsonConvert.SerializeObject(unitSettings)}"); } }
/// <summary> /// 解析单元配置文件 /// </summary> /// <param name="unitSettingsFileInfo"></param> /// <returns></returns> private Entities.UnitSettings ParseUnitFile(FileInfo unitSettingsFileInfo) { //Span<Byte> bytes=new Span<Byte>(); Byte[] bytes; FileStream fs = null; try { fs = unitSettingsFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite); bytes = new Byte[fs.Length]; fs.Read(bytes); fs.Close(); }catch (Exception exception) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,{exception.Message},{exception.StackTrace}"); return(null); } finally { if (fs != null) { fs.Dispose(); } } String json = Encoding.UTF8.GetString(bytes); if (String.IsNullOrWhiteSpace(json)) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,文件内容为空"); return(null); } if (json.IndexOf('§') > -1) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,文件内容含有保留字符\"§\""); return(null); } Entities.UnitSettings unitSettings = Newtonsoft.Json.JsonConvert.DeserializeObject <Entities.UnitSettings>(json); if (unitSettings == null) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,文件反序列化失败"); return(null); } if (String.IsNullOrWhiteSpace(unitSettings.Description)) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Warning]", $"单元\"{unitSettingsFileInfo.FullName}\"解析警告,不建议 Description 配置项为空"); } if (String.IsNullOrWhiteSpace(unitSettings.ExecuteAbsolutePath)) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,ExecuteAbsolutePath 配置项为空"); return(null); } if (!File.Exists(unitSettings.ExecuteAbsolutePath)) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,ExecuteAbsolutePath 配置项无效,可执行文件不存在或没有读取权限"); return(null); } if (String.IsNullOrWhiteSpace(unitSettings.WorkAbsoluteDirectory)) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,WorkAbsoluteDirectory 配置项为空"); return(null); } if (!Directory.Exists(unitSettings.WorkAbsoluteDirectory)) { Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile[Error]", $"单元\"{unitSettingsFileInfo.FullName}\"解析失败,WorkAbsoluteDirectory 配置项无效,可执行文件工作目录不存在或没有读取权限"); return(null); } unitSettings.SetName(unitSettingsFileInfo.GetOriginName()); Program.LoggerModule.Log("Modules.UnitControlModule.ParseUnitFile", $"单元\"{unitSettingsFileInfo.FullName}\"解析完成"); return(unitSettings); }