using HighWayIot.Log4net; using HighWayIot.Plc.PlcHelper; using HighWayIot.Repository.domain; using HighWayIot.Repository.service; using HighWayIot.Rfid; using HighWayIot.Rfid.Entity; using HighWayIot.TouchSocket; using HighWayIot.Winform.Properties; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace HighWayIot.Winform.Business { /// /// TCP数据工厂类 /// public class TCPClientFactory { /// /// 标签服务类 /// private ZxTagSettingService _tagrService = ZxTagSettingService.Instance; /// /// 标签实体类 /// private List _tagSetting; /// /// 读写器服务类 /// private ZxReaderSettingService _readerService = ZxReaderSettingService.Instance; /// /// 读写器实体类 /// private List _readerSetting; /// /// RFID数据分析 /// private RfidDataAnalyse _RfidDataAnalyse = new RfidDataAnalyse(); /// /// PLC /// private WorkStationHelper _workStationHelper = new WorkStationHelper(); /// /// TCP客户端 /// private TouchSocketTcpClient _touchSocketTcpClient = TouchSocketTcpClient.Instance; /// /// 心跳检测 /// private Dictionary _heartBeatRecord = new Dictionary(); /// /// Timer /// private Timer _heartbeatTimer; public TCPClientFactory() { _tagSetting = _tagrService.GetTagInfos(); _readerSetting = _readerService.GetReaderInfos(); _heartbeatTimer = new Timer(new TimerCallback(HeartbeatJudge), null, 0, 10000); } /// /// 对接收到的数据进行初步解析分发到各个报文类型的解析类中 /// public void ReciveDataRoute(byte[] bytes, string ip) { BaseReciveDataEntity reciveData = BaseRFIDDataAnalyse.BaseReceiveAnalyse(bytes); if(reciveData == null) { return; } switch (reciveData.Code) { case 0x02: //盘点结果 Receive02HEntity data02Hentity = _RfidDataAnalyse.Receive02H(reciveData.Data); if (data02Hentity == null || data02Hentity.Data == null) { return; } ReciveRFIDSingal(data02Hentity, ip); ReciveHeartBeatSignal(ip); break; case 0xBF: //心跳信号 ReciveHeartBeatSignal(ip); break; default: LogHelper.Instance.Error($"接收到未知报文,识别代码[{reciveData.Code.ToString("X2")}]"); return; } } /// /// 接收信息的信号 /// /// public void ReciveRFIDSingal(Receive02HEntity entity, string ip) { //找到读取次数最大的标签EPC byte[] epcData = entity.Data.Where(x => x.Count == entity.Data.Max(y => y.Count)).First().EPC; //标签号byte数组转换成字符串 string epcResult = string.Join(" ", epcData.Select(x => x.ToString("X2"))); //根据IP和标签EPC获取工位和对应设备号 string deviceNo = _tagSetting.Where(x => x.RfidEpc == epcResult).FirstOrDefault().DeviceNo; string workstationNo = _readerSetting.Where(x => x.RfidIp == ip).FirstOrDefault().WorkstationNo; if (string.IsNullOrEmpty(deviceNo)) { LogHelper.Instance.Error($"未查询到 [{epcResult}] 标签相关的信息!"); return; } if (string.IsNullOrEmpty(workstationNo)) { LogHelper.Instance.Error($"未查询到 [{ip}] 读写器相关的信息!"); return; } try { ///写入对应的PLC信号 _workStationHelper.WriteStationSingal(int.Parse(workstationNo), int.Parse(deviceNo)); LogHelper.Instance.RfidLog($"{workstationNo}工位, {deviceNo}号车"); } catch (Exception ex) { LogHelper.Instance.Error("数值转换发生错误", ex); } } /// /// 心跳信号接收 /// public void ReciveHeartBeatSignal(string ip) { //if(entity.Status != 0x00) //{ // string workstationNo = _readerService.GetWorkstateNoByIp(ip); // LogHelper.Instance.Error($"读写器编号[{workstationNo}]心跳返回异常,异常代码[{entity.Status.ToString("X2")}],系统时间[{entity.Systick}]"); //} //初次心跳处理 if (!_heartBeatRecord.ContainsKey(ip)) { LogHelper.Instance.RfidLog($"[{ip}] 初次心跳"); _heartBeatRecord.Add(ip, DateTime.Now); return; } else //不是初次就更新 { _heartBeatRecord[ip] = DateTime.Now; } //心跳异常处理 } public void HeartbeatJudge(object o) { foreach (var kvp in _heartBeatRecord.ToArray()) { DateTime lastTime = kvp.Value; TimeSpan timeSpan = DateTime.Now - lastTime; if (timeSpan > TimeSpan.FromSeconds(16)) { LogHelper.Instance.RfidLog($"[{kvp.Key}] 可能掉线,准备重连"); _heartBeatRecord.Remove(kvp.Key); _touchSocketTcpClient.DisposeClient(kvp.Key).GetAwaiter().GetResult(); _touchSocketTcpClient.CreateTcpClient(kvp.Key, "20108"); _touchSocketTcpClient.Send(kvp.Key, _RfidDataAnalyse.SendBFH(5)).GetAwaiter().GetResult(); } } } } }