diff --git a/WCS.BLL/DbModels/ShelfInfo.cs b/WCS.BLL/DbModels/ShelfInfo.cs
index 9753562..28e4dee 100644
--- a/WCS.BLL/DbModels/ShelfInfo.cs
+++ b/WCS.BLL/DbModels/ShelfInfo.cs
@@ -90,13 +90,18 @@ namespace WCS.DAL.DbModels
[SugarColumn(ColumnName = "group_name", Length = 50, IsNullable = false, ColumnDescription = "货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架)")]
public string GroupName { get; set; }
-
///
- /// 是否串联绑定
+ /// 模块是不是
///
[SugarColumn(ColumnName = "is_bind", IsNullable = false, ColumnDescription = "是否串联绑定")]
public bool IsBind { get; set; }
+ ///
+ /// 货架的模块是不是服务端
+ ///
+ [SugarColumn(ColumnName = "is_service", IsNullable = true, ColumnDescription = "货架的模块是不是服务端")]
+ public bool IsService { get; set; } = false;
+
///
/// 串联绑定后的大货架编码
///
diff --git a/WCS.BLL/Manager/DbInit.cs b/WCS.BLL/Manager/DbInit.cs
index 065e18b..906dd51 100644
--- a/WCS.BLL/Manager/DbInit.cs
+++ b/WCS.BLL/Manager/DbInit.cs
@@ -78,6 +78,8 @@ namespace WCS.BLL.Manager
, typeof(AppVersion)
);
+ //DbHelp.db.CodeFirst.InitTables(typeof(ShelfInfo));
+
Logs.Write("【初始化数据库】db(业务数据库)建表", LogsType.StartBoot);
DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord));
Logs.Write("【初始化数据库】dblog(日志数据库)建表", LogsType.StartBoot);
diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs
index 8a6a228..1a3a39f 100644
--- a/WCS.BLL/Manager/TCPClientManager.cs
+++ b/WCS.BLL/Manager/TCPClientManager.cs
@@ -23,12 +23,15 @@ namespace WCS.BLL.Manager
///
public static List TCPClients = new List();
+ public static TcpService Service { get; set; }
+
public static void InitTcpClient()
{
+ #region 模块是Service的逻辑
Logs.Write("【InitTcpClient】开始", LogsType.StartBoot);
-
- var clientsInDB = DbHelp.db.Queryable()
+ var moduleServices = DbHelp.db.Queryable()
.WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName)
+ .Where(t => t.IsService)
.Select(t => new
{
IP = t.ClientIp,
@@ -37,154 +40,208 @@ namespace WCS.BLL.Manager
})
.Distinct()
.ToList();
- Logs.Write($"【InitTcpClient】需要连接的服务端地址如下:\r\n{string.Join(";", clientsInDB)}", LogsType.StartBoot);
- foreach (var cleientInDB in clientsInDB)
+ if (moduleServices != null && moduleServices.Count > 0)
{
+ Logs.Write($"【InitTcpClient】需要连接的服务端地址如下:\r\n{string.Join(";", moduleServices)}", LogsType.StartBoot);
+ foreach (var cleientInDB in moduleServices)
+ {
+ Task.Run(() =>
+ {
+ var tcpCleint = new TCPClient(cleientInDB.IP, cleientInDB.Port, cleientInDB.ShelfTypeName);
+ 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($"【接收{clientIpHost}】{BitConverter.ToString(data)}", LogsType.Instructions);
+
+ e.ByteBlock.Clear();
+ var len = data.Length;
+
+ if (tcpCleint.ShelfTypeName == "信息化货架")
+ {
+ Logs.Write($"【信息化货架开始处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
+ Helper.ReturnDataProcess(TcpCleint, data);
+ Logs.Write($"【信息化货架完成处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
+ return EasyTask.CompletedTask;
+ }
+
+ if (tcpCleint.ShelfTypeName == "液晶货架")
+ {
+ Logs.Write($"【液晶货架开始处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
+ //Helper.ReturnDataProcess(TcpCleint, data);
+ Logs.Write($"【液晶货架完成处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
+ return EasyTask.CompletedTask;
+ }
+
+ 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.InstructionsProcess);
+ 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.InstructionsProcess);
+ }
+ }
+ return EasyTask.CompletedTask;
+ };
+ //配置首次连接后复位操作
+ tcpCleint.tcpClient.Connected += (client, e) =>
+ {
+ Logs.Write($"【TcpClient】{client.IP}完成连接,端口号{client.Port}", LogsType.StartBoot);
+ 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;
+ //获取剩余未完成连接的tcp
+ var noFirstConnectedTcps = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false)
+ .Select(t => t.RemoteIPHost)
+ .ToList();
+ Logs.Write($"【InitTcpClient】剩余未完成连接的TCP为{string.Join(";", noFirstConnectedTcps)}", LogsType.StartBoot);
+ }
+ return EasyTask.CompletedTask;
+ };
+
+ lock (TCPClients)//避免添加失败的情况
+ {
+ TCPClients.Add(tcpCleint);
+ }
+
+ tcpCleint.Connect();
+ });
+ }
+
+ //启动线程监听所有TCP是否已经完成首次连接
Task.Run(() =>
{
- var tcpCleint = new TCPClient(cleientInDB.IP, cleientInDB.Port, cleientInDB.ShelfTypeName);
- tcpCleint.tcpClient.Received += (client, e) =>
+ while (true)
{
- var clientIpHost = client.IP + ":" + client.Port;
- var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost);
- if (TcpCleint == null)
+ try
{
- return EasyTask.CompletedTask;
- }
-
- var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray();
-
-
- Logs.Write($"【接收{clientIpHost}】{BitConverter.ToString(data)}", LogsType.Instructions);
-
- e.ByteBlock.Clear();
- var len = data.Length;
-
- if (tcpCleint.ShelfTypeName == "信息化货架")
- {
- Logs.Write($"【信息化货架开始处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
- Helper.ReturnDataProcess(TcpCleint, data);
- Logs.Write($"【信息化货架完成处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
- return EasyTask.CompletedTask;
- }
-
- if (tcpCleint.ShelfTypeName == "液晶货架")
- {
- Logs.Write($"【液晶货架开始处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
- //Helper.ReturnDataProcess(TcpCleint, data);
- Logs.Write($"【液晶货架完成处理接收数据】{BitConverter.ToString(data)}", LogsType.InstructionsProcess);
- return EasyTask.CompletedTask;
- }
-
- 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)
+ Thread.Sleep(1000);
+ var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false)
+ .ToList();
+ if (noFirstConnectedClients.Count == 0)
{
- var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray();
- if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度
+ break;
+ }
+ else
+ {
+ Console.WriteLine($"存在tcp未完成首次连接,继续重连!");
+ noFirstConnectedClients.ForEach(t =>
{
- continue;
- }
- Logs.Write($"【处理单条指令 开始】{BitConverter.ToString(dataTemp)}", LogsType.InstructionsProcess);
- 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.InstructionsProcess);
+ t.ReConnectAsync();
+ });
}
}
- return EasyTask.CompletedTask;
- };
- //配置首次连接后复位操作
- tcpCleint.tcpClient.Connected += (client, e) =>
- {
- Logs.Write($"【TcpClient】{client.IP}完成连接,端口号{client.Port}", LogsType.StartBoot);
- var clientIpHost = client.IP + ":" + client.Port;
- var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost);
- if (TcpCleint == null)
+ catch (Exception ex)
{
- return EasyTask.CompletedTask;
+
}
- //首次连接
- if (TcpCleint.IsFirstConnected == false)
- {
- Logs.Write($"【InitTcpClient】{clientIpHost}完成首次连接", LogsType.StartBoot);
-
-
-
- Console.WriteLine($"【InitTcpClient】{clientIpHost}完成首次连接");
- InitStatus(TcpCleint);
- TcpCleint.IsFirstConnected = true;
- //获取剩余未完成连接的tcp
- var noFirstConnectedTcps = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false)
- .Select(t => t.RemoteIPHost)
- .ToList();
- Logs.Write($"【InitTcpClient】剩余未完成连接的TCP为{string.Join(";", noFirstConnectedTcps)}", LogsType.StartBoot);
- }
- return EasyTask.CompletedTask;
- };
-
- lock (TCPClients)//避免添加失败的情况
- {
- TCPClients.Add(tcpCleint);
}
-
- tcpCleint.Connect();
});
+ Logs.Write("【InitTcpClient】完成 后台继续连接", LogsType.StartBoot);
}
+ #endregion
- //启动线程监听所有TCP是否已经完成首次连接
- Task.Run(() =>
+ #region 模块是Client的逻辑
+ var moduleClients = DbHelp.db.Queryable()
+ .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName)
+ .Where(t => t.IsService == false)
+ .Select(t => new
+ {
+ IP = t.ClientIp,
+ ShelfTypeName = t.ShelfTypeName,
+ Port = t.Port,
+ })
+ .Distinct()
+ .ToList();
+ //有客户端作客户端时才需要初始化一个服务端
+ if (moduleClients != null && moduleClients.Count > 0)
{
- while (true)
+ Service = new TcpService();
+ Service.Connecting = (client, e) =>
{
- 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)
- {
+ return EasyTask.CompletedTask;
+ };//有客户端正在连接
+ Service.Connected = (client, e) => { return EasyTask.CompletedTask; };//有客户端成功连接
+ Service.Disconnecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在断开连接,只有当主动断开时才有效。
+ Service.Disconnected = (client, e) => { return EasyTask.CompletedTask; };//有客户端断开连接
+ Service.Received = (client, e) =>
+ {
+ //从客户端收到信息
+ var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意:数据长度是byteBlock.Len
+ client.Logger.Info($"已从{client.Id}接收到信息:{mes}");
- }
- }
- });
- Logs.Write("【InitTcpClient】完成 后台继续连接", LogsType.StartBoot);
+ //client.Send(mes);//将收到的信息直接返回给发送方
+
+
+ return EasyTask.CompletedTask;
+ };
+
+ Service.Setup(new TouchSocketConfig()//载入配置
+ .SetListenIPHosts("tcp://0.0.0.0:9999", 7790)//同时监听两个地址
+ .ConfigureContainer(a =>//容器的配置顺序应该在最前面
+ {
+ a.AddConsoleLogger();//添加一个控制台日志注入(注意:在maui中控制台日志不可用)
+ })
+ .ConfigurePlugins(a =>
+ {
+ //a.Add();//此处可以添加插件
+ }));
+
+ Service.Start();
+ }
+ #endregion
}
//后台启动时给所有板子、警示灯发送复位操作 保持状态一致
diff --git a/WCS.BLL/Services/Service/SingleLightService.cs b/WCS.BLL/Services/Service/SingleLightService.cs
index 415d166..9b6d7f0 100644
--- a/WCS.BLL/Services/Service/SingleLightService.cs
+++ b/WCS.BLL/Services/Service/SingleLightService.cs
@@ -75,7 +75,7 @@ namespace WCS.BLL.Services.Service
{
var shelfModel = new SingleLightShelfModel();
//报警灯
- if(shelf.LightId > 0)
+ if (shelf.LightId > 0)
{
shelfModel.WarningLightMode = request.LightMode;
}
@@ -96,29 +96,62 @@ namespace WCS.BLL.Services.Service
}
//合并:同一个TCP的货架合并 报警灯和库位灯统一只发送一条指令
- var clientIpList = shelfs.Select(t => t.ClientIp)
- .Distinct()
- .ToList();
- foreach (var clientIp in clientIpList)
+ var clients = shelfs.Select(t => new
{
- var shelfModelsInOneIp = shelfModels.Where(t => t.ClientIp == clientIp).ToList();
+ ClientIp = t.ClientIp,
+ IsService = t.IsService,
+ })
+ .Distinct()
+ .ToList();
+ foreach (var client in clients)
+ {
+ var shelfModelsInOneIp = shelfModels.Where(t => t.ClientIp == client.ClientIp).ToList();
+
var sendData = Helper.SingleLightControl(shelfModelsInOneIp);
- TCPClient tcpClient = TCPClientManager.GetTCPClientByIPHost(clientIp);
- if (tcpClient != null)
+ if (client.IsService)
{
- try
+ TCPClient tcpClient = TCPClientManager.GetTCPClientByIPHost(client.ClientIp);
+ if (tcpClient != null)
{
- tcpClient.Send(sendData);
- Logs.Write("【单灯单独控制】发送指令" + BitConverter.ToString(sendData));
+ try
+ {
+ tcpClient.Send(sendData);
+ Logs.Write("【单灯单独控制】发送指令" + BitConverter.ToString(sendData));
+ }
+ catch (Exception ex)
+ {
+ Logs.Write($"【单灯单独控制】{client}以下指令发送中遇到异常{ex.Message}" + BitConverter.ToString(sendData));
+ }
}
- catch (Exception ex)
+ else
{
- Logs.Write($"【单灯单独控制】{clientIp}以下指令发送中遇到异常{ex.Message}" + BitConverter.ToString(sendData));
+ Logs.Write($"【单灯单独控制】{client}未连接,以下指令未能成功发送" + BitConverter.ToString(sendData));
}
}
else
{
- Logs.Write($"【单灯单独控制】{clientIp}未连接,以下指令未能成功发送" + BitConverter.ToString(sendData));
+ var tcpClient = TCPClientManager.Service.GetClients().Where(t => t.IP + ":" + t.Port.ToString() == client.ClientIp).FirstOrDefault();
+ if (tcpClient != null)
+ {
+ try
+ {
+ tcpClient.Send(sendData,0,sendData.Length);
+ Logs.Write("【单灯单独控制】发送指令" + BitConverter.ToString(sendData));
+ }
+ catch (Exception ex)
+ {
+ Logs.Write($"【单灯单独控制】{client}以下指令发送中遇到异常{ex.Message}" + BitConverter.ToString(sendData));
+ }
+ }
+ else
+ {
+ Logs.Write($"【单灯单独控制】{client}未连接,以下指令未能成功发送" + BitConverter.ToString(sendData));
+ return new ResponseCommon