DeviceSimulator.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. using Aitex.Core.Util;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Security.Permissions;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace MECF.Framework.Simulator.Core.Driver
  9. {
  10. public class DeviceSimulator
  11. {
  12. public event Action<string> MessageIn;
  13. public event Action<string> MessageOut;
  14. public event Action<string> ErrorOccur;
  15. public virtual bool IsEnabled
  16. {
  17. get { return false; }
  18. }
  19. public virtual bool IsConnected
  20. {
  21. get { return false; }
  22. }
  23. public bool BinaryDataMode { get; set; } = true;
  24. protected SortedList<string, Action<string>> commandList = new SortedList<string, Action<string>>();
  25. protected string _lineDelimiter;
  26. protected char _msgDelimiter;
  27. protected int _commandIndex;
  28. protected int _cmdMaxLength = 4;
  29. private FixSizeQueue<string> _lstAsciiMsgs = new FixSizeQueue<string>(1000);
  30. private FixSizeQueue<byte[]> _lstBinMsgs = new FixSizeQueue<byte[]>(1000);
  31. private PeriodicJob _thread;
  32. public DeviceSimulator(int commandIndex, string lindDelimiter, char msgDelimiter, int cmdMaxLength=4)
  33. {
  34. _lineDelimiter = lindDelimiter;
  35. _msgDelimiter = msgDelimiter;
  36. _commandIndex = commandIndex;
  37. _cmdMaxLength = cmdMaxLength;
  38. _thread = new PeriodicJob(100, MonitorMessages, "Monitor Messages Thread", true);
  39. }
  40. private bool MonitorMessages()
  41. {
  42. try
  43. {
  44. string asciimsg;
  45. while (_lstAsciiMsgs.TryDequeue(out asciimsg))
  46. {
  47. ProcessUnsplitMessage(asciimsg);
  48. }
  49. byte[] binmsg;
  50. while (_lstBinMsgs.TryDequeue(out binmsg))
  51. {
  52. ProcessUnsplitMessage(binmsg);
  53. }
  54. }
  55. catch (Exception ex)
  56. {
  57. System.Diagnostics.Trace.WriteLine(ex);
  58. }
  59. return true;
  60. }
  61. protected virtual void AddCommandHandler(string command, Action<string> handler)
  62. {
  63. commandList.Add(command, handler);
  64. }
  65. protected virtual void ProcessUnsplitMessage(string message)
  66. {
  67. }
  68. protected virtual void ProcessUnsplitMessage(byte[] message)
  69. {
  70. }
  71. protected virtual void OnErrorMessage(string message)
  72. {
  73. if (ErrorOccur != null)
  74. {
  75. ErrorOccur(message);
  76. }
  77. }
  78. protected void AddMessageIn(string message)
  79. {
  80. if (MessageIn != null)
  81. {
  82. MessageIn(message);
  83. }
  84. }
  85. protected void OnReadMessage(byte[] message)
  86. {
  87. if (MessageIn != null)
  88. {
  89. if (BinaryDataMode)
  90. {
  91. MessageIn(string.Join(" ", Array.ConvertAll(message, x=>x.ToString("X2"))));
  92. }
  93. MessageIn(Encoding.ASCII.GetString(message));
  94. }
  95. // liuyao : 这里好像有点什么问题,如果发byte会不行,我也忘记了
  96. //OnReadMessage(Encoding.ASCII.GetString(message));
  97. _lstBinMsgs.Enqueue(message);
  98. //ProcessUnsplitMessage(message);
  99. }
  100. protected void OnReadMessage(string message)
  101. {
  102. if (MessageIn != null)
  103. {
  104. MessageIn(message);
  105. }
  106. if (_commandIndex < 0)
  107. {
  108. _lstAsciiMsgs.Enqueue(message);
  109. //ProcessUnsplitMessage(message);
  110. return;
  111. }
  112. if (_msgDelimiter.Equals(' '))
  113. {
  114. //string cmd = message.Contains(_msgDelimiter)? message.Substring(_commandIndex, _cmdMaxLength):message;
  115. string cmd = message.Substring(_commandIndex, _cmdMaxLength);
  116. if (cmd.Contains(_msgDelimiter))
  117. cmd = cmd.Substring(0, cmd.IndexOf(_msgDelimiter));
  118. if (!commandList.ContainsKey(cmd))
  119. {
  120. CommandNotRecognized(message);
  121. }
  122. else
  123. {
  124. //Log.WriteIfEnabled( LogCategory.Debug, source, DeviceId + ":ProcessMessages: '" + msg.Message );
  125. var handler = commandList[cmd];
  126. if (handler == null)
  127. {
  128. //Log.WriteIfEnabled( LogCategory.Error, source, DeviceId + ":ProcessMessages: CANNOT FIND MESSAGE HANDLER '" + msg.Message );
  129. }
  130. else
  131. {
  132. if (!message.Contains("stat_pdo") && !message.Contains("statfx"))
  133. {
  134. //Log.WriteIfEnabled(LogCategory.Debug, source, "Received command " + message);
  135. }
  136. handler(message);
  137. }
  138. }
  139. }
  140. else
  141. {
  142. string[] msgComponents = message.Split(_msgDelimiter);
  143. int index = msgComponents[0] == "$$$" ? 1 : _commandIndex;
  144. if (msgComponents.Length <= index)
  145. {
  146. CommandNotRecognized(message);
  147. return;
  148. }
  149. // find the message handler in the dictionary
  150. string cmd = msgComponents[index];
  151. if (!commandList.ContainsKey(cmd))
  152. {
  153. CommandNotRecognized(message);
  154. }
  155. else
  156. {
  157. //Log.WriteIfEnabled( LogCategory.Debug, source, DeviceId + ":ProcessMessages: '" + msg.Message );
  158. var handler = commandList[cmd];
  159. if (handler == null)
  160. {
  161. //Log.WriteIfEnabled( LogCategory.Error, source, DeviceId + ":ProcessMessages: CANNOT FIND MESSAGE HANDLER '" + msg.Message );
  162. }
  163. else
  164. {
  165. if (!message.Contains("stat_pdo") && !message.Contains("statfx"))
  166. {
  167. //Log.WriteIfEnabled(LogCategory.Debug, source, "Received command " + message);
  168. }
  169. handler(message);
  170. }
  171. }
  172. }
  173. }
  174. protected virtual void CommandNotRecognized(string msg)
  175. {
  176. if (commandList.ContainsKey("Unknown") && commandList["Unknown"] != null)
  177. {
  178. commandList["Unknown"](msg);
  179. }
  180. else
  181. {
  182. ProcessWriteMessage("_ERR Unrecognized command");
  183. }
  184. }
  185. protected virtual void OnWriteMessage(string msg)
  186. {
  187. if (MessageOut != null)
  188. MessageOut(msg);
  189. ProcessWriteMessage(msg);
  190. }
  191. protected void OnWriteMessage(byte[] msg)
  192. {
  193. if (MessageOut != null)
  194. MessageOut(string.Join(" ", Array.ConvertAll(msg, x => x.ToString("X2"))));
  195. ProcessWriteMessage(msg);
  196. }
  197. protected virtual void ProcessWriteMessage(string msg)
  198. {
  199. }
  200. protected virtual void ProcessWriteMessage(byte[] msg)
  201. {
  202. }
  203. }
  204. }