private void TimerDateTime_Tick(object sender, EventArgs e) { var timeSyncInterval = Math.Max(_MDIApplication.TimeSyncInterval, 1); if ((DateTime.Now - LastServerTime).TotalMinutes >= timeSyncInterval) { LastServerTime = DateTime.Now; try { if (_MDIApplication.DateTimeService != null) { var dateTimeService = _MDIApplication.DateTimeService.Value; var serverTime = dateTimeService.GetCurrentDateTime(); ServerTimeSpan = serverTime - DateTime.Now; } LastServerTimeException = null; } catch (Exception err) { LastServerTimeException = err; EventPublic.Error(LastServerTimeException.FormatException()); } } if (LastServerTimeException == null) { var calcServerTime = DateTime.Now + ServerTimeSpan; string dateTimeString = calcServerTime.ToString("服务器时间:yyyy-MM-dd HH:mm:ss"); this.StaticItemServerTime.Caption = dateTimeString; } else { this.StaticItemServerTime.Caption = "服务器连接失败"; } }
public byte[] CallService(byte[] serviceName, byte[] functionName, byte[] header, byte[] inputParameters) { string hostName; int port; try { string[] addressStrings = ServerAddress.Split(':'); hostName = addressStrings[0]; port = Convert.ToInt32(addressStrings[1]); } catch (Exception err) { throw new Exception("地址格式错误", err).AddExceptionData("地址", ServerAddress); } var tcpClient = new TcpClient(); tcpClient.Connect(hostName, port); EventPublic.Information("[{0}]连接[{1}]成功" , tcpClient.Client.LocalEndPoint , tcpClient.Client.RemoteEndPoint); var clientStream = tcpClient.GetStream(); var reader = new BinaryReader(clientStream); var writer = new BinaryWriter(clientStream); writer.NetWriteBinary(serviceName); writer.NetWriteBinary(functionName); writer.NetWriteBinary(header); writer.NetWriteBinary(inputParameters); // 获取返回参数 string resultType = reader.NetReadObject <string>(); byte[] result = null; if (resultType == RemotePublic.SuccessString) { result = reader.NetReadBinary(); } else { var message = reader.NetReadObject <string>(); var exceptionString = reader.NetReadObject <string>(); var remoteException = new Exception(message); var fullServiceName = String.Format("{0}.{1}" , RemotePublic.Deserialize <string>(serviceName) , RemotePublic.Deserialize <string>(functionName)); throw new Exception("远程调用服务异常", remoteException) .AddExceptionData("服务地址", ServerAddress) .AddExceptionData("服务", fullServiceName) .AddExceptionData("远程异常信息", exceptionString); } tcpClient.Close(); clientStream.Close(); return(result); }
private void LogExceptionButton_Click(object sender, RoutedEventArgs e) { try { throw new Exception("TestException").AddExceptionData("测试", "测试信息"); } catch (Exception err) { EventPublic.Exception(err); MessageBox.Show("异常记录完成"); } }
/// <summary> /// 添加目录中的元件集到插件类型列表 /// </summary> /// <param name="dir">目录</param> /// <param name="includeSubDir">是否包含子目录,默认为True</param> public static void AddDirectory(string dir, bool includeSubDir = true) { EventPublic.Information("开始加载插件目录:{0}", dir); var files = Directory.GetFiles(dir, AssemblyPattern, includeSubDir ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); foreach (var file in files) { AddFile(file); } EventPublic.Information("插件目录加载完毕:{0}", dir); }
public static void RebuildAddonTypeList() { AddonTypeList = new List <Type>(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { if (type.HasAttribute <AddonAttribute>(true)) { AddonTypeList.Add(type); EventPublic.Information("插件加载:{0}", type); } } } }
/// <summary> /// 添加文件的元件集到插件类型列表 /// </summary> /// <param name="dir">目录</param> /// <param name="includeSubDir">是否包含子目录,默认为True</param> public static Assembly AddFile(string file) { // 此处不能使用LoadFrom,因为KF.Base冲突 EventPublic.Information("开始加载插件文件:{0}", file); try { AssemblyName assemblyName = AssemblyName.GetAssemblyName(file); var assembly = AppDomain.CurrentDomain.Load(assemblyName); EventPublic.Information("插件文件加载完毕:{0}", file); return(assembly); } catch (Exception err) { // 加载文件时记录异常,不报错 EventPublic.Exception(err); return(null); } }
private void AcceptSocket(TcpListener listener) { var tcpClient = listener.AcceptTcpClient(); EventPublic.Information("[{0}]收到[{1}]的请求" , tcpClient.Client.LocalEndPoint , tcpClient.Client.RemoteEndPoint); // 接收到连接后完成通讯 var clientStream = tcpClient.GetStream(); var reader = new BinaryReader(clientStream); var writer = new BinaryWriter(clientStream); // 读取服务名称 var serviceName = reader.NetReadBinary(); // 方法名称 var functionName = reader.NetReadBinary(); // 读取协议头 var header = reader.NetReadBinary(); // 输入参数 var inputParameters = reader.NetReadBinary(); var serviceNameString = RemotePublic.Deserialize <string>(serviceName); var functionNameString = RemotePublic.Deserialize <string>(functionName); // 调用服务 EventPublic.Information("开始调用服务:{0}.{1}" , serviceNameString , functionNameString); try { var result = RemotePublic.CallService(ServiceList , serviceNameString , functionNameString , RemotePublic.Deserialize <Header>(header) , RemotePublic.Deserialize <object[]>(inputParameters)); writer.NetWriteObject(RemotePublic.SuccessString); writer.NetWriteBinary(result); } catch (Exception err) { // 发出异常 writer.NetWriteObject(RemotePublic.FailedString); writer.NetWriteObject(err.Message); writer.NetWriteObject(err.FormatException()); } tcpClient.Close(); clientStream.Close(); }
/// <summary> /// 启动服务 /// </summary> public void Start() { Stopped = false; if (Status is Status_Disabled) { EventPublic.Warning("服务被禁止,不能启动."); return; } OnStart(); Status = Status.Default <Status_Running>(); ServerTask = Task.Factory.StartNew(() => { Run(); if (Status is Status_Enabled) { Status = Status.Default <Status_Ready>(); } }, TaskCreationOptions); }
protected override void OnStart() { var localAddr = IPAddress.Parse(LocalHost); Listener = new TcpListener(localAddr, Port); EventPublic.Information("开始在地址:{0}:{1}监听", localAddr, Port); Listener.Start(); ListenTask = Task.Factory.StartNew(() => { while (!Stopped) { try { AcceptSocket(Listener); } catch (Exception err) { EventPublic.Exception(err); } } }); }
/// <summary> /// 读取配置 /// </summary> /// <param name="dirPath">目录路径</param> public static void LoadConfigStorages(string dirPath) { ConfigStorages = new Dictionary <string, Config.ConfigStorage>(); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } var filePaths = Directory.GetFiles(dirPath, "*.config"); foreach (var filePath in filePaths) { try { var configStorage = IOPublic.ReadObjectFromFile(filePath) as ConfigStorage; if (configStorage != null) { ConfigStorages.Add(configStorage.StorageName, configStorage); } } catch (Exception err) { EventPublic.Exception(err); } } }
private void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { EventPublic.Exception(e.Exception); }
public static void ProcessTransactionEvent(PaoTransaction trans) { EventPublic.FireEvent(new TransactionEventInfo(trans)); }
/// <summary> /// 遍历插件,检索插件以及子插件,并将这些插件放入addonList /// </summary> /// <param name="addonAction">对插件的操作,如果返回false,表示中断;如果返回true,表示继续检索</param> /// <param name="rootObj">根插件</param> public static bool TraverseAddon(Func <PaoObject, bool> addonAction, object rootObj) { if (rootObj == null) { return(true); } if (rootObj is PaoObject) { // 如果插件动作返回false,则退出检索 if (!addonAction(rootObj as PaoObject)) { return(false); } } var properties = TypeDescriptor.GetProperties(rootObj); foreach (PropertyDescriptor property in properties) { if (property.Attributes.GetAttribute <AddonPropertyAttribute>() == null) { continue; } // 获取属性值,然后根据属性值的状况查找子插件 object propertyValue = null; try { propertyValue = property.GetValue(rootObj); } catch (Exception err) { EventPublic.Exception(err); } if (propertyValue == null) { continue; } var propertyType = propertyValue.GetType(); // 跳过值类型和字符串 if (propertyType.IsValueType || propertyType == typeof(string)) { continue; } if (propertyValue is PaoObject) { // 插件属性 if (!TraverseAddon(addonAction, propertyValue)) { return(false); } } else if (propertyValue is IDictionary) { // 处理字典 var dict = propertyValue as IDictionary; foreach (object element in dict.Values) { if (element == null) { continue; } if (element is PaoObject) { if (!TraverseAddon(addonAction, element)) { return(false); } } } } else if (propertyValue is IEnumerable) { // 跳过基础类型数组,避免过长的循环 var elementType = propertyType.GetElementType(); if (propertyType.IsArray && (elementType.IsValueType || elementType == typeof(string))) { continue; } // 处理列表 foreach (object element in propertyValue as IEnumerable) { if (element == null) { continue; } if (element is PaoObject) { if (!TraverseAddon(addonAction, element)) { return(false); } } } } } return(true); }
private void Window_Loaded(object sender, RoutedEventArgs e) { EventPublic.Information("Window_Loaded"); }
private void Window_Initialized(object sender, EventArgs e) { EventPublic.Information("Window_Initialized"); }
private void LogWarningButton_Click(object sender, RoutedEventArgs e) { EventPublic.Warning("警告"); MessageBox.Show("警告记录完成"); }
/// <summary> /// 启动应用程序 /// </summary> /// <param name="loadFromConfig">从配置加载</param> /// <param name="configFileName">配置文件名,此文件应该放于应用程序目录</param> /// <param name="createApplicationFunc">应用创建函数</param> /// <param name="applicationPrepareFunc">准备应用程序</param> /// <param name="overwriteConfigFile">覆盖配置文件</param> public static void StartApplication(bool loadFromConfig , string configFileName , Func <PaoApplication> createApplicationFunc , Action <PaoApplication> applicationPrepareFunc , bool overwriteConfigFile = false) { _AppDirectory = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; string configFilePath = Path.Combine(_AppDirectory, configFileName); //首先添加默认的日志记录器 EventPublic.ClearEventProcessor(); EventPublic.AddEventProcessor(DebugLogger.Default); EventPublic.AddEventProcessor(EventLogger.Default); PaoApplication app = null; TransactionPublic.Run("插件引擎启动", () => { TransactionPublic.Run("加载插件库", () => { AddonPublic.AddDirectory(AppDirectory); string libPathString = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath; if (!libPathString.IsNullOrEmpty()) { string[] libPaths = libPathString.Split(';'); foreach (var libDir in libPaths) { var libPath = GetAbsolutePath(libDir); AddonPublic.AddDirectory(libPath); } } // 重建插件类型列表 AddonPublic.RebuildAddonTypeList(); }); TransactionPublic.Run("加载配置", () => { if (createApplicationFunc == null) { throw new Exception("创建配置的方法不能为空"); } if (loadFromConfig && !File.Exists(configFilePath)) { app = IOPublic.ReadObjectFromFile(configFilePath).As <PaoApplication>(); } else { // 用应用创建函数启动应用 app = createApplicationFunc(); if (overwriteConfigFile || !File.Exists(configFilePath)) { // 保存配置文件 IOPublic.WriteObjectToFile(configFilePath, app); } } if (applicationPrepareFunc != null) { applicationPrepareFunc(app); } }); }); app.Start(); }
/// <summary> /// 运行 /// </summary> public void Start() { // 一个应用中只能有一个默认应用程序 Default = this; TransactionPublic.Run("主应用程序", () => { TransactionPublic.Run("应用程序初始化", () => { TransactionPublic.Run("准备启动", OnPreparing); TransactionPublic.Run("本地配置加载", () => { // 加载本地配置存储 if (ConfigStorageDirName.IsNotNullOrEmpty()) { ConfigStoragePublic.LoadConfigStorages(AppPublic.GetAbsolutePath(ConfigStorageDirName)); } // 加载Application扩展属性 ExtendAddonPublic.GetAddonExtendProperties(this); }); TransactionPublic.Run("检索全局插件", () => { AddonPublic.SearchRuntimeAddons(this); }); #region 事件 TransactionPublic.Run("事件处理机准备", () => { if (!EventProcessorList.IsNullOrEmpty()) { EventPublic.ClearEventProcessor(); foreach (var EventProcessor in EventProcessorList) { var logObj = EventProcessor.Value; EventPublic.AddEventProcessor(logObj); } } }); #endregion 日志 #region 务器 TransactionPublic.Run("启动服务器列表", () => { if (ServerList.IsNotNullOrEmpty()) { foreach (var server in ServerList) { var serverObj = server.Value; if (serverObj == null) { throw new Exception("服务创建失败"); } serverObj.Start(); EventPublic.Information("服务{0}启动完毕.", serverObj.ObjectToString()); } } }); #endregion 务 }); #region 序 TransactionPublic.Run("启动程序", Run); #endregion 序 TransactionPublic.Run("应用程序退出", () => { TransactionPublic.Run("扩展属性保存", () => { // 保存本地配置存储 if (ConfigStorageDirName.IsNotNullOrEmpty()) { ConfigStoragePublic.SaveConfigStorages(AppPublic.GetAbsolutePath(ConfigStorageDirName)); } }); }); }, OnException); }