using DotNetty.Buffers; using DotNetty.Codecs; using DotNetty.Handlers.Timeout; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using JSMachine.WMS.Common; using JSMachine.WMS.Infrastructure.Helper; using JSMachine.WMS.Netty.NettyAsServer.Codec; using System; using System.Text; using System.Threading.Tasks; using Encoder = JSMachine.WMS.Netty.NettyAsServer.Codec.Encoder; namespace JSMachine.WMS.Netty.NettyAsServer { public static class TcpServerEngine { private static ServerBootstrap SocketBootstrap = new(); private static IEventLoopGroup BossGroup => new MultithreadEventLoopGroup(2); private static IEventLoopGroup WorkGroup = new MultithreadEventLoopGroup(); public static async void InitEngine(int port) { try { LogHelper.Info("正在启动TCP服务端-----------"); SocketBootstrap .Group(BossGroup, WorkGroup) .Channel() .Option(ChannelOption.TcpNodelay, true) //.Option(ChannelOption.ConnectTimeout, TimeSpan.FromSeconds(1000)) .Option(ChannelOption.SoKeepalive, true) //以下两种方式都是设置一次性能接收的数据包大小 //.Option(ChannelOption.SoRcvbuf, 4 * 1024) .Option(ChannelOption.RcvbufAllocator, new FixedRecvByteBufAllocator(8 * 1024)) .ChildHandler(new ActionChannelInitializer(channel => { IChannelPipeline pipeline = channel.Pipeline; //心跳超时时间配置 //pipeline.AddLast(new IdleStateHandler(100,100,100)); IByteBuffer delimiter = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("[CR]\r\n")); //简单的协议可以直接使用自带的分隔符解码器 pipeline.AddLast("framing-dec", new DelimiterBasedFrameDecoder(4000, true, delimiter)); //自定义编码器 pipeline.AddLast(new Encoder()); pipeline.AddLast("echo", new EchoServerChannelHandler()); })); await SocketBootstrap.BindAsync(port); LogHelper.Info("TCP服务启动成功"); } catch (Exception ex) { LogHelper.Error($"TCP服务启动失败,错误信息 {ex.Message}"); await Task.WhenAll( BossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), WorkGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } } } }