using System; using System.IO; using System.Xml; using System.Data; using System.Text; using System.Collections; using System.Reflection; using System.Configuration; using Core.Mes.Common; using Core.Mes.IBaseInterface; namespace Core.Mes.ServerFrameWork { public class Dispatcher : MarshalByRefObject, ICommon { private ArrayList _objects = null; private ServerConfigure _servConf = null; public ServerConfigure ServConfig { get { return _servConf; } } #region " Construct " public Dispatcher() { } public Dispatcher(IServerPool pool, ServerConfigure _conf, ArrayList _objs) { Pool = pool; _servConf = _conf; _objects = _objs; } private IServerPool _pool = null; public IServerPool Pool { get { return _pool; } set { _pool = value; if (_pool.OwnObjects == null && _objects != null) _pool.OwnObjects = _objects; } } #endregion #region " Variable " //== 子服务集合 public static Hashtable _htServers = new Hashtable(); //== 数据链接集合 public static Hashtable htDBManager = new Hashtable(); public event GetStatusInfoHandler getStatusInfo; public delegate void GetStatusInfoHandler(string info); protected virtual void SetStatusMessage(string info) { if (getStatusInfo != null) { getStatusInfo(info); } } #endregion #region 内存释放 public void MemoryDispose() { long memorysize = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64; int PagedMemorySize = (int)memorysize / (1024 * 1024); if (PagedMemorySize > _servConf.MemoryMaxSize)//进程占用内存>100M 做GC. { try { GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } catch { } System.Diagnostics.Process.GetCurrentProcess().Dispose(); } } #endregion #region MethodTimeLog private static object lockObj = new object(); public void MethodTimeLog(TimeSpan tspan, object[] objs, object[] args) { string path = string.Format(@"./log/Method/MethodTimeLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd")); lock (lockObj) { using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8)) { StringBuilder sbtxt = new StringBuilder(); sbtxt.AppendLine("=============================================="); sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); sbtxt.AppendLine(string.Format("Time:{0}", tspan.TotalMilliseconds)); sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString())); sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString())); if (args != null) { foreach (object obj in args) { if (obj != null) { sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString())); } } } sbtxt.AppendLine("=============================================="); sw.WriteLine(sbtxt.ToString()); } } } public void MethodErrLog(Exception ex, object[] objs, object[] args) { string path = string.Format(@"./log/Method/MethodErrLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd")); lock (lockObj) { using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8)) { StringBuilder sbtxt = new StringBuilder(); sbtxt.AppendLine("=============================================="); sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString())); sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString())); if (args != null) { foreach (object obj in args) { if (obj != null) { sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString())); } } } sbtxt.AppendLine(ex.Message); sbtxt.AppendLine(ex.StackTrace); sbtxt.AppendLine("=============================================="); sw.WriteLine(sbtxt.ToString()); } } } public void DebugLog(object[] objs, object[] args) { string path = string.Format(@"./log/Method/DebugLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd")); lock (lockObj) { if (File.Exists(Path.GetFullPath(path))) { FileInfo fileInfo = new FileInfo(Path.GetFullPath(path)); if (fileInfo.Length / (1024 * 1024) > 6) { File.Delete(path); } } using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8)) { StringBuilder sbtxt = new StringBuilder(); sbtxt.AppendLine("=============================================="); sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString())); sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString())); if (args != null) { foreach (object obj in args) { if (obj != null) { sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString())); } } } sbtxt.AppendLine("=============================================="); sw.WriteLine(sbtxt.ToString()); } } } #endregion #region " 调用服务 " /// /// 服务端公开给客户端的调用后台服务的方法 /// /// /// public ReturnObject MethodHandler(CallingMessage message, ValidateInfo validateInfo) { CallingMessageEx messageEx = new CallingMessageEx(); messageEx.FromCallingMessage(message); messageEx.RedirectLimit = 0; messageEx.InnerServerRedirect = true; ReturnObjectEx rtnObjEx = Execute(messageEx, validateInfo); ReturnObject rtnObj = new ReturnObject(); rtnObj.ErrCode = rtnObjEx.ErrCode; rtnObj.ErrMessage = rtnObjEx.ErrMessage; rtnObj.RealDataSet = rtnObjEx.RealDataSet; rtnObj.RealObject = rtnObjEx.RealObject; return rtnObj; } public ReturnObjectEx MethodHandlerEx(CallingMessageEx message, ValidateInfo validateInfo) { return Execute(message, validateInfo); } private ReturnObjectEx Execute(CallingMessageEx messageEx, ValidateInfo validateInfo) { //step1: MemoryDispose(); //step2: string serverName = messageEx.ServerName; string assemblyName = messageEx.AssemblyName; string className = messageEx.ClassName; string methodName = messageEx.MethodName; object[] args = messageEx.args; ReturnObjectEx rtnObjEx = new ReturnObjectEx(); MethodInfo myMethod = null; try { if (Pool.HtComponent.Contains(className)) { try { if (serverName.ToUpper() != "SERVERCOMMON" && messageEx.RedirectLimit > 0) { string RedirURL = ""; double sum_factor = 0; ArrayList serviceProvider = new ArrayList(); ArrayList pfactors = new ArrayList(); serviceProvider.Add("THIS"); sum_factor += this.ServConfig.PriorityFactor; pfactors.Add(sum_factor); foreach (string server in Pool.HtExtServer.Keys) { RemotingServer rs = (RemotingServer)Pool.HtExtServer[server]; if (rs.Valid != RemoteServerStatus.Normal || rs.Enable == false) continue; rs.FindRemoteServer(serverName); if (!rs.HTServices.ContainsKey(serverName)) continue; ServiceObject so = ((ServiceObject)(rs.HTServices[serverName])); if (so.Valid != ServiceObjectStatus.Normal || so.Enable == false) continue; RedirURL = so.URL; sum_factor += rs.PriorityFactor; serviceProvider.Add(server); pfactors.Add(sum_factor); } Random rand = new Random(); double rand_selector = rand.NextDouble() * sum_factor; int selector = 0; for (int idx = 0; idx < pfactors.Count; idx++) { if (rand_selector <= (double)pfactors[idx]) { selector = idx; break; } } if (selector != 0) { SimpleReturnObject _out = new SimpleReturnObject(); if (messageEx.InnerServerRedirect) { RemotingServer rs = (RemotingServer)Pool.HtExtServer[serviceProvider[selector]]; rtnObjEx = (ReturnObjectEx)rs.ExecuteMethod(messageEx, out _out); return rtnObjEx; } else { rtnObjEx.ReDirectURL = RedirURL; return rtnObjEx; } } } //使用本地服务 myMethod = Pool.GetType().GetMethod("HandleMethodEx"); ; DateTime startTime = DateTime.Now; if (_servConf.Debug == "true") { DebugLog(new object[] { className, methodName }, args); } ReturnObject rtnObj = (ReturnObject)myMethod.Invoke(Pool, new object[] { className, methodName, args, _objects }); rtnObjEx.ReDirectURL = ""; rtnObjEx.ErrCode = rtnObj.ErrCode; rtnObjEx.ErrMessage = rtnObj.ErrMessage; rtnObjEx.RealDataSet = rtnObj.RealDataSet; rtnObjEx.RealObject = rtnObj.RealObject; DateTime endTime = DateTime.Now; TimeSpan tspan = endTime - startTime; if (tspan.TotalMilliseconds > (_servConf.MethodTime * 1000)) { MethodTimeLog(tspan, new object[] { className, methodName }, args); } if (rtnObjEx.RealObject != null) { if (rtnObjEx.RealObject.GetType() == typeof(DataSet)) { DataSet _ds = (DataSet)rtnObjEx.RealObject; bool largeData = false; int row_cnt = 0; foreach (DataTable _dt in _ds.Tables) { row_cnt += _dt.Rows.Count; if (_dt.Rows.Count > _servConf.CompressThreshold || row_cnt > _servConf.CompressThreshold) { largeData = true; break; } } if (largeData) { byte[] _rtn = Utility.SerializeDataSet(_ds); byte[] _rtn_comp = Utility.CompressBytes(_rtn); DataTable dt_rus = new DataTable("RETURN_RESULT"); dt_rus.Columns.AddRange(new DataColumn[]{ new DataColumn("IsCompressed", System.Type.GetType("System.Int32") ), new DataColumn("UnCompress_size", System.Type.GetType("System.Int32")), new DataColumn("Compress_size", System.Type.GetType("System.Int32"))} ); dt_rus.AcceptChanges(); dt_rus.Rows.Add(new object[] { 1, _rtn.Length, _rtn_comp.Length }); dt_rus.AcceptChanges(); if (rtnObjEx.RealDataSet == null) { rtnObjEx.RealDataSet = new DataSet(); } rtnObjEx.RealDataSet.Tables.Add(dt_rus); rtnObjEx.RealObject = _rtn_comp; } } } return rtnObjEx; } catch (Exception ex) { MethodErrLog(ex, new object[] { className, methodName }, args); return new ReturnObjectEx(null, ex.Message); } finally { try { if (rtnObjEx.RealObject != null) { rtnObjEx.RealObject = null; } if (rtnObjEx.RealDataSet != null) { rtnObjEx.RealDataSet = null; } } catch { } } } else { return new ReturnObjectEx(null, "未找到请求的服务![2]"); } } catch (Exception ex) { return new ReturnObjectEx(null, "服务调用发生异常! \n" + ex.Message); } } #endregion #region " Common Handler " //======================================================= // 用来确保当创建 Singleton 时, 第一个实例永远不会过期 //======================================================= public override object InitializeLifetimeService() { return null; } #endregion } }