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.

145 lines
5.2 KiB
C#

#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.0.30319.42000
* Mr.Wen's MacBook Pro
* Sln.IntelliBelt.Socket
* E0B382FE-A373-4B1C-9175-EC962B22F6A5
*
* WenJY
*
* 2026-04-24 10:48:20
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using System.Collections.Concurrent;
using System.Text;
using Sln.IntelliBelt.Common;
using Sln.IntelliBelt.Serilog;
using Sln.IntelliBelt.Socket.Adapter;
using TouchSocket.Core;
using TouchSocket.Sockets;
namespace Sln.IntelliBelt.Socket;
public class TcpServer
{
private readonly SerilogHelper _logger;
private readonly TcpService _service;
private readonly StringChange _stringChange;
public TcpServer(SerilogHelper logger, TcpService service, StringChange stringChange)
{
_logger = logger;
_service = service;
_stringChange = stringChange;
}
public delegate void ReceivedClientBuffer(byte[] buffer);
public event ReceivedClientBuffer? ReceivedClientBufferEvent;
public delegate void RefreshClientInfo(TcpService tcpService);
public event RefreshClientInfo? RefreshClientInfoEvent;
public delegate void ReceivedBufferRequestInfo(TcpSessionClient client,BufferRequestInfo requestInfo);
public event ReceivedBufferRequestInfo ReceivedBufferRequestInfoEvent;
public void Init(int serverPort)
{
try
{
_service.Connecting = (client, e) => {
return EasyTask.CompletedTask;
};
_service.Connected = (client, e) => {
_logger.Info($"客户端{client.IP}:{client.Port}接入服务成功,Id:{client.Id}");
RefreshClientInfoEvent?.Invoke(_service);
return EasyTask.CompletedTask;
};
_service.Closed = (client, e) => {
_logger.Info($"客户端{client.IP}:{client.Port}断开连接");
RefreshClientInfoEvent?.Invoke(_service);
return EasyTask.CompletedTask;
};
_service.Received = (client, e) =>
{
if (e.RequestInfo is BufferRequestInfo request)
{
string msg = $"{client.Id}链接收到终端:{request.terminalAddr}指令====>>>>ContentLen:{request.contentLen};Content:{request.content};";
_logger.Info($"{msg}");
if (client.Id != request.terminalAddr)
{
_logger.Info($"更新连接 Id:{client.Id}==>{request.terminalAddr}");
client.ResetIdAsync(request.terminalAddr).Wait();
}
ReceivedBufferRequestInfoEvent?.Invoke(client, request);
}
return EasyTask.CompletedTask;
};
_service.SetupAsync(new TouchSocketConfig()//载入配置
.SetListenIPHosts(new IPHost[] { new IPHost($"0.0.0.0:{serverPort}") })
.SetTcpDataHandlingAdapter(() => new CustomDataHandlingAdapter(_logger,_stringChange))
.ConfigureContainer(a =>//容器的配置顺序应该在最前面
{
a.AddConsoleLogger();
})
.ConfigurePlugins(a =>
{
//自定义插件
}));
_service.StartAsync();
_logger.Info($"TcpServer启动成功监听端口{serverPort}");
}
catch (Exception ex)
{
_logger.Info($"TcpServer启动异常{ex.Message}");
}
}
/// <summary>
/// 向指定客户端发送指令,使用序号关联匹配应答,避免创建新的 TCP 连接
/// </summary>
public async Task<BufferRequestInfo> SendMsgToClient(string clientId, byte[] buffer)
{
if (_service.Clients.TryGetClient(clientId, out TcpSessionClient tcpSessionClient))
{
var waitClinet = tcpSessionClient.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response => //设置用于筛选的fun委托当返回为true时才会响应返回
{
return true;
}
});
Task<ResponsedData> responsedData = waitClinet.SendThenResponseAsync(buffer, 5000);
IRequestInfo requestInfo = responsedData.Result.RequestInfo;
BufferRequestInfo bufferRequestInfo = (BufferRequestInfo)requestInfo ;
return bufferRequestInfo;
}
else
{
return new BufferRequestInfo();
}
}
}