TlvCommunicatorClient.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System.Threading.Tasks;
  2. namespace TLVProtocal;
  3. internal class TlvCommunicatorClient : BaseFilter, ITlvCommunicatorClient
  4. {
  5. private ITcpClient _tcpClient;
  6. private ITlvProvider _provider;
  7. private MessageQueue _messageQueue;
  8. private MessageReceiveQueue _receiveQueue;
  9. private TlvAckLayer _ackLayer;
  10. private TlvPackLayer _packLayer;
  11. private TlvContentLayer _contentLayer;
  12. private RawDataLog _dataLogLayer;
  13. private ushort _requestID = 0;
  14. private int _timeoutTimer = 0;
  15. private readonly ConcurrentDictionary<ushort, SyncMessage> _requests = [];
  16. bool ITlvCommunicatorClient.Initialize(ITlvProvider provider, bool ConvertToBigEnd, int timeoutTime)
  17. {
  18. if (this._tcpClient is not null)
  19. return false;
  20. this._tcpClient = IOFactory.GetTcpClient();
  21. this._provider = provider;
  22. this._timeoutTimer = timeoutTime;
  23. this._ackLayer = new(ConvertToBigEnd, timeoutTime);
  24. this._packLayer = new(ConvertToBigEnd);
  25. this._contentLayer = new(ConvertToBigEnd);
  26. this._messageQueue = new();
  27. this._messageQueue.Initialize();
  28. this._receiveQueue = new();
  29. this._receiveQueue.Initialize();
  30. this._dataLogLayer = new();
  31. string filePath = Path.Combine(Environment.CurrentDirectory, "Log", "TlvCommunicatorClient.log");
  32. this._dataLogLayer.Initialize(filePath);
  33. _ = this >> this._contentLayer >> this._receiveQueue >> this._ackLayer >> this._packLayer >> this._messageQueue >> (BaseFilter)this._tcpClient;
  34. //this._dataLogLayer >>
  35. return true;
  36. }
  37. bool ITlvCommunicatorClient.Open(string ipAddress, ushort port)
  38. {
  39. if (this._tcpClient is null)
  40. return false;
  41. this._tcpClient.Initiallize($"TlvCommunicatorClient {ipAddress}:{port}");
  42. return this._tcpClient.Open(ipAddress, port, out _);
  43. }
  44. bool ITlvCommunicatorClient.SendNotify(TlvData tlvData)
  45. {
  46. return base.Send(tlvData);
  47. }
  48. bool ITlvCommunicatorClient.SendRequest(TlvData request, out TlvData reply)
  49. {
  50. reply = null;
  51. SyncMessage syncMessage = new();
  52. lock (_requests)
  53. {
  54. do request.RequestID = this.GetNextID();
  55. while (!this._requests.TryAdd(request.RequestID.Value, syncMessage));
  56. }
  57. Task.Factory.StartNew(() =>
  58. {
  59. if (!base.Send(request))
  60. {
  61. syncMessage.WaitEvent.Set();
  62. this._requests.TryRemove(request.RequestID.Value, out _);
  63. }
  64. });
  65. if (!syncMessage.WaitEvent.WaitOne(this._timeoutTimer))
  66. {
  67. this._requests.TryRemove(request.RequestID.Value, out _);
  68. return false;
  69. }
  70. if (!this._requests.TryRemove(request.RequestID.Value, out _))
  71. return false;
  72. reply = syncMessage.TlvData;
  73. return true;
  74. }
  75. public override bool Receive(Data data)
  76. {
  77. if (data is not TlvData tlv)
  78. return false;
  79. if (tlv.RequestID is null)
  80. {
  81. this._provider?.Received(tlv);
  82. return true;
  83. }
  84. if (!this._requests.TryGetValue(tlv.RequestID.Value, out SyncMessage syncMessage))
  85. return false;
  86. syncMessage.TlvData = tlv;
  87. syncMessage.WaitEvent.Set();
  88. return true;
  89. }
  90. public override bool Send(Data data)
  91. {
  92. return false;
  93. }
  94. public override void Connected(Connection connection)
  95. {
  96. if (connection is not TcpConnection tcpConnection)
  97. return;
  98. this._provider?.Connected(tcpConnection);
  99. }
  100. public override void Disconnected(Connection connection)
  101. {
  102. if (connection is not TcpConnection tcpConnection)
  103. return;
  104. this._provider?.Disconnected(tcpConnection);
  105. }
  106. private ushort GetNextID()
  107. {
  108. if (this._requestID == ushort.MaxValue)
  109. return 0;
  110. return ++_requestID;
  111. }
  112. void IDisposable.Dispose()
  113. {
  114. this._tcpClient?.Close();
  115. this._tcpClient = null;
  116. ((IDisposable)this._messageQueue).Dispose();
  117. this._messageQueue = null;
  118. this._packLayer = null;
  119. this._contentLayer = null;
  120. this._ackLayer = null;
  121. }
  122. }
  123. internal class SyncMessage
  124. {
  125. public TlvData TlvData { get; set; }
  126. public readonly AutoResetEvent WaitEvent = new(false);
  127. }