TcpProtocol.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using System.Web.UI.WebControls.WebParts;
  9. using TeamAAS_VP.Enums;
  10. using TeamAAS_VP.Models.Robot;
  11. using TouchSocket.Core;
  12. using TouchSocket.Sockets;
  13. namespace TeamAAS_VP.Core.Lights
  14. {
  15. public class TcpProtocol : ICommunicationProtocol
  16. {
  17. private readonly string _host;
  18. private readonly int _port;
  19. private TcpClient _client;
  20. public bool IsConnected => _client?.Online == true;
  21. public IWaitingClient<ITcpClient, IReceiverResult> _waitClient { get; private set; }
  22. public Terminator Terminator { get; set; } = Terminator.None;
  23. public Encoding Encoding { get; set; } = Encoding.ASCII;
  24. public event Action<object, bool> ConnectionChanged;
  25. public event Action<object, string> DataReceived;
  26. public event Action<object, string> DataSent;
  27. public TcpProtocol(string host, int port, Terminator terminator = Terminator.None)
  28. {
  29. _host = host;
  30. _port = port;
  31. Terminator = terminator;
  32. }
  33. public async Task<bool> ConnectAsync()
  34. {
  35. try
  36. {
  37. _client = new TouchSocket.Sockets.TcpClient();
  38. var config = new TouchSocketConfig();
  39. config.SetRemoteIPHost(new IPHost(IPAddress.Parse(_host), _port));
  40. config.ConfigurePlugins(a => { a.UseTcpReconnection(); }); ////如需永远尝试连接,tryCount设置为-1即可。
  41. ////设置结束符
  42. if (Terminator == Terminator.None)
  43. {
  44. config.SetTcpDataHandlingAdapter(() => { return new NormalDataHandlingAdapter(); }); ////亦或者省略\r\n,但此时调用方不能高速调用,会粘包
  45. }
  46. else if (Terminator == Terminator.CR)
  47. {
  48. config.SetTcpDataHandlingAdapter(() => { return new TerminatorPackageAdapter("\r"); }); //命令行中使用\r结尾
  49. }
  50. else if (Terminator == Terminator.LF)
  51. {
  52. config.SetTcpDataHandlingAdapter(() => { return new TerminatorPackageAdapter("\n"); }); //命令行中使用\n结尾
  53. }
  54. else if (Terminator == Terminator.CRLF)
  55. {
  56. config.SetTcpDataHandlingAdapter(() => { return new TerminatorPackageAdapter("\r\n"); }); //命令行中使用\r\n结尾
  57. }
  58. //载入配置
  59. _client.Setup(config);
  60. ////调用CreateWaitingClient获取到IWaitingClient的对象。
  61. _waitClient = _client.CreateWaitingClient(new WaitingOptions()
  62. {
  63. FilterFunc = response => //设置用于筛选的fun委托,当返回为true时,才会响应返回
  64. {
  65. return true;
  66. //if (response.Data.Length == 1)
  67. //{
  68. // return true;
  69. //}
  70. //return false;
  71. }
  72. });
  73. var result = await _client.TryConnectAsync();
  74. if (result.IsSuccess)
  75. {
  76. ConnectionChanged?.Invoke(this, true);
  77. return true;
  78. }
  79. ConnectionChanged?.Invoke(this, false);
  80. return false;
  81. }
  82. catch
  83. {
  84. return false;
  85. }
  86. }
  87. public Task DisconnectAsync()
  88. {
  89. ConnectionChanged?.Invoke(this, false);
  90. _client?.Close();
  91. return Task.CompletedTask;
  92. }
  93. public async Task<byte[]> SendAndReceiveAsync(byte[] data, int timeout = 5000)
  94. {
  95. if (_waitClient == null)
  96. throw new InvalidOperationException("Not connected");
  97. DataSent?.Invoke(this, Encoding.GetString(data));
  98. var response = await _waitClient.SendThenReturnAsync(data, timeout);
  99. DataReceived?.Invoke(this, Encoding.GetString(response));
  100. return response;
  101. }
  102. public Task SendAsync(byte[] data)
  103. {
  104. if (_client == null)
  105. throw new InvalidOperationException("Not connected");
  106. DataSent?.Invoke(this, Encoding.GetString(data));
  107. _client.Send(data);
  108. return Task.CompletedTask;
  109. }
  110. public async Task<string> SendAndReceiveAsync(string data, int timeout = 5000)
  111. {
  112. if (_waitClient == null)
  113. throw new InvalidOperationException("Not connected");
  114. DataSent?.Invoke(this, data);
  115. var response = await SendAndReceiveAsync(Encoding.GetBytes(data), timeout);
  116. DataReceived?.Invoke(this, Encoding.GetString(response));
  117. return Encoding.GetString(response);
  118. }
  119. public string SendAndReceive(string data, int timeout = 5000)
  120. {
  121. if (_waitClient == null)
  122. throw new InvalidOperationException("Not connected");
  123. DataSent?.Invoke(this, data);
  124. var response = _waitClient.SendThenReturn(Encoding.GetBytes(data), timeout);
  125. DataReceived?.Invoke(this, Encoding.GetString(response));
  126. return Encoding.GetString(response);
  127. }
  128. public byte[] SendAndReceive(byte[] data, int timeout = 5000)
  129. {
  130. if (_waitClient == null)
  131. throw new InvalidOperationException("Not connected");
  132. DataSent?.Invoke(this, Encoding.GetString(data));
  133. var response = _waitClient.SendThenReturn(data, timeout);
  134. DataReceived?.Invoke(this, Encoding.GetString(response));
  135. return response;
  136. }
  137. public void Send(string data)
  138. {
  139. if (_client == null)
  140. throw new InvalidOperationException("Not connected");
  141. DataSent?.Invoke(this, data);
  142. _client.Send(Encoding.GetBytes(data));
  143. }
  144. public async Task SendAsync(string data)
  145. {
  146. if (_client == null)
  147. throw new InvalidOperationException("Not connected");
  148. DataSent?.Invoke(this, data);
  149. await _client.SendAsync(Encoding.GetBytes(data));
  150. }
  151. public void Send(byte[] data)
  152. {
  153. if (_client == null)
  154. throw new InvalidOperationException("Not connected");
  155. DataSent?.Invoke(this, Encoding.GetString(data));
  156. _client.Send(data);
  157. }
  158. public void Dispose()
  159. {
  160. _client?.Dispose();
  161. }
  162. }
  163. }