ConnectionBase.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using System.Threading;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using MECF.Framework.Common.Communications;
  7. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
  8. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot.HineAutomation
  9. {
  10. public abstract class ConnectionBase : IConnection
  11. {
  12. public string Address
  13. {
  14. get { return _address; }
  15. }
  16. public bool IsConnected
  17. {
  18. get { return _socket == null ? false : _socket.IsConnected; }
  19. }
  20. public bool Connect()
  21. {
  22. if (_socket == null)
  23. return true;
  24. if (_socket.IsConnecting)
  25. return true;
  26. Disconnect();
  27. if (!string.IsNullOrEmpty(_address))
  28. {
  29. if (SC.GetValue<bool>("System.IsSimulatorMode"))
  30. _socket = new AsyncSocket(_address, "\r");
  31. else
  32. _socket = new AsyncSocket(_address, "\n");
  33. _socket.OnDataChanged += new AsyncSocket.MessageHandler(OnDataReceived);
  34. _socket.OnErrorHappened += new AsyncSocket.ErrorHandler(OnErrorHappened);
  35. _socket.EnableLog = SC.GetValue<bool>($"TMRobot.EnableLogMessage");
  36. }
  37. _socket.Connect(_address);
  38. return true;
  39. }
  40. public bool Disconnect()
  41. {
  42. if (_socket != null)
  43. {
  44. _socket.Dispose();
  45. _socket = null;
  46. }
  47. return true;
  48. }
  49. public bool IsBusy
  50. {
  51. get { return _activeHandler != null; }
  52. }
  53. public bool IsCommunicationError { get; private set; }
  54. public string LastCommunicationError { get; private set; }
  55. protected AsyncSocket _socket;
  56. protected HandlerBase _activeHandler; //set, control,
  57. protected object _lockerActiveHandler = new object();
  58. private string _address;//ip:port
  59. private RD_TRIG _trigCommunicationError = new RD_TRIG();
  60. public bool EnableRetry { get; set; }
  61. public R_TRIG _trigRetryConnect = new R_TRIG();
  62. public int MaxRetryCount { get; set; }
  63. public ConnectionBase(string addr)
  64. {
  65. _address = addr;
  66. if (!string.IsNullOrEmpty(addr))
  67. {
  68. if (SC.GetValue<bool>("System.IsSimulatorMode"))
  69. _socket = new AsyncSocket(addr, "\r");
  70. else
  71. _socket = new AsyncSocket(addr, "\n");
  72. _socket.OnDataChanged += new AsyncSocket.MessageHandler(OnDataReceived);
  73. _socket.OnErrorHappened += new AsyncSocket.ErrorHandler(OnErrorHappened);
  74. }
  75. }
  76. private void OnErrorHappened(ErrorEventArgs args)
  77. {
  78. }
  79. public void Execute(HandlerBase handler)
  80. {
  81. if (_activeHandler != null)
  82. return;
  83. if (handler == null)
  84. return;
  85. if (IsConnected)
  86. {
  87. lock (_lockerActiveHandler)
  88. {
  89. _activeHandler = handler;
  90. _activeHandler.SetState(EnumHandlerState.Sent);
  91. }
  92. if (!_socket.Write(handler.SendText))
  93. {
  94. lock (_lockerActiveHandler)
  95. {
  96. _activeHandler = null;
  97. }
  98. IsCommunicationError = true;
  99. }
  100. if (_activeHandler != null && !((HAtmHandler)_activeHandler).HasResponse)
  101. {
  102. lock (_lockerActiveHandler)
  103. {
  104. _activeHandler = null;
  105. }
  106. }
  107. }
  108. }
  109. protected abstract MessageBase ParseResponse(string rawMessage);
  110. protected virtual void OnEventArrived(MessageBase msg)
  111. {
  112. }
  113. protected abstract void OnDataReceived(string oneLineMessage);
  114. public HandlerBase MonitorTimeout()
  115. {
  116. HandlerBase result = null;
  117. lock (_lockerActiveHandler)
  118. {
  119. if (_activeHandler != null && _activeHandler.CheckTimeout())
  120. {
  121. result = _activeHandler;
  122. _activeHandler = null;
  123. SetCommunicationError(true, "receive response timeout");
  124. }
  125. }
  126. return result;
  127. }
  128. /// <summary>
  129. ///
  130. /// </summary>
  131. /// <param name="retryConnectMaxCount">-1 keep retry, 0 no retry</param>
  132. public void MonitorConnection(int retryMaxCount, out bool retried)
  133. {
  134. retried = false;
  135. _trigRetryConnect.CLK = IsCommunicationError || !IsConnected;
  136. if (_trigRetryConnect.Q)
  137. {
  138. int retry = 0;
  139. while (retry < retryMaxCount || retryMaxCount < 0)
  140. {
  141. LOG.Write($"Retry connect with {_address} for the {retry+1} time.");
  142. Connect();
  143. Thread.Sleep(retry * 1000);
  144. retried = true;
  145. lock (_lockerActiveHandler)
  146. {
  147. _activeHandler = null;
  148. }
  149. if (IsConnected)
  150. break;
  151. retry++;
  152. //break;
  153. }
  154. }
  155. SetCommunicationError(false, "retried");
  156. }
  157. /// <summary>
  158. /// receive invalid packet
  159. /// send out timeout
  160. /// receive response timeout
  161. /// </summary>
  162. /// <param name="isError"></param>
  163. /// <param name="reason"></param>
  164. public void SetCommunicationError(bool isError, string reason)
  165. {
  166. IsCommunicationError = isError;
  167. LastCommunicationError = reason;
  168. _trigCommunicationError.CLK = isError;
  169. if (_trigCommunicationError.R)
  170. {
  171. LOG.Write($"{Address} communication error, {reason}");
  172. }
  173. if (_trigCommunicationError.T)
  174. {
  175. LOG.Write($"{Address} communication error recovered, {reason}");
  176. }
  177. }
  178. public void Reset()
  179. {
  180. _trigRetryConnect.RST = true;
  181. }
  182. }
  183. }