Files
wcs/WCS.BLL/Manager/TCPClientManager.cs

218 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;
using WCS.BLL.Config;
using WCS.BLL.HardWare;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
namespace WCS.BLL.Manager
{
public static class TCPClientManager
{
/// <summary>
/// 货架类型的TCP连接管理
/// </summary>
public static List<TCPClient> TCPClients = new List<TCPClient>();
public static void InitTcpClient()
{
Logs.Write("【InitTcpClient】开始", LogsType.StartBoot);
var ips = DbHelp.db.Queryable<ShelfInfo>()
.WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName),t => t.GroupName == LocalFile.Config.GroupName)
.Select(t => t.ClientIp)
.Distinct()
.ToList();
foreach (var ip in ips)
{
Task.Run(() =>
{
var tcpCleint = new TCPClient(ip, "");
tcpCleint.tcpClient.Received += (client, e) =>
{
var clientIpHost = client.IP + ":" + client.Port;
var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost);
if (TcpCleint == null)
{
return EasyTask.CompletedTask;
}
var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray();
Logs.Write($"【接收】{BitConverter.ToString(data)}", LogsType.Instructions);
e.ByteBlock.Clear();
var len = data.Length;
for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++)
{
//协议拆包 通过前缀校验是否为完整数据包
var prefixInData = data.Skip(index).Take(TcpCleint.PreFixLength);
var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix);
if (isEqual)
{
var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray();
if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度
{
continue;
}
Logs.Write($"【处理单条指令 开始】{BitConverter.ToString(dataTemp)}", LogsType.Instructions);
index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1
//获取板子ID
var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1];
var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]);
//报警灯 返回来就修改对应的灯的颜色
if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20)
{
var shelf = ShelfManager.Shelves.Where(t => t.ClientIp == clientIpHost)
.Where(t => t.LightId == boardId)
.FirstOrDefault();
var smartShelf = shelf as SmartShelf;
smartShelf?.WarningLightProcess(dataTemp, boardId, lightNumber);
}
//!= 0x20 货架类型协议返回
else
{
var shelf = ShelfManager.Shelves
.Where(t => t.ClientIp == clientIpHost)
.Where(t => t.ModuleIds != null && t.ModuleIds.Contains(boardId))
.FirstOrDefault();
var smartShelf = shelf as SmartShelf;
smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber);
}
Logs.Write($"【处理单条指令 结束】{BitConverter.ToString(dataTemp)}", LogsType.Instructions);
}
}
return EasyTask.CompletedTask;
};
//配置首次连接后复位操作
tcpCleint.tcpClient.Connected += (client, e) =>
{
var clientIpHost = client.IP + ":" + client.Port;
var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost);
if (TcpCleint == null)
{
return EasyTask.CompletedTask;
}
//首次连接
if (TcpCleint.IsFirstConnected == false)
{
Logs.Write($"【InitTcpClient】{clientIpHost}完成首次连接", LogsType.StartBoot);
Console.WriteLine($"【InitTcpClient】{clientIpHost}完成首次连接");
InitStatus(TcpCleint);
TcpCleint.IsFirstConnected = true;
}
return EasyTask.CompletedTask;
};
TCPClients.Add(tcpCleint);
tcpCleint.Connect();
});
}
//启动线程监听所有TCP是否已经完成首次连接
Task.Run(() =>
{
while (true)
{
try
{
Thread.Sleep(1000);
var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false)
.ToList();
if (noFirstConnectedClients.Count == 0)
{
break;
}
else
{
Console.WriteLine($"存在tcp未完成首次连接继续重连");
noFirstConnectedClients.ForEach(t =>
{
t.ReConnectAsync();
});
}
}
catch (Exception ex)
{
}
}
});
Logs.Write("【InitTcpClient】完成 后台继续连接", LogsType.StartBoot);
}
//后台启动时给所有板子、警示灯发送复位操作 保持状态一致
public static void InitStatus()
{
Task.Run(() =>
{
try
{
Thread.Sleep(1000);
//给所有板子发复位
TCPClients.ForEach(tcpClient =>
{
//板子复位
new SmartShelfModule()
{
BoardId = 2047
}.Reset(tcpClient);
//报警灯复位
new WarningLight().CloseLight(tcpClient);
});
}
catch (Exception ex)
{
Logs.Write($"启动时复位异常,{ex.Message}");
}
});
}
//后台启动时给所有板子、警示灯发送复位操作 保持状态一致
public static void InitStatus(TCPClient tcpClient)
{
List<ModuleInfo> MI = DbHelp.db.Queryable<ModuleInfo>().Where(it => it.CleintIp == tcpClient.RemoteIPHost).ToList();
if (MI.Count != 0)
{
List<ShelfInfo> SI = DbHelp.db.Queryable<ShelfInfo>().Where(it => it.ShelfCode == MI[0].ShelfCode).ToList();
if (SI.Count != 0)
{
if (SI[0].ShelfTypeName == "信息化货架")
{
return;
}
}
}
Task.Run(() =>
{
try
{
Thread.Sleep(1000);
//板子复位
new SmartShelfModule()
{
BoardId = 2047
}.Reset(tcpClient);
//报警灯复位
new WarningLight().CloseLight(tcpClient);
}
catch (Exception ex)
{
Logs.Write($"[{tcpClient.RemoteIPHost}]:启动时复位异常,{ex.Message}");
}
});
}
public static TCPClient GetTCPClientByIPHost(string IpHost)
{
return TCPClients.Where(t => t.RemoteIPHost == IpHost).FirstOrDefault();
}
}
}