26a2ec87719ad5c4faf0c434ac83b6e8a4f12a4f.svn-base 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. using System;
  2. using System.IO;
  3. using System.Xml;
  4. using System.Data;
  5. using System.Text;
  6. using System.Collections;
  7. using System.Reflection;
  8. using System.Configuration;
  9. using Core.Mes.Common;
  10. using Core.Mes.IBaseInterface;
  11. namespace Core.Mes.ServerFrameWork
  12. {
  13. [Serializable]
  14. public class Dispatcher : MarshalByRefObject, ICommon
  15. {
  16. private ArrayList _objects = null;
  17. private ServerConfigure _servConf = null;
  18. public ServerConfigure ServConfig
  19. {
  20. get { return _servConf; }
  21. }
  22. #region " Construct "
  23. public Dispatcher() { }
  24. public Dispatcher(IServerPool pool, ServerConfigure _conf, ArrayList _objs)
  25. {
  26. Pool = pool;
  27. _servConf = _conf;
  28. _objects = _objs;
  29. }
  30. private IServerPool _pool = null;
  31. public IServerPool Pool
  32. {
  33. get { return _pool; }
  34. set
  35. {
  36. _pool = value;
  37. if (_pool.OwnObjects == null && _objects != null) _pool.OwnObjects = _objects;
  38. }
  39. }
  40. #endregion
  41. #region " Variable "
  42. //== 子服务集合
  43. public static Hashtable _htServers = new Hashtable();
  44. //== 数据链接集合
  45. public static Hashtable htDBManager = new Hashtable();
  46. public event GetStatusInfoHandler getStatusInfo;
  47. public delegate void GetStatusInfoHandler(string info);
  48. protected virtual void SetStatusMessage(string info)
  49. {
  50. if (getStatusInfo != null)
  51. {
  52. getStatusInfo(info);
  53. }
  54. }
  55. #endregion
  56. #region 内存释放
  57. public void MemoryDispose()
  58. {
  59. long memorysize = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
  60. int PagedMemorySize = (int)memorysize / (1024 * 1024);
  61. if (PagedMemorySize > _servConf.MemoryMaxSize)//进程占用内存>100M 做GC.
  62. {
  63. try
  64. {
  65. GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
  66. }
  67. catch
  68. {
  69. }
  70. System.Diagnostics.Process.GetCurrentProcess().Dispose();
  71. }
  72. }
  73. #endregion
  74. #region MethodTimeLog
  75. private static object lockObj = new object();
  76. public void MethodTimeLog(TimeSpan tspan, object[] objs, object[] args)
  77. {
  78. string path = string.Format(@"./log/Method/MethodTimeLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd"));
  79. lock (lockObj)
  80. {
  81. using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
  82. {
  83. StringBuilder sbtxt = new StringBuilder();
  84. sbtxt.AppendLine("==============================================");
  85. sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
  86. sbtxt.AppendLine(string.Format("Time:{0}", tspan.TotalMilliseconds));
  87. sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString()));
  88. sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString()));
  89. if (args != null)
  90. {
  91. foreach (object obj in args)
  92. {
  93. if (obj != null)
  94. {
  95. sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString()));
  96. }
  97. }
  98. }
  99. sbtxt.AppendLine("==============================================");
  100. sw.WriteLine(sbtxt.ToString());
  101. }
  102. }
  103. }
  104. public void MethodErrLog(Exception ex, object[] objs, object[] args)
  105. {
  106. string path = string.Format(@"./log/Method/MethodErrLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd"));
  107. lock (lockObj)
  108. {
  109. using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
  110. {
  111. StringBuilder sbtxt = new StringBuilder();
  112. sbtxt.AppendLine("==============================================");
  113. sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
  114. sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString()));
  115. sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString()));
  116. if (args != null)
  117. {
  118. foreach (object obj in args)
  119. {
  120. if (obj != null)
  121. {
  122. sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString()));
  123. }
  124. }
  125. }
  126. sbtxt.AppendLine(ex.Message);
  127. sbtxt.AppendLine(ex.StackTrace);
  128. sbtxt.AppendLine("==============================================");
  129. sw.WriteLine(sbtxt.ToString());
  130. }
  131. }
  132. }
  133. public void DebugLog(object[] objs, object[] args)
  134. {
  135. string path = string.Format(@"./log/Method/DebugLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd"));
  136. lock (lockObj)
  137. {
  138. if (File.Exists(Path.GetFullPath(path)))
  139. {
  140. FileInfo fileInfo = new FileInfo(Path.GetFullPath(path));
  141. if (fileInfo.Length / (1024 * 1024) > 6)
  142. {
  143. File.Delete(path);
  144. }
  145. }
  146. using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
  147. {
  148. StringBuilder sbtxt = new StringBuilder();
  149. sbtxt.AppendLine("==============================================");
  150. sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
  151. sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString()));
  152. sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString()));
  153. if (args != null)
  154. {
  155. foreach (object obj in args)
  156. {
  157. if (obj != null)
  158. {
  159. sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString()));
  160. }
  161. }
  162. }
  163. sbtxt.AppendLine("==============================================");
  164. sw.WriteLine(sbtxt.ToString());
  165. }
  166. }
  167. }
  168. #endregion
  169. #region " 调用服务 "
  170. /// <summary>
  171. /// 服务端公开给客户端的调用后台服务的方法
  172. /// </summary>
  173. /// <param name="message"></param>
  174. /// <returns></returns>
  175. public ReturnObject MethodHandler(CallingMessage message, ValidateInfo validateInfo)
  176. {
  177. CallingMessageEx messageEx = new CallingMessageEx();
  178. messageEx.FromCallingMessage(message);
  179. messageEx.RedirectLimit = 0;
  180. messageEx.InnerServerRedirect = true;
  181. ReturnObjectEx rtnObjEx = RelayMessage(messageEx, validateInfo);
  182. ReturnObject rtnObj = new ReturnObject();
  183. rtnObj.ErrCode = rtnObjEx.ErrCode;
  184. rtnObj.ErrMessage = rtnObjEx.ErrMessage;
  185. rtnObj.RealDataSet = rtnObjEx.RealDataSet;
  186. rtnObj.RealObject = rtnObjEx.RealObject;
  187. return rtnObj;
  188. }
  189. public ReturnObjectEx MethodHandlerEx(CallingMessageEx message, ValidateInfo validateInfo)
  190. {
  191. return RelayMessage(message, validateInfo);
  192. }
  193. private ReturnObjectEx RelayMessage(CallingMessageEx messageEx, ValidateInfo validateInfo)
  194. {
  195. string serverName = messageEx.ServerName;
  196. string assemblyName = messageEx.AssemblyName;
  197. string className = messageEx.ClassName;
  198. string methodName = messageEx.MethodName;
  199. object[] args = messageEx.args;
  200. ReturnObjectEx rtnObjEx = new ReturnObjectEx();
  201. try
  202. {
  203. if (serverName.ToUpper() != "SERVERCOMMON" && messageEx.RedirectLimit > 0)
  204. {
  205. string RedirURL = "";
  206. double sum_factor = 0;
  207. ArrayList serviceProvider = new ArrayList();
  208. ArrayList pfactors = new ArrayList();
  209. serviceProvider.Add("THIS");
  210. sum_factor += this.ServConfig.PriorityFactor;
  211. pfactors.Add(sum_factor);
  212. foreach (string server in Pool.HtExtServer.Keys)
  213. {
  214. RemotingServer rs = (RemotingServer)Pool.HtExtServer[server];
  215. if (rs.Valid != RemoteServerStatus.Normal || rs.Enable == false) continue;
  216. rs.FindRemoteServer(serverName);
  217. if (!rs.HTServices.ContainsKey(serverName)) continue;
  218. ServiceObject so = ((ServiceObject)(rs.HTServices[serverName]));
  219. if (so.Valid != ServiceObjectStatus.Normal || so.Enable == false) continue;
  220. RedirURL = so.URL;
  221. sum_factor += rs.PriorityFactor;
  222. serviceProvider.Add(server);
  223. pfactors.Add(sum_factor);
  224. }
  225. Random rand = new Random();
  226. double rand_selector = rand.NextDouble() * sum_factor;
  227. int selector = 0;
  228. for (int idx = 0 ; idx < pfactors.Count ; idx++)
  229. {
  230. if (rand_selector <= (double)pfactors[idx])
  231. {
  232. selector = idx;
  233. break;
  234. }
  235. }
  236. if (selector != 0)
  237. {
  238. SimpleReturnObject _out = new SimpleReturnObject();
  239. if (messageEx.InnerServerRedirect)
  240. {
  241. //通过服务器转发调用。(由本服务器 调用其他服务器方法,并转发结果到客户机)
  242. RemotingServer rs = (RemotingServer)Pool.HtExtServer[serviceProvider[selector]];
  243. rtnObjEx = (ReturnObjectEx)rs.ExecuteMethod(messageEx, out _out);
  244. return rtnObjEx;
  245. }
  246. else
  247. {
  248. //不转发调用。(返回其他服务器地址,由客户机自行调用)
  249. rtnObjEx.ReDirectURL = RedirURL;
  250. return rtnObjEx;
  251. }
  252. }
  253. }
  254. //调用本地服务
  255. return ExecuteLocalService(messageEx, validateInfo);
  256. }
  257. catch (Exception ex)
  258. {
  259. MethodErrLog(ex, new object[] { className, methodName }, args);
  260. return new ReturnObjectEx(null, "服务调用发生异常! \n" + ex.Message);
  261. }
  262. }
  263. private ReturnObjectEx ExecuteLocalService(CallingMessageEx messageEx, ValidateInfo validateInfo)
  264. {
  265. //step1:
  266. MemoryDispose();
  267. //step2:
  268. string serverName = messageEx.ServerName;
  269. string assemblyName = messageEx.AssemblyName;
  270. string className = messageEx.ClassName;
  271. string methodName = messageEx.MethodName;
  272. object[] args = messageEx.args;
  273. ReturnObjectEx rtnObjEx = new ReturnObjectEx();
  274. MethodInfo myMethod = null;
  275. try
  276. {
  277. if (Pool.HtComponent.Contains(className))
  278. {
  279. try
  280. {
  281. //使用本地服务
  282. myMethod = Pool.GetType().GetMethod("HandleMethodEx");
  283. DateTime startTime = DateTime.Now;
  284. if (_servConf.Debug == "true")
  285. {
  286. DebugLog(new object[] { className, methodName }, args);
  287. }
  288. ReturnObject rtnObj = (ReturnObject)myMethod.Invoke(Pool, new object[] { className, methodName, args, _objects });
  289. rtnObjEx.ReDirectURL = "";
  290. rtnObjEx.ErrCode = rtnObj.ErrCode;
  291. rtnObjEx.ErrMessage = rtnObj.ErrMessage;
  292. rtnObjEx.RealDataSet = rtnObj.RealDataSet;
  293. rtnObjEx.RealObject = rtnObj.RealObject;
  294. DateTime endTime = DateTime.Now;
  295. TimeSpan tspan = endTime - startTime;
  296. if (tspan.TotalMilliseconds > (_servConf.MethodTime * 1000))
  297. {
  298. MethodTimeLog(tspan, new object[] { className, methodName }, args);
  299. }
  300. if (rtnObjEx.RealObject != null)
  301. {
  302. #region 返回值为表格
  303. if (rtnObjEx.RealObject.GetType() == typeof(DataSet))
  304. {
  305. DataSet _ds = (DataSet)rtnObjEx.RealObject;
  306. bool largeData = false;
  307. int row_cnt = 0;
  308. foreach (DataTable _dt in _ds.Tables)
  309. {
  310. row_cnt += _dt.Rows.Count;
  311. if (_dt.Rows.Count > _servConf.CompressThreshold || row_cnt > _servConf.CompressThreshold)
  312. {
  313. largeData = true;
  314. break;
  315. }
  316. }
  317. if (largeData)
  318. {
  319. byte[] _rtn = Utility.SerializeDataSet(_ds);
  320. _ds.Dispose();
  321. _ds = null;
  322. rtnObjEx.RealObject = null;
  323. byte[] _rtn_comp = Utility.CompressBytes(_rtn);
  324. DataTable dt_rus = new DataTable("RETURN_RESULT");
  325. dt_rus.Columns.AddRange(new DataColumn[]{
  326. new DataColumn("IsCompressed", System.Type.GetType("System.Int32") ),
  327. new DataColumn("UnCompress_size", System.Type.GetType("System.Int32")),
  328. new DataColumn("Compress_size", System.Type.GetType("System.Int32"))}
  329. );
  330. dt_rus.AcceptChanges();
  331. dt_rus.Rows.Add(new object[] { 1, _rtn.Length, _rtn_comp.Length });
  332. dt_rus.AcceptChanges();
  333. if (rtnObjEx.RealDataSet == null)
  334. {
  335. rtnObjEx.RealDataSet = new DataSet();
  336. }
  337. rtnObjEx.RealDataSet.Tables.Add(dt_rus);
  338. rtnObjEx.RealObject = _rtn_comp;
  339. }
  340. }
  341. else if (rtnObjEx.RealObject.GetType() == typeof(ArrayList))
  342. {
  343. }
  344. #endregion
  345. }
  346. return rtnObjEx;
  347. }
  348. catch (Exception ex)
  349. {
  350. MethodErrLog(ex, new object[] { className, methodName }, args);
  351. return new ReturnObjectEx(null, ex.Message);
  352. }
  353. finally
  354. {
  355. try
  356. {
  357. if (rtnObjEx.RealObject != null)
  358. {
  359. rtnObjEx.RealObject = null;
  360. }
  361. if (rtnObjEx.RealDataSet != null)
  362. {
  363. rtnObjEx.RealDataSet = null;
  364. }
  365. }
  366. catch { }
  367. }
  368. }
  369. else
  370. {
  371. return new ReturnObjectEx(null, "未找到请求的服务![2]");
  372. }
  373. }
  374. catch (Exception ex)
  375. {
  376. return new ReturnObjectEx(null, "服务调用发生异常! \n" + ex.Message);
  377. }
  378. }
  379. #endregion
  380. #region " Common Handler "
  381. //=======================================================
  382. // 用来确保当创建 Singleton 时, 第一个实例永远不会过期
  383. //=======================================================
  384. public override object InitializeLifetimeService()
  385. {
  386. return null;
  387. }
  388. #endregion
  389. }
  390. }