DeviceSimulator.cs 7.4 KB

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