fbdbc6cafd61920e516bf068507f9a6aba510f29.svn-base 15 KB

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