Files
wcs/WCS.BLL/Manager/TCPClientManager.cs
hehaibing-1996 649e22b4ce 1.WebSocket登录注册
2.数据重发机制
2024-05-17 15:12:07 +08:00

197 lines
8.4 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 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.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>()
.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();
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)
{
Logs.Write("协议处理1");
var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray();
if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度
{
continue;
}
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]);
Logs.Write("协议处理2");
//报警灯
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?.ProtocolProcess(dataTemp, boardId, lightNumber);
}
//!= 0x20 货架类型协议返回
else
{
Logs.Write("协议处理3");
var shelf = ShelfManager.Shelves
.Where(t => t.ClientIp == clientIpHost)
.Where(t => t.ModuleIds.Contains(boardId))
.FirstOrDefault();
var smartShelf = shelf as SmartShelf;
smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber);
}
}
}
Logs.Write("协议处理完毕!");
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);
InitStatus(TcpCleint);
TcpCleint.IsFirstConnected = true;
}
return EasyTask.CompletedTask;
};
TCPClients.Add(tcpCleint);
tcpCleint.Connect();
});
}
//启动线程监听所有TCP是否已经完成首次连接
Task.Run(() =>
{
while (true)
{
Thread.Sleep(1000);
var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false)
.ToList();
if (noFirstConnectedClients.Count == 0)
{
break;
}
else
{
noFirstConnectedClients.ForEach(t =>
{
t.ReConnectAsync();
});
}
}
});
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)
{
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();
}
}
}