using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web.UI.WebControls.WebParts; using TeamAAS_VP.Enums; using TeamAAS_VP.Models.Robot; using TouchSocket.Core; using TouchSocket.Sockets; namespace TeamAAS_VP.Core.Lights { public class TcpProtocol : ICommunicationProtocol { private readonly string _host; private readonly int _port; private TcpClient _client; public bool IsConnected => _client?.Online == true; public IWaitingClient _waitClient { get; private set; } public Terminator Terminator { get; set; } = Terminator.None; public Encoding Encoding { get; set; } = Encoding.ASCII; public event Action ConnectionChanged; public event Action DataReceived; public event Action DataSent; public TcpProtocol(string host, int port, Terminator terminator = Terminator.None) { _host = host; _port = port; Terminator = terminator; } public async Task ConnectAsync() { try { _client = new TouchSocket.Sockets.TcpClient(); var config = new TouchSocketConfig(); config.SetRemoteIPHost(new IPHost(IPAddress.Parse(_host), _port)); config.ConfigurePlugins(a => { a.UseTcpReconnection(); }); ////如需永远尝试连接,tryCount设置为-1即可。 ////设置结束符 if (Terminator == Terminator.None) { config.SetTcpDataHandlingAdapter(() => { return new NormalDataHandlingAdapter(); }); ////亦或者省略\r\n,但此时调用方不能高速调用,会粘包 } else if (Terminator == Terminator.CR) { config.SetTcpDataHandlingAdapter(() => { return new TerminatorPackageAdapter("\r"); }); //命令行中使用\r结尾 } else if (Terminator == Terminator.LF) { config.SetTcpDataHandlingAdapter(() => { return new TerminatorPackageAdapter("\n"); }); //命令行中使用\n结尾 } else if (Terminator == Terminator.CRLF) { config.SetTcpDataHandlingAdapter(() => { return new TerminatorPackageAdapter("\r\n"); }); //命令行中使用\r\n结尾 } //载入配置 _client.Setup(config); ////调用CreateWaitingClient获取到IWaitingClient的对象。 _waitClient = _client.CreateWaitingClient(new WaitingOptions() { FilterFunc = response => //设置用于筛选的fun委托,当返回为true时,才会响应返回 { return true; //if (response.Data.Length == 1) //{ // return true; //} //return false; } }); var result = await _client.TryConnectAsync(); if (result.IsSuccess) { ConnectionChanged?.Invoke(this, true); return true; } ConnectionChanged?.Invoke(this, false); return false; } catch { return false; } } public Task DisconnectAsync() { ConnectionChanged?.Invoke(this, false); _client?.Close(); return Task.CompletedTask; } public async Task SendAndReceiveAsync(byte[] data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); var response = await _waitClient.SendThenReturnAsync(data, timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return response; } public Task SendAsync(byte[] data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); _client.Send(data); return Task.CompletedTask; } public async Task SendAndReceiveAsync(string data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); var response = await SendAndReceiveAsync(Encoding.GetBytes(data), timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return Encoding.GetString(response); } public string SendAndReceive(string data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); var response = _waitClient.SendThenReturn(Encoding.GetBytes(data), timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return Encoding.GetString(response); } public byte[] SendAndReceive(byte[] data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); var response = _waitClient.SendThenReturn(data, timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return response; } public void Send(string data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); _client.Send(Encoding.GetBytes(data)); } public async Task SendAsync(string data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); await _client.SendAsync(Encoding.GetBytes(data)); } public void Send(byte[] data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); _client.Send(data); } public void Dispose() { _client?.Dispose(); } } }