first commit
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.Netty.Common.Model;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Netty.NettyAsClient
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP客户端引擎
|
||||
/// </summary>
|
||||
public class TcpClientEngine
|
||||
{
|
||||
private Bootstrap SocketBootstrap = new();
|
||||
private MultithreadEventLoopGroup WorkGroup = new();
|
||||
private IChannel channel;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 TCP 客户端编解码管道并启动后台连接监视。
|
||||
/// </summary>
|
||||
/// <param name="tcpEngineInitParam">服务端地址、端口及协议编解码配置。</param>
|
||||
public async Task InitEngine(TcpEngineInitParam tcpEngineInitParam)
|
||||
{
|
||||
LogHelper.Info("正在启动TCP客户端引擎-----------");
|
||||
|
||||
SocketBootstrap
|
||||
.Group(WorkGroup)
|
||||
.Channel<TcpSocketChannel>()
|
||||
.Option(ChannelOption.TcpNodelay, true)
|
||||
.Option(ChannelOption.ConnectTimeout, TimeSpan.FromSeconds(2))
|
||||
.Option(ChannelOption.SoKeepalive, true)
|
||||
//以下两种方式都是设置一次性能接收的数据包大小
|
||||
//.Option(ChannelOption.SoRcvbuf, 4 * 1024)
|
||||
.Option(ChannelOption.RcvbufAllocator, new FixedRecvByteBufAllocator(25))
|
||||
.Handler(new ActionChannelInitializer<ISocketChannel>(channel =>
|
||||
{
|
||||
IChannelPipeline pipeline = channel.Pipeline;
|
||||
|
||||
if (!string.IsNullOrEmpty(tcpEngineInitParam.DecoderWord))
|
||||
{
|
||||
IByteBuffer delimiter = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("\r"));
|
||||
//简单的协议可以直接使用自带的分隔符解码器
|
||||
pipeline.AddLast("framing-dec", new DelimiterBasedFrameDecoder(32, true, delimiter));
|
||||
}
|
||||
else
|
||||
{
|
||||
//pipeline.AddLast("framing-enc", new LengthFieldPrepender(2));
|
||||
pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(tcpEngineInitParam.EncoderWord))
|
||||
{
|
||||
//自定义编码器,编解码器必须写在处理器之前,否则数据包将不会经过编解码器
|
||||
pipeline.AddLast(new JSMachine.WMS.Netty.NettyAsClient.Codec.Encoder(tcpEngineInitParam.EncoderWord));
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline.AddLast(new JSMachine.WMS.Netty.NettyAsClient.Codec.EnCoderPrint(tcpEngineInitParam.EncoderWord));
|
||||
}
|
||||
|
||||
|
||||
pipeline.AddLast("echo", new EchoClientChannelHandler(tcpEngineInitParam));
|
||||
}));
|
||||
|
||||
await MonitorTcpConnection(tcpEngineInitParam.IP, tcpEngineInitParam.Port);
|
||||
}
|
||||
|
||||
private async Task MonitorTcpConnection(string serverIP, int port)
|
||||
{
|
||||
// 连接断开后持续重试,保证扫码设备临时掉线时能够自动恢复通信。
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (channel == null || !channel.Active)
|
||||
{
|
||||
try
|
||||
{
|
||||
channel = await SocketBootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(serverIP), port));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error($"连接服务端 {serverIP} 失败,错误信息 {ex.Message} 即将重新连接");
|
||||
}
|
||||
}
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user