using System; using System.Threading; using System.Collections; using System.Reflection; using Core.Mes.IBaseInterface; using System.IO; using System.Security.Cryptography; using System.Text; namespace Core.Mes.ServerFrameWork { /// /// 容器型服务的统一接口 /// public class IServerPool : MarshalByRefObject, IServerBase { #region IServerBase 成员 public string Description { get { // TODO: 添加 IServerPool.Description getter 实现 return null; } } private ArrayList _objects = null; public ArrayList OwnObjects { get { return _objects; } set { _objects = value; } } private Hashtable _dbManager = null; public Hashtable DBManagerList { get { return _dbManager; } set { _dbManager = value; } } private Hashtable _htServiceKeys = null; public Hashtable HTServiceKeys { get { return _htServiceKeys; } set { _htServiceKeys = value; } } private Hashtable _htComponent = new Hashtable(); public Hashtable HtComponent { get { return _htComponent; } set { _htComponent = value; } } private SrvDaemon _srvDaemon = null; public SrvDaemon srvDaemon { get { return _srvDaemon; } set { _srvDaemon = value; } } private Hashtable _htExtServer = null; public Hashtable HtExtServer { get { return _htExtServer; } set { _htExtServer = value; } } private ServerConfigure _servConf = null; public ServerConfigure ServerConfig { get { return _servConf; } set { _servConf = value; } } #endregion #region IDisposable 成员 public void Dispose() { System.Collections.IEnumerator ie = this.HtComponent.GetEnumerator(); while (ie.MoveNext()) { try { System.Collections.DictionaryEntry de = (DictionaryEntry)ie.Current; DisposeClass((Hashtable)de.Value, 0); DisposeClass((Hashtable)de.Value, 1); } catch { } } } private void DisposeClass(Hashtable ht, int index) { try { ArrayList al = ht[index] as ArrayList; int count = al.Count; for (int i = 0; i < al.Count; i++) { try { ((IComponent)al[0]).Dispose(); } catch { } } } catch { } } Assembly assembly = null; public bool LoadAllClass(string dll_file, string dbName) { if (!File.Exists(dll_file)) return false; try { assembly = Assembly.LoadFile(dll_file); foreach (Type type in assembly.GetTypes()) { if (type.IsClass && type.IsSubclassOf(typeof(IComponent))) { LoadClass(type, dbName); } } return true; } catch { return false; } } //======================================================= // 加载单个类,并按最小副本数生成多个类的实例 // classPoolHash 0--闲列表 1-忙列表 2--最小副本数 3--最大副本数 //======================================================= public void LoadClass(Type moduleType, string dataBaseName) { try { string className = moduleType.FullName; //== 反射类 IComponent module = (IComponent)Activator.CreateInstance(moduleType); module.DBName = dataBaseName; module.DBManagerList = this.DBManagerList; module.HTServiceKeys = this.HTServiceKeys; module.ServerConfig = this.ServerConfig; module.OwnObjects = this._objects; int maxCopyValue = module.maxValue; int minCopyValue = module.minValue; Hashtable classPoolHash = (Hashtable)HtComponent[className]; if (classPoolHash == null) { classPoolHash = new Hashtable(); HtComponent.Add(className, classPoolHash); } //存储每个类的空闲列表 ArrayList freeList = classPoolHash[0] as ArrayList; if (freeList == null) { freeList = new ArrayList(); classPoolHash.Add(0, freeList); } //存储一个空忙列表 ArrayList busyList = classPoolHash[1] as ArrayList; if (busyList == null) { busyList = new ArrayList(); classPoolHash.Add(1, busyList); } //加入最小副本数个副本到空闲列表 freeList.Add(module); if (minCopyValue < 1) minCopyValue = 1; for (int i = 0; i < minCopyValue - 1; i++) { IComponent classObj = (IComponent)Activator.CreateInstance(moduleType); classObj.DBName = dataBaseName; classObj.DBManagerList = this.DBManagerList; classObj.HTServiceKeys = this.HTServiceKeys; classObj.ServerConfig = this.ServerConfig; classObj.OwnObjects = _objects; freeList.Add(classObj); } //加入最大,最小副本值 classPoolHash.Add(2, maxCopyValue); classPoolHash.Add(3, minCopyValue); classPoolHash.Add(4, dataBaseName); } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion private string _serverName = ""; public string ServerName { get { return _serverName; } set { _serverName = value; } } private string _assemblyName = ""; public string AssemblyName { get { return _assemblyName; } set { _assemblyName = value; } } public ReturnObject HandleMethod(string className, string methodName, object[] args) { //查找对应的业务组件子服务 Result structObj = this.searchObject(className, methodName); if (structObj.busy.Equals("Error")) { //无此所访问的类 return new ReturnObject(null, 10003, "未找到请求的服务![1]"); } else if (structObj.busy.Equals("Wait")) { //达到最大访问限制,等待,超过规定时间放弃 int i = 1; while (structObj.busy.Equals("Wait")) { if ((i++) > 30) { //3秒后放弃,超时返回 return new ReturnObject(null, 10001, "服务正忙,请稍后再试!"); } Thread.Sleep(100); structObj = this.searchObject(className, methodName); } } //得到正确的副本后... //设置相关信息 Type type = structObj.obj.GetType(); IComponent component = (IComponent)(structObj.obj); component.CallingMethodStartTime = DateTime.Now; component.CallingClass = type.FullName; //执行方法 MethodInfo mthod = type.GetMethod(methodName); object myReturnObj; if (mthod == null) { myReturnObj = new ReturnObject(null, 10002, string.Format("调用的方法不存在,请检查方法名是否正确!\nServerName=[{0}]\nMethod=[{1}]", className, methodName)); } else { try { myReturnObj = mthod.Invoke(structObj.obj, args); } catch (Exception ex) { if (((IComponent)(structObj.obj)).DBManager == null) { myReturnObj = new ReturnObject(null, 20000, "数据库链接不存在! 请检查服务器链接配置[DBManager]"); } else { myReturnObj = new ReturnObject(null, ex.Message); } } } //释放副本 this.realeasObject(className, structObj.obj as IComponent); if (myReturnObj.GetType().Equals(typeof(ReturnObject))) return (ReturnObject)myReturnObj; else return new ReturnObject(myReturnObj, 10005, "未按指定的类型定义返回值!"); } public ReturnObject HandleMethodEx(string className, string methodName, object[] args, ArrayList _objs) { _objects = _objs; return HandleMethod(className, methodName, args); } private IComponent RequestServerResource(string className, string methodName) { if (srvDaemon == null) return null; string _sName = this.ServerName.Trim().ToUpper(); string _cName = string.IsNullOrEmpty(className.Trim()) ? "" : "." + className.Trim().ToUpper(); string _mName = string.IsNullOrEmpty(methodName.Trim()) ? "" : "." + methodName.Trim().ToUpper(); string _name = _sName + _cName + _mName; double OccupyMem = 30.0; if (srvDaemon.SrvClassManager.ContainsKey(_name)) { SrvClassInfo sci = (SrvClassInfo)(srvDaemon.SrvClassManager[_name]); OccupyMem = sci.AvgMemUsed; } SystemInfo si = new SystemInfo(); if ((double)(si.MemoryAvailable / 1024 / 1024) - OccupyMem < ServerConfig.PreserveSystemMemory) return null; Assembly ab = Assembly.Load(this.AssemblyName); Type tp = ab.GetType(className); IComponent newObj = (IComponent)Activator.CreateInstance(tp); return newObj; } private Result searchObject(string className) { return searchObject(className, ""); } private Result searchObject(string className, string methodName) { string busy = "Success"; string err = ""; Hashtable poolHash = (Hashtable)this.HtComponent[className]; if (poolHash == null) { busy = "Error"; err = "no the class"; Result result = new Result(busy, err, null); return result; } lock (poolHash) { //取出空闲和忙列表 ArrayList frList = poolHash[0] as ArrayList; ArrayList bsyList = poolHash[1] as ArrayList; if (bsyList == null) { bsyList = new ArrayList(); poolHash.Add(1, bsyList); } //如果无空闲副本,且忙列表超过最大副本数目,等待后重新请求 //否则返回空闲副本 if (frList.Count > 0) { IComponent temp = (IComponent)frList[0]; bsyList.Add(temp); frList.RemoveAt(0); Result result = new Result(busy, err, temp); return result; } //创建并返回新副本 IComponent newObj = RequestServerResource(className, methodName); if (newObj != null) { newObj.DBManagerList = this.DBManagerList; newObj.DBName = poolHash[4].ToString(); newObj.HTServiceKeys = this.HTServiceKeys; newObj.ServerConfig = this.ServerConfig; newObj.OwnObjects = _objects; bsyList.Add(newObj); Result result = new Result("Success", "", newObj); return result; } //最大,等待 if (bsyList.Count == Convert.ToInt16(poolHash[2])) { busy = "Wait"; Result result = new Result(busy, err, null); return result; } if (bsyList.Count < Convert.ToInt16(poolHash[2])) { Assembly ab = Assembly.Load(this.AssemblyName); Type tp = ab.GetType(className); newObj = (IComponent)Activator.CreateInstance(tp); newObj.DBManagerList = this.DBManagerList; newObj.DBName = poolHash[4].ToString(); newObj.HTServiceKeys = this.HTServiceKeys; newObj.ServerConfig = this.ServerConfig; newObj.OwnObjects = _objects; bsyList.Add(newObj); Result result = new Result(busy, err, newObj); return result; } return new Result("", "", null); } } public string realeasObject(string className, IComponent busyObj) { string err = "success"; Hashtable poolHash = (Hashtable)this.HtComponent[className]; if (poolHash == null) { err = "no the class"; return err; } lock (poolHash) { //移入空闲列表 ArrayList frList = poolHash[0] as ArrayList; ArrayList bsyList = poolHash[1] as ArrayList; //如果空闲副本数目大于最小副本数目,销毁生存期较长副本 if (frList.Count > Convert.ToInt16(poolHash[3])) { bsyList.Remove(busyObj); busyObj.Dispose(); busyObj = null; return err; } else { bsyList.Remove(busyObj); frList.Add(busyObj); } return err; } } private string MD5key = ""; public string MD5_KEY { get { return MD5key; } } private string SHA256key = ""; public string SHA256_KEY { get { return SHA256key; } } public void GetFileKey(string filename, out string _MD5key, out string _SHA256key) { _MD5key = ""; _SHA256key = ""; if (!File.Exists(filename)) return; FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read); MD5 md5 = new MD5CryptoServiceProvider(); byte[] b_md5 = md5.ComputeHash(file); file.Seek(0, SeekOrigin.Begin); byte[] b_sha256 = SHA256Managed.Create().ComputeHash(file); file.Close(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < b_md5.Length; i++) { sb.Append(b_md5[i].ToString("x2")); } MD5key = sb.ToString(); StringBuilder builder = new StringBuilder(); for (int i = 0; i < b_sha256.Length; i++) { builder.Append(b_sha256[i].ToString("X2")); } SHA256key = builder.ToString(); _MD5key = MD5_KEY; _SHA256key = SHA256_KEY; } public struct Result { public string busy; public string err; public object obj; public Result(string busy, string err, object obj) { this.busy = busy; this.err = err; this.obj = obj; } } } }