using DefaultEdit.Enums;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.SerialPorts;
using TouchSocket.Sockets;
namespace DefaultEdit.Communication
{
public class SerialCommunication : IDisposable
{
///
/// 串口名称
///
public string PortName { get; private set; }
///
/// 波特率
///
public int BaudRate { get; private set; }
///
/// 奇偶校验位
///
public Parity Parity { get; private set; }
///
/// 停止位
///
public StopBits StopBits { get; private set; }
///
/// 数据位
///
public int DataBits { get; private set; }
public Encoding Encoding { get; set; } = Encoding.ASCII;
///
/// 当前连接状态
///
public bool IsConnected
{
get
{
if ( client != null )
{
return client.Online;
}
else
{
return false;
}
}
}
private SerialPortClient client;
private IWaitingClient WaitClient;
///
/// 接收到的数据
///
public string Data { get; private set; }
///
/// 连接状态变化事件
///
public event Action ConnectionChanged;
///
/// 数据接收事件
///
public event Action DataReceived;
///
/// 发送数据事件
///
public event Action SendData;
public Terminator terminator;
public SerialCommunication(Terminator terminator, string portName, int baudRate = 9600, Parity parity = Parity.None, StopBits stopBits = StopBits.One, int dataBits = 8)
{
PortName = portName;
BaudRate = baudRate;
Parity = parity;
StopBits = stopBits;
DataBits = dataBits;
client = new SerialPortClient();
client.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到端口
client.Connected = (client, e) =>
{
ConnectionChanged?.Invoke(this, IsConnected);
return EasyTask.CompletedTask;
};//成功连接到端口
client.Closing = (client, e) => { return EasyTask.CompletedTask; };//即将从端口断开连接。此处仅主动断开才有效。
client.Closed = (client, e) =>
{
ConnectionChanged?.Invoke(this, IsConnected);
return EasyTask.CompletedTask;
};//从端口断开连接,当连接不成功时不会触发。
client.Received = async (c, e) =>
{
Data = e.ByteBlock.Span.ToString(Encoding); //接收到数据
DataReceived?.Invoke(this, Data);
};
TouchSocketConfig touchSocket = new TouchSocketConfig();
touchSocket.SetSerialPortOption(new SerialPortOption()
{
BaudRate = BaudRate,//波特率
DataBits = DataBits,//数据位
Parity = Parity,//校验位
PortName = PortName,//COM
StopBits = StopBits//停止位
});
if ( terminator == Terminator.None )
{
touchSocket.SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromSeconds(0.8) });
}
if ( terminator == Terminator.CRLF )
{
touchSocket.SetSerialDataHandlingAdapter(() => new TerminatorPackageAdapter("\r\n"));
}
client.Setup(touchSocket);
}
///
/// 异步连接到串口扫描枪
///
///
public async Task ConnectAsync()
{
if ( ( await client.TryConnectAsync() ).IsSuccess )
{
ConnectionChanged?.Invoke(this, IsConnected);
//调用CreateWaitingClient获取到IWaitingClient的对象。
WaitClient = client.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response => //设置用于筛选的fun委托,当返回为true时,才会响应返回
{
return true;
}
});
return true;
}
return false;
}
///
/// 连接到串口扫描枪
///
///
public bool Connect()
{
if ( client.TryConnect().IsSuccess )//尝试连接到端口
{
//调用CreateWaitingClient获取到IWaitingClient的对象。
WaitClient = client.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response => //设置用于筛选的fun委托,当返回为true时,才会响应返回
{
return true;
}
});
return true;
}
return false;
}
///
/// 断开连接到串口扫描枪
///
public void Disconnect()
{
if ( IsConnected )
{
client.Close();
ConnectionChanged?.Invoke(this, IsConnected);
}
}
///
/// 发送数据到串口扫描枪,并等待返回数据。
///
///
///
///
public string SendThenReturn(string msg, int millisecondsTimeout = 5000)
{
//然后使用SendThenReturn。
SendData?.Invoke(this, msg);
byte[] returnData = WaitClient.SendThenReturn(Encoding.GetBytes(msg), millisecondsTimeout);
DataReceived?.Invoke(this, Encoding.GetString(returnData));
return Encoding.GetString(returnData);
}
///
/// 异步发送数据到串口扫描枪,并等待返回数据。
///
///
///
///
public async Task SendThenReturnAsync(string msg, int millisecondsTimeout = 5000)
{
SendData?.Invoke(this, msg);
byte[] returnData = await WaitClient.SendThenReturnAsync(Encoding.GetBytes(msg), millisecondsTimeout);
DataReceived?.Invoke(this, Encoding.GetString(returnData));
return Encoding.GetString(returnData);
}
///
/// 发送数据到串口扫描枪
///
///
public void Send(string msg)
{
if ( IsConnected )
{
SendData?.Invoke(this, msg);
client.Send(Encoding.GetBytes(msg)); //发送数据到串口扫描枪
}
}
public void Dispose()
{
if ( WaitClient != null )
{
WaitClient = null;
}
if ( client != null )
{
client.Dispose();
client = null;
}
}
}
}