终端一体化运控平台
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

279 行
9.0 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Threading.Tasks;
  7. namespace BPASmartClient.MessageCommunication.MsgControl
  8. {
  9. /// <summary>
  10. /// 内部消息总线
  11. /// </summary>
  12. public class InnerMessageBus
  13. {
  14. static InnerMessageBus _bus;
  15. const int TimeOut = 2000;
  16. static public InnerMessageBus Get_Instance()
  17. {
  18. if (_bus == null)
  19. {
  20. _bus = new InnerMessageBus();
  21. }
  22. return _bus;
  23. }
  24. #region 委托事件的定义
  25. /// <summary>
  26. /// 当触发引用事件时执行的委托
  27. /// </summary>
  28. public delegate void MessageEventHandler(object sender,InnerMessageEventArgs e);
  29. #endregion
  30. #region 自定义各类响应事件
  31. /// <summary>
  32. /// 返回为整数型的结果事件响应
  33. /// </summary>
  34. public event MessageEventHandler M_Event_消息事件;
  35. #endregion
  36. private readonly Object thisLock = new Object();
  37. /// <summary>
  38. /// 发送消息方法
  39. /// ----------------------------------------------
  40. /// </summary>
  41. /// <param name="sender">消息发送者</param>
  42. /// <param name="str_Msg">消息名称串</param>
  43. /// <param name="obj_Data">消息体数据区</param>
  44. public void PostMessage(object sender,string str_Msg,object obj_Data)
  45. {
  46. bool isLock = false;
  47. System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock);
  48. if (!isLock)//理论上不可能出现
  49. {
  50. return;
  51. }
  52. try
  53. {
  54. var temp = RouteTable.ToList();
  55. foreach (ListenPointInfo item in temp)
  56. {
  57. if (MachMessageName(str_Msg,item))
  58. {
  59. InnerMessageEventArgs temp_arg = new InnerMessageEventArgs();
  60. temp_arg.obj_Sender = sender;
  61. temp_arg.obj_MessageObj = obj_Data;
  62. temp_arg.str_MessageStr = str_Msg;
  63. TypeHelper helper = new TypeHelper();
  64. object[] args = new object[2];
  65. args[0] = sender;
  66. args[1] = temp_arg;
  67. if (sender != null)
  68. {
  69. try
  70. {
  71. helper.M_Call_InstancMethod(item.PointObj,item.MethodName,args);
  72. }
  73. catch (Exception exp)
  74. {
  75. }
  76. }
  77. }
  78. }
  79. }
  80. catch (Exception exp)
  81. {
  82. //接收消息的调用方法发生异常
  83. }
  84. finally
  85. {
  86. System.Threading.Monitor.Exit(thisLock);
  87. }
  88. }
  89. /// <summary>
  90. /// 采用正则表达式匹配字符串
  91. /// </summary>
  92. /// <param name="MessageString"></param>
  93. /// <param name="item"></param>
  94. /// <returns></returns>
  95. private static bool MachMessageName(string MessageString,ListenPointInfo item)
  96. {
  97. string value;
  98. string pattern;
  99. value = MessageString;
  100. try
  101. {
  102. pattern = item.str_Message.Replace("*",@"[-\.\w]*");
  103. ///使用正则表达式进行消息路由匹配;
  104. if (pattern.Contains('*'))
  105. {
  106. if (Regex.IsMatch(value,pattern))
  107. {
  108. //Console.WriteLine("路由消息" + MessageString + " * " + (((item.PointObj.GetType()).FullName + "匹配成功!")));
  109. return true;
  110. }
  111. else
  112. {
  113. return false;
  114. }
  115. }
  116. else
  117. {
  118. if (value == pattern)
  119. {
  120. //Console.WriteLine("路由消息" + MessageString + "匹配成功!");
  121. return true;
  122. }
  123. else
  124. {
  125. return false;
  126. }
  127. }
  128. }
  129. catch (Exception ex)
  130. {
  131. Console.WriteLine("InnerMessageBus类MachMessageName方法出错,原因:" + ex.Message);
  132. return false;
  133. }
  134. }
  135. /// <summary>
  136. /// 消息路由表,内部的
  137. /// </summary>
  138. List<ListenPointInfo> RouteTable = new List<ListenPointInfo>();
  139. /// <summary>
  140. /// 外部应用调用消息
  141. /// </summary>
  142. /// <param name="obj_Listener">消息监听对象者</param>
  143. /// <param name="str_MessageString"></param>
  144. /// <param name="handler"></param>
  145. public void ListenMessage(object obj_Listener,string str_MessageString,string str_处理方法名称)
  146. {
  147. // arg = new InnerMessageEventArgs();
  148. Type[] argTypes = new Type[2];
  149. argTypes[0] = typeof(object);
  150. argTypes[1] = typeof(InnerMessageEventArgs);
  151. if (obj_Listener.GetType().GetMethod(str_处理方法名称,argTypes) != null)
  152. {
  153. ListenPointInfo info = new ListenPointInfo();
  154. info.PointObj = obj_Listener;
  155. info.str_Message = str_MessageString;
  156. info.MethodName = str_处理方法名称;
  157. bool isLock = false;
  158. System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock);
  159. if (!isLock)//理论上不可能出现
  160. {
  161. return;
  162. }
  163. try
  164. {
  165. RouteTable.Add(info);
  166. }
  167. finally
  168. {
  169. System.Threading.Monitor.Exit(thisLock);
  170. }
  171. }
  172. else
  173. {
  174. TypeHelper helper = new TypeHelper();
  175. if ((helper.M_GetMethodInfosByName(obj_Listener.GetType(),str_处理方法名称).Count != 1))
  176. {
  177. //taoye modified
  178. Console.WriteLine("在使用消息中间件时,希望执行ListenMessage方法,绑定" + obj_Listener.GetType().ToString() + "中方法:" + str_处理方法名称 + ",但该方法不唯一或不存在.");
  179. }
  180. }
  181. }
  182. /// <summary>
  183. /// 关闭消息监听和事件的挂接关系
  184. /// </summary>
  185. /// <param name="str">消息名称</param>
  186. /// <param name="str_消息处理方法名称">消息处理方法名称</param>
  187. public void ListenMessage_trunOff(string str,string str_消息处理方法名称)
  188. {
  189. bool isLock = false;
  190. System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock);
  191. if (!isLock)//理论上不可能出现
  192. {
  193. return;
  194. }
  195. try
  196. {
  197. for (int i = RouteTable.Count - 1; i >= 0; i--)
  198. {
  199. if (str == RouteTable[i].str_Message && str_消息处理方法名称 == RouteTable[i].MethodName)
  200. {
  201. RouteTable.RemoveAt(i);
  202. break;
  203. }
  204. }
  205. }
  206. finally
  207. {
  208. System.Threading.Monitor.Exit(thisLock);
  209. }
  210. }
  211. /// <summary>
  212. /// 采用对象方式直接释放指定对象的监听信息
  213. /// </summary>
  214. /// <param name="obj"></param>
  215. /// <returns></returns>
  216. private bool RemoveRouteTableByObject(object obj)
  217. {
  218. bool isLock = false;
  219. System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock);
  220. if (!isLock)//理论上不可能出现
  221. {
  222. return false;
  223. }
  224. bool result = false;
  225. int currentI = -1;
  226. try
  227. {
  228. for (int i = 0; i < this.RouteTable.Count; i++)
  229. {
  230. if (RouteTable[i].PointObj == obj)
  231. {
  232. currentI = i;
  233. }
  234. }
  235. if (currentI != -1)
  236. {
  237. RouteTable.RemoveAt(currentI);
  238. result = true;
  239. }
  240. }
  241. finally
  242. {
  243. System.Threading.Monitor.Exit(thisLock);
  244. }
  245. return result;
  246. }
  247. /// <summary>
  248. /// 调试用属性,获取当前路由表所有的信息,只读
  249. /// </summary>
  250. public List<ListenPointInfo> __Debug_RoutTable
  251. {
  252. get
  253. {
  254. return this.RouteTable;
  255. }
  256. }
  257. }
  258. }