You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
6.8 KiB
C#

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SlnMesnac.Config;
using SlnMesnac.TouchSocket.Entity;
5 months ago
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
5 months ago
using TouchSocket.Core;
using TouchSocket.Sockets;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* LAPTOP-E0N2L34V
* SlnMesnac.TouchSocket
* 496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* WenJY
* wenjy@mesnac.com
* 2024-03-27 21:58:35
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.TouchSocket
{
4 months ago
public class TcpServer
5 months ago
{
5 months ago
private ILogger<TcpServer> _logger;
private readonly TcpService _service;
private readonly AppConfig _appConfig;
5 months ago
/// <summary>
/// 接收客户端指令委托
/// </summary>
public delegate void ReceivedClientBuffer(byte[] buffer);
public event ReceivedClientBuffer? ReceivedClientBufferEvent;
public delegate void RefreshClientInfo(TcpService tcpService);
public event RefreshClientInfo? RefreshClientInfoEvent;
public Action<String, bool> RefreshStateAction;
public delegate void GetVisionData(TcpVisionEntity entity);
/// <summary>
/// 视觉系统反馈给上位机调度系统状态
/// </summary>
public event GetVisionData? VisionSysStateEvent;
/// <summary>
/// 视觉系统回复给上位机调度系统开始工作状态
/// </summary>
public event GetVisionData? VisionStartWorkEvent;
/// <summary>
/// 一次码垛完成,发送码垛结果
/// </summary>
public event GetVisionData? StackWorkDoneEvent;
/// <summary>
/// 视觉系统发送给机器人码垛位置定位结果
/// </summary>
public event GetVisionData? StackRobotLocationEvent;
/// <summary>
/// 人工异常处理完成并更新计数
/// </summary>
public event GetVisionData? ManualExceptionDealDoneEvent;
private string ClientID = "";
public TcpServer(ILogger<TcpServer> logger,TcpService tcpService, AppConfig appConfig)
5 months ago
{
_logger = logger;
_service = tcpService;
_appConfig = appConfig;
}
4 months ago
public void Init(int serverPort)
5 months ago
{
try
{
_service.Connecting = (client, e) => {
_logger.LogInformation($"客户端{client.IP}正在接入服务");
return EasyTask.CompletedTask;
};
_service.Connected = (client, e) => {
5 months ago
_logger.LogInformation($"客户端{client.IP}接入服务成功");
RefreshClientInfoEvent?.Invoke(_service);
RefreshStateAction?.Invoke(client.IP,true);
ClientID = client.Id;
5 months ago
return EasyTask.CompletedTask;
};
_service.Disconnected = (client, e) => {
5 months ago
_logger.LogInformation($"客户端{client.IP}断开连接");
RefreshStateAction?.Invoke(client.IP, false);
5 months ago
RefreshClientInfoEvent?.Invoke(_service);
return EasyTask.CompletedTask;
};
_service.Received = (client, e) =>
{
//从客户端收到信息
var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意数据长度是byteBlock.Len
_logger.LogInformation($"客户端{client.IP}:"+ mes);
//区分一下指令类型,委托传参
if (mes == "heartbeat")
{
RefreshStateAction?.Invoke(client.IP, true);
}
//var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意数据长度是byteBlock.Len
5 months ago
byte[] receivedBuffer = new byte[e.ByteBlock.Len];
Array.Copy(e.ByteBlock.Buffer, 0, receivedBuffer, 0, e.ByteBlock.Len);
//ReceivedClientBufferEvent?.Invoke(receivedBuffer);
DataClassify(BufferDataAnalysis.BufferRootAnalysis(receivedBuffer));
5 months ago
return EasyTask.CompletedTask;
};
_service.Setup(new TouchSocketConfig()//载入配置
.SetListenIPHosts(new IPHost[] { new IPHost(serverPort) })
5 months ago
.ConfigureContainer(a =>//容器的配置顺序应该在最前面
{
a.AddConsoleLogger();
})
.ConfigurePlugins(a =>
{
//自定义插件
}));
_service.Start();
_logger.LogInformation($"TcpServer启动成功监听端口{serverPort}");
}
catch (Exception ex)
{
//throw new InvalidOperationException($"TcpServer启动异常{ex.Message}");
_logger.LogError($"TcpServer启动异常{ex.Message}");
}
}
/// <summary>
/// 数据类型区分
5 months ago
/// </summary>
/// <param name="entity"></param>
public void DataClassify(TcpVisionEntity entity)
5 months ago
{
if(entity == null)
5 months ago
{
_logger.LogError("数据格式校验错误!");
return;
}
switch(entity.Command)
{
case 10: VisionSysStateEvent?.Invoke(entity); break;
case 11: VisionStartWorkEvent?.Invoke(entity); break;
case 12: StackWorkDoneEvent?.Invoke(entity); break;
case 13: StackRobotLocationEvent?.Invoke(entity); break;
case 14: ManualExceptionDealDoneEvent?.Invoke(entity); break;
default: _logger.LogInformation("未知命令字!"); return;
5 months ago
}
}
///// <summary>
///// 向所有客户端发送心跳
///// </summary>
//public void SendHeartBeat()
//{
// var clients = _service.SocketClients.GetClients();
// foreach (var item in clients)
// {
// _service.Send(item.Id,"heartbeat");
// }
//}
5 months ago
}
}