86598306ef2af880481ea1ece6c7a77c246d3329.svn-base 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. using System;
  2. using System.Threading;
  3. using System.Collections;
  4. using System.Reflection;
  5. using Core.Mes.IBaseInterface;
  6. using System.IO;
  7. using System.Security.Cryptography;
  8. using System.Text;
  9. namespace Core.Mes.ServerFrameWork
  10. {
  11. /// <summary>
  12. /// 容器型服务的统一接口
  13. /// </summary>
  14. public class IServerPool : MarshalByRefObject, IServerBase
  15. {
  16. #region IServerBase 成员
  17. public string Description
  18. {
  19. get
  20. {
  21. // TODO: 添加 IServerPool.Description getter 实现
  22. return null;
  23. }
  24. }
  25. private ArrayList _objects = null;
  26. public ArrayList OwnObjects
  27. {
  28. get { return _objects; }
  29. set { _objects = value; }
  30. }
  31. private Hashtable _dbManager = null;
  32. public Hashtable DBManagerList
  33. {
  34. get { return _dbManager; }
  35. set { _dbManager = value; }
  36. }
  37. private Hashtable _htServiceKeys = null;
  38. public Hashtable HTServiceKeys
  39. {
  40. get { return _htServiceKeys; }
  41. set { _htServiceKeys = value; }
  42. }
  43. private Hashtable _htComponent = new Hashtable();
  44. public Hashtable HtComponent
  45. {
  46. get { return _htComponent; }
  47. set { _htComponent = value; }
  48. }
  49. private SrvDaemon _srvDaemon = null;
  50. public SrvDaemon srvDaemon
  51. {
  52. get { return _srvDaemon; }
  53. set { _srvDaemon = value; }
  54. }
  55. private Hashtable _htExtServer = null;
  56. public Hashtable HtExtServer
  57. {
  58. get { return _htExtServer; }
  59. set { _htExtServer = value; }
  60. }
  61. private ServerConfigure _servConf = null;
  62. public ServerConfigure ServerConfig
  63. {
  64. get { return _servConf; }
  65. set { _servConf = value; }
  66. }
  67. #endregion
  68. #region IDisposable 成员
  69. public void Dispose()
  70. {
  71. System.Collections.IEnumerator ie = this.HtComponent.GetEnumerator();
  72. while (ie.MoveNext())
  73. {
  74. try
  75. {
  76. System.Collections.DictionaryEntry de = (DictionaryEntry)ie.Current;
  77. DisposeClass((Hashtable)de.Value, 0);
  78. DisposeClass((Hashtable)de.Value, 1);
  79. }
  80. catch { }
  81. }
  82. }
  83. private void DisposeClass(Hashtable ht, int index)
  84. {
  85. try
  86. {
  87. ArrayList al = ht[index] as ArrayList;
  88. int count = al.Count;
  89. for (int i = 0; i < al.Count; i++)
  90. {
  91. try
  92. {
  93. ((IComponent)al[0]).Dispose();
  94. }
  95. catch { }
  96. }
  97. }
  98. catch { }
  99. }
  100. Assembly assembly = null;
  101. public bool LoadAllClass(string dll_file, string dbName)
  102. {
  103. if (!File.Exists(dll_file)) return false;
  104. try
  105. {
  106. assembly = Assembly.LoadFile(dll_file);
  107. foreach (Type type in assembly.GetTypes())
  108. {
  109. if (type.IsClass && type.IsSubclassOf(typeof(IComponent)))
  110. {
  111. LoadClass(type, dbName);
  112. }
  113. }
  114. return true;
  115. }
  116. catch { return false; }
  117. }
  118. //=======================================================
  119. // 加载单个类,并按最小副本数生成多个类的实例
  120. // classPoolHash 0--闲列表 1-忙列表 2--最小副本数 3--最大副本数
  121. //=======================================================
  122. public void LoadClass(Type moduleType, string dataBaseName)
  123. {
  124. try
  125. {
  126. string className = moduleType.FullName;
  127. //== 反射类
  128. IComponent module = (IComponent)Activator.CreateInstance(moduleType);
  129. module.DBName = dataBaseName;
  130. module.DBManagerList = this.DBManagerList;
  131. module.HTServiceKeys = this.HTServiceKeys;
  132. module.ServerConfig = this.ServerConfig;
  133. module.OwnObjects = this._objects;
  134. int maxCopyValue = module.maxValue;
  135. int minCopyValue = module.minValue;
  136. Hashtable classPoolHash = (Hashtable)HtComponent[className];
  137. if (classPoolHash == null)
  138. {
  139. classPoolHash = new Hashtable();
  140. HtComponent.Add(className, classPoolHash);
  141. }
  142. //存储每个类的空闲列表
  143. ArrayList freeList = classPoolHash[0] as ArrayList;
  144. if (freeList == null)
  145. {
  146. freeList = new ArrayList();
  147. classPoolHash.Add(0, freeList);
  148. }
  149. //存储一个空忙列表
  150. ArrayList busyList = classPoolHash[1] as ArrayList;
  151. if (busyList == null)
  152. {
  153. busyList = new ArrayList();
  154. classPoolHash.Add(1, busyList);
  155. }
  156. //加入最小副本数个副本到空闲列表
  157. freeList.Add(module);
  158. if (minCopyValue < 1) minCopyValue = 1;
  159. for (int i = 0; i < minCopyValue - 1; i++)
  160. {
  161. IComponent classObj = (IComponent)Activator.CreateInstance(moduleType);
  162. classObj.DBName = dataBaseName;
  163. classObj.DBManagerList = this.DBManagerList;
  164. classObj.HTServiceKeys = this.HTServiceKeys;
  165. classObj.ServerConfig = this.ServerConfig;
  166. classObj.OwnObjects = _objects;
  167. freeList.Add(classObj);
  168. }
  169. //加入最大,最小副本值
  170. classPoolHash.Add(2, maxCopyValue);
  171. classPoolHash.Add(3, minCopyValue);
  172. classPoolHash.Add(4, dataBaseName);
  173. }
  174. catch (Exception ex)
  175. {
  176. Console.WriteLine(ex.Message);
  177. }
  178. }
  179. #endregion
  180. private string _serverName = "";
  181. public string ServerName
  182. {
  183. get { return _serverName; }
  184. set { _serverName = value; }
  185. }
  186. private string _assemblyName = "";
  187. public string AssemblyName
  188. {
  189. get { return _assemblyName; }
  190. set { _assemblyName = value; }
  191. }
  192. public ReturnObject HandleMethod(string className, string methodName, object[] args)
  193. {
  194. //查找对应的业务组件子服务
  195. Result structObj = this.searchObject(className, methodName);
  196. if (structObj.busy.Equals("Error"))
  197. {
  198. //无此所访问的类
  199. return new ReturnObject(null, 10003, "未找到请求的服务![1]");
  200. }
  201. else if (structObj.busy.Equals("Wait"))
  202. {
  203. //达到最大访问限制,等待,超过规定时间放弃
  204. int i = 1;
  205. while (structObj.busy.Equals("Wait"))
  206. {
  207. if ((i++) > 30)
  208. {
  209. //3秒后放弃,超时返回
  210. return new ReturnObject(null, 10001, "服务正忙,请稍后再试!");
  211. }
  212. Thread.Sleep(100);
  213. structObj = this.searchObject(className, methodName);
  214. }
  215. }
  216. //得到正确的副本后...
  217. //设置相关信息
  218. Type type = structObj.obj.GetType();
  219. IComponent component = (IComponent)(structObj.obj);
  220. component.CallingMethodStartTime = DateTime.Now;
  221. component.CallingClass = type.FullName;
  222. //执行方法
  223. MethodInfo mthod = type.GetMethod(methodName);
  224. object myReturnObj;
  225. if (mthod == null)
  226. {
  227. myReturnObj = new ReturnObject(null, 10002, string.Format("调用的方法不存在,请检查方法名是否正确!\nServerName=[{0}]\nMethod=[{1}]", className, methodName));
  228. }
  229. else
  230. {
  231. try
  232. {
  233. myReturnObj = mthod.Invoke(structObj.obj, args);
  234. }
  235. catch (Exception ex)
  236. {
  237. if (((IComponent)(structObj.obj)).DBManager == null)
  238. {
  239. myReturnObj = new ReturnObject(null, 20000, "数据库链接不存在! 请检查服务器链接配置[DBManager]");
  240. }
  241. else
  242. {
  243. myReturnObj = new ReturnObject(null, ex.Message);
  244. }
  245. }
  246. }
  247. //释放副本
  248. this.realeasObject(className, structObj.obj as IComponent);
  249. if (myReturnObj.GetType().Equals(typeof(ReturnObject)))
  250. return (ReturnObject)myReturnObj;
  251. else
  252. return new ReturnObject(myReturnObj, 10005, "未按指定的类型定义返回值!");
  253. }
  254. public ReturnObject HandleMethodEx(string className, string methodName, object[] args, ArrayList _objs)
  255. {
  256. _objects = _objs;
  257. return HandleMethod(className, methodName, args);
  258. }
  259. private IComponent RequestServerResource(string className, string methodName)
  260. {
  261. if (srvDaemon == null) return null;
  262. string _sName = this.ServerName.Trim().ToUpper();
  263. string _cName = string.IsNullOrEmpty(className.Trim()) ? "" : "." + className.Trim().ToUpper();
  264. string _mName = string.IsNullOrEmpty(methodName.Trim()) ? "" : "." + methodName.Trim().ToUpper();
  265. string _name = _sName + _cName + _mName;
  266. double OccupyMem = 30.0;
  267. if (srvDaemon.SrvClassManager.ContainsKey(_name))
  268. {
  269. SrvClassInfo sci = (SrvClassInfo)(srvDaemon.SrvClassManager[_name]);
  270. OccupyMem = sci.AvgMemUsed;
  271. }
  272. SystemInfo si = new SystemInfo();
  273. if ((double)(si.MemoryAvailable / 1024 / 1024) - OccupyMem < ServerConfig.PreserveSystemMemory) return null;
  274. Assembly ab = Assembly.Load(this.AssemblyName);
  275. Type tp = ab.GetType(className);
  276. IComponent newObj = (IComponent)Activator.CreateInstance(tp);
  277. return newObj;
  278. }
  279. private Result searchObject(string className)
  280. {
  281. return searchObject(className, "");
  282. }
  283. private Result searchObject(string className, string methodName)
  284. {
  285. string busy = "Success";
  286. string err = "";
  287. Hashtable poolHash = (Hashtable)this.HtComponent[className];
  288. if (poolHash == null)
  289. {
  290. busy = "Error";
  291. err = "no the class";
  292. Result result = new Result(busy, err, null);
  293. return result;
  294. }
  295. lock (poolHash)
  296. {
  297. //取出空闲和忙列表
  298. ArrayList frList = poolHash[0] as ArrayList;
  299. ArrayList bsyList = poolHash[1] as ArrayList;
  300. if (bsyList == null)
  301. {
  302. bsyList = new ArrayList();
  303. poolHash.Add(1, bsyList);
  304. }
  305. //如果无空闲副本,且忙列表超过最大副本数目,等待后重新请求
  306. //否则返回空闲副本
  307. if (frList.Count > 0)
  308. {
  309. IComponent temp = (IComponent)frList[0];
  310. bsyList.Add(temp);
  311. frList.RemoveAt(0);
  312. Result result = new Result(busy, err, temp);
  313. return result;
  314. }
  315. //创建并返回新副本
  316. IComponent newObj = RequestServerResource(className, methodName);
  317. if (newObj != null)
  318. {
  319. newObj.DBManagerList = this.DBManagerList;
  320. newObj.DBName = poolHash[4].ToString();
  321. newObj.HTServiceKeys = this.HTServiceKeys;
  322. newObj.ServerConfig = this.ServerConfig;
  323. newObj.OwnObjects = _objects;
  324. bsyList.Add(newObj);
  325. Result result = new Result("Success", "", newObj);
  326. return result;
  327. }
  328. //最大,等待
  329. if (bsyList.Count == Convert.ToInt16(poolHash[2]))
  330. {
  331. busy = "Wait";
  332. Result result = new Result(busy, err, null);
  333. return result;
  334. }
  335. if (bsyList.Count < Convert.ToInt16(poolHash[2]))
  336. {
  337. Assembly ab = Assembly.Load(this.AssemblyName);
  338. Type tp = ab.GetType(className);
  339. newObj = (IComponent)Activator.CreateInstance(tp);
  340. newObj.DBManagerList = this.DBManagerList;
  341. newObj.DBName = poolHash[4].ToString();
  342. newObj.HTServiceKeys = this.HTServiceKeys;
  343. newObj.ServerConfig = this.ServerConfig;
  344. newObj.OwnObjects = _objects;
  345. bsyList.Add(newObj);
  346. Result result = new Result(busy, err, newObj);
  347. return result;
  348. }
  349. return new Result("", "", null);
  350. }
  351. }
  352. public string realeasObject(string className, IComponent busyObj)
  353. {
  354. string err = "success";
  355. Hashtable poolHash = (Hashtable)this.HtComponent[className];
  356. if (poolHash == null)
  357. {
  358. err = "no the class";
  359. return err;
  360. }
  361. lock (poolHash)
  362. {
  363. //移入空闲列表
  364. ArrayList frList = poolHash[0] as ArrayList;
  365. ArrayList bsyList = poolHash[1] as ArrayList;
  366. //如果空闲副本数目大于最小副本数目,销毁生存期较长副本
  367. if (frList.Count > Convert.ToInt16(poolHash[3]))
  368. {
  369. bsyList.Remove(busyObj);
  370. busyObj.Dispose();
  371. busyObj = null;
  372. return err;
  373. }
  374. else
  375. {
  376. bsyList.Remove(busyObj);
  377. frList.Add(busyObj);
  378. }
  379. return err;
  380. }
  381. }
  382. private string MD5key = "";
  383. public string MD5_KEY
  384. {
  385. get { return MD5key; }
  386. }
  387. private string SHA256key = "";
  388. public string SHA256_KEY
  389. {
  390. get { return SHA256key; }
  391. }
  392. public void GetFileKey(string filename, out string _MD5key, out string _SHA256key)
  393. {
  394. _MD5key = "";
  395. _SHA256key = "";
  396. if (!File.Exists(filename)) return;
  397. FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read);
  398. MD5 md5 = new MD5CryptoServiceProvider();
  399. byte[] b_md5 = md5.ComputeHash(file);
  400. file.Seek(0, SeekOrigin.Begin);
  401. byte[] b_sha256 = SHA256Managed.Create().ComputeHash(file);
  402. file.Close();
  403. StringBuilder sb = new StringBuilder();
  404. for (int i = 0; i < b_md5.Length; i++)
  405. {
  406. sb.Append(b_md5[i].ToString("x2"));
  407. }
  408. MD5key = sb.ToString();
  409. StringBuilder builder = new StringBuilder();
  410. for (int i = 0; i < b_sha256.Length; i++)
  411. {
  412. builder.Append(b_sha256[i].ToString("X2"));
  413. }
  414. SHA256key = builder.ToString();
  415. _MD5key = MD5_KEY;
  416. _SHA256key = SHA256_KEY;
  417. }
  418. public struct Result
  419. {
  420. public string busy;
  421. public string err;
  422. public object obj;
  423. public Result(string busy, string err, object obj)
  424. {
  425. this.busy = busy;
  426. this.err = err;
  427. this.obj = obj;
  428. }
  429. }
  430. }
  431. }