wcs_server_s7_baoying/WcsMain/Tcp/Client/PlcTcpClient.cs

102 lines
3.8 KiB
C#
Raw Normal View History

2024-06-20 09:23:01 +08:00
using System.Diagnostics;
using System.Text.RegularExpressions;
using WcsMain.Tcp.Entity;
using WcsMain.Tcp.Entity.Message;
using WcsMain.WcsAttribute.AutoFacAttribute;
namespace WcsMain.Tcp.Client;
/// <summary>
/// 专用与连接 PLC 的Tcp客户端
/// </summary>
public class PlcTcpClient : BaseTcpClient
{
/// <summary>
/// 存储收到的消息
/// </summary>
private Dictionary<string, MsgInfo> msgInfos = [];
/// <summary>
/// 重写检测离线方法 ---- 上一次传输数据的时间和当前时间差 3 秒判断断开
/// </summary>
public async override void MonitorServeConnectedAsync()
{
if (tcpServeConnectionDatas.Count < 1) return;
CancellationTokenSource cts = new();
PeriodicTimer timer = new(new TimeSpan(0, 0, 0, 1, 0));
while (await timer.WaitForNextTickAsync(cts.Token))
{
foreach (var tcpServe in tcpServeConnectionDatas)
{
if (tcpServe.IsConnected == Enum.General.TrueFalseEnum.FALSE || tcpServe.IsConnected == default) continue;
// 计算上一次接收消息的时间和当前的时间差,超过三秒判断断开
var lastRevMsgTime = tcpServe.RecvMsgTime;
var timespan = DateTime.Now - lastRevMsgTime;
var timespanSeconds = timespan.TotalSeconds;
if (timespanSeconds > 3) // 心跳超时时间
{
tcpServe.TcpClient?.Close();
tcpServe.IsConnected = Enum.General.TrueFalseEnum.FALSE;
continue;
}
}
}
}
/// <summary>
/// 发送信息到指定别称的客户端
/// </summary>
/// <param name="value"></param>
/// <param name="displayName"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public PlcTcpClientSendResult SendWithResult(string? value, string? displayName, int timeout)
{
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(displayName))
{
return new() { Success = false, Exception = new Exception("传入的参数为空") };
}
MsgHeader? header = GetMsgHeader(value);
if(header == default || string.IsNullOrEmpty(header.MsgId)) return new() { Success = false, Exception = new Exception("发送的信息不是标准报文格式") };
Stopwatch stopwatch = Stopwatch.StartNew();
var sendResult = Send(value, displayName); // 发送消息
if(!sendResult.Success) return new() { Success = sendResult.Success, Exception = sendResult.Exception }; // 发送失败
MsgInfo? msgInfo = default;
while (stopwatch.ElapsedMilliseconds < timeout)
{
bool exist = msgInfos.TryGetValue(header.MsgId, out msgInfo);
if (exist) break;
}
if(msgInfo == default) return new() { Success = false, Exception = new Exception("发送的信息不是标准报文格式"), UseTime = stopwatch.ElapsedMilliseconds};
return new()
{
Success = true,
ResponseData = msgInfo,
UseTime = stopwatch.ElapsedMilliseconds
};
}
/// <summary>
/// 获取msg的Header
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public MsgHeader? GetMsgHeader(string? value)
{
if (string.IsNullOrEmpty(value)) return default;
if (!Regex.IsMatch(value, "^<.+\\>$")) return default;
string[] msgDatas = value.Split(';');
if(msgDatas.Length < 4 ) return default;
var msgHeader = new MsgHeader()
{
MsgType = msgDatas[0].Replace("<", ""),
ClientId = msgDatas[1],
MsgId = msgDatas[2],
MsgTag = msgDatas[3],
};
return msgHeader;
}
}