public void Init() { if (this.bossGroup != null) { return; } this.config = this.ServiceProvider.GetService <IOptionsMonitor <NetworkConfiguration> >().CurrentValue; var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher, config.EventLoopCount); }
private void InitializeNetty() { var dispatcher = new DispatcherEventLoopGroup(); _bossGroup = dispatcher; _workerGroup = new WorkerEventLoopGroup(dispatcher); _bootstrap = new ServerBootstrap() .Group(_bossGroup, _workerGroup) .Channel <TcpServerChannel>() .Option(ChannelOption.SoBacklog, 100) .ChildHandler(new ActionChannelInitializer <IChannel>(_setting.ChannelAction)); }
static async Task RunServerAsync() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"Server garbage collection: {GCSettings.IsServerGC}"); Console.WriteLine($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); IEventLoopGroup group; IEventLoopGroup workGroup; var dispatcher = new DispatcherEventLoopGroup(); group = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); try { var bootstrap = new ServerBootstrap(); bootstrap.Group(group, workGroup); bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } bootstrap .Option(ChannelOption.SoBacklog, 8192) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; //pipeline.AddLast("encoder", new HttpResponseEncoder()); pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new HttpObjectAggregator(ConfigHelper.GetValue <int>("maxContentLength"))); pipeline.AddLast("handler", new HttpServerHandler()); })); IChannel bootstrapChannel = await bootstrap.BindAsync(IPAddress.IPv6Any, ConfigHelper.GetValue <int>("httpPort")); Console.WriteLine($"Httpd started. Listening on {bootstrapChannel.LocalAddress}"); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { group.ShutdownGracefullyAsync().Wait(); } }
/// <summary> /// 需要使用 SocketTool 创建tcp服务器 /// </summary> public JT808SourcePackageChannelServiceTest() { SimpleTcpClient = new JT808SimpleTcpClient(endPoint, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6555)); //作为设备5秒上传 Task.Run(() => { Random random = new Random(); while (true) { JT808Package jT808Package = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("12345678900" + random.Next(0, 2).ToString()); SimpleTcpClient.WriteAsync(JT808Serializer.Serialize(jT808Package)); Thread.Sleep(1000); } }); // 作为源包转发服务端 DispatcherEventLoopGroup bossGroup = new DispatcherEventLoopGroup(); WorkerEventLoopGroup workerGroup = new WorkerEventLoopGroup(bossGroup, 1); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel <TcpServerChannel>(); bootstrap .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; channel.Pipeline.AddLast("jt808Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }), Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag }))); channel.Pipeline.AddLast("jt808Decode", new JT808ClientDecoder()); })); bootstrap.BindAsync(6655); DispatcherEventLoopGroup bossGroup1 = new DispatcherEventLoopGroup(); WorkerEventLoopGroup workerGroup1 = new WorkerEventLoopGroup(bossGroup1, 1); ServerBootstrap bootstrap1 = new ServerBootstrap(); bootstrap1.Group(bossGroup1, workerGroup1); bootstrap1.Channel <TcpServerChannel>(); bootstrap1 .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; channel.Pipeline.AddLast("jt808Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }), Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag }))); channel.Pipeline.AddLast("jt808Decode", new JT808ClientDecoder()); })); bootstrap1.BindAsync(6656); }
public Task StartAsync(CancellationToken cancellationToken) { bossGroup = new DispatcherEventLoopGroup(); workerGroup = new WorkerEventLoopGroup(bossGroup, configuration.EventLoopCount); serverBufferAllocator = new PooledByteBufferAllocator(); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } bootstrap .Option(ChannelOption.SoBacklog, configuration.SoBacklog) .ChildOption(ChannelOption.Allocator, serverBufferAllocator) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; using (var scope = serviceProvider.CreateScope()) { channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler( configuration.ReaderIdleTimeSeconds, configuration.WriterIdleTimeSeconds, configuration.AllIdleTimeSeconds)); channel.Pipeline.AddLast("jtneTcpConnection", scope.ServiceProvider.GetRequiredService <JTNETcpConnectionHandler>()); //LengthFieldBasedFrameDecoder 定长解码器 //参数说明: //maxFrameLength:解码的帧的最大长度 //lengthFieldOffset:长度字段的偏差(长度属性的起始位(偏移位),包中存放有整个大数据包长度的字节,这段字节的其实位置) //lengthFieldLength:长度字段占的字节数(即存放整个大数据包长度的字节所占的长度) //lengthAdjustmen:添加到长度字段的补偿值(长度调节值,在总长被定义为包含包头长度时,修正信息长度)。 //initialBytesToStrip:从解码帧中第一次去除的字节数(跳过的字节数,根据需要我们跳过lengthFieldLength个字节,以便接收端直接接受到不含“长度属性”的内容) //failFast :为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常 //22 JTNEPackage数据体长度 //2 JTNEPackage数据体长度占两个字节 //1 JTNEPackage校验位 channel.Pipeline.AddLast("jtneTcpDecoder", new LengthFieldBasedFrameDecoder(int.MaxValue, 22, 2, 1, 0)); channel.Pipeline.AddLast("jtneTcpBuffer", scope.ServiceProvider.GetRequiredService <JTNETcpDecoder>()); channel.Pipeline.AddLast("jtneTcpServerHandler", scope.ServiceProvider.GetRequiredService <JTNETcpServerHandler>()); } })); logger.LogInformation($"JTNE TCP Server start at {IPAddress.Any}:{configuration.TcpPort}."); return(bootstrap.BindAsync(configuration.TcpPort) .ContinueWith(i => bootstrapChannel = i.Result)); }
private static async Task RunServerAsync() { InternalLoggerFactory.DefaultFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, false)); var dispatcher = new DispatcherEventLoopGroup(); var bossGroup = dispatcher; var workerGroup = new WorkerEventLoopGroup(dispatcher); var bootstrap = new ServerBootstrap(); try { bootstrap .Group(bossGroup, workerGroup) .Channel <TcpServerChannel>() .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("SRV-LSTN")) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { var pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler("SRV-CONN")); pipeline.AddLast("framing-enc", new LengthFieldPrepender(2)); pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); //pipeline.AddLast("mqtt-encoder", new MqttEncoder()); //pipeline.AddLast("mqtt-decoder", new MqttDecoder(true, 256 * 1024)); //pipeline.AddLast("string-encoder", new StringEncoder()); //pipeline.AddLast("string-decoder", new StringDecoder()); pipeline.AddLast("request-encoder", new RequestEncoder()); pipeline.AddLast("request-decoder", new RequestDecoder()); pipeline.AddLast("echo", new EchoServerHandler()); })); var boundChannel = await bootstrap.BindAsync(9998); Console.ReadLine(); await boundChannel.CloseAsync(); } finally { await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1)) ); } }
public void Test1() { //预热 Thread.Sleep(3000); jT808SourcePackageChannelService = ServiceProvider.GetService <JT808SourcePackageChannelService>(); var result = jT808SourcePackageChannelService.GetAll(); //创建服务 DispatcherEventLoopGroup bossGroup2 = new DispatcherEventLoopGroup(); WorkerEventLoopGroup workerGroup2 = new WorkerEventLoopGroup(bossGroup2, 1); ServerBootstrap bootstrap2 = new ServerBootstrap(); bootstrap2.Group(bossGroup2, workerGroup2); bootstrap2.Channel <TcpServerChannel>(); bootstrap2 .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; channel.Pipeline.AddLast("jt808Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }), Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag }))); channel.Pipeline.AddLast("jt808Decode", new JT808ClientDecoder()); })); bootstrap2.BindAsync(6522); //添加服务 var addResult = jT808SourcePackageChannelService.Add(new Dtos.JT808IPAddressDto { Host = "127.0.0.1", Port = 6522 }).Result; Thread.Sleep(1000); var result1 = jT808SourcePackageChannelService.GetAll(); //删除 var result2 = jT808SourcePackageChannelService.Remove(new Dtos.JT808IPAddressDto { Host = "127.0.0.1", Port = 6522 }).Result; //[::ffff:127.0.0.1]:13196 var result3 = jT808SourcePackageChannelService.GetAll(); }
public async void StartAsync(X509Certificate2 certificate, AutoResetEvent closer, int threadCount) { Contract.Requires(certificate != null); Contract.Requires(closer != null); Contract.Requires(threadCount > 0); theCloser = closer; Console.WriteLine("Initializing Server..."); LoggerFactory loggerFactory = new LoggerFactory(); loggerFactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Error, false); InternalLoggerFactory.DefaultFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, false)); var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workerGroup = new WorkerEventLoopGroup(dispatcher, threadCount); try { var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel <TcpServerChannel>(); bootstrap .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("SRV_LSTN")) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (certificate != null) { pipeline.AddLast("tls", TlsHandler.Server(certificate)); } pipeline.AddLast("framing-enc", new LengthFieldPrepender(2)); pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); pipeline.AddLast("echo", new EchoServerHandler()); })); theChannel = await bootstrap.BindAsync(IPAddress.Any, 3382); } catch (Exception e) { Console.WriteLine(e.Message); } }
static async Task RunServerAsync() { IEventLoopGroup bossGroup; IEventLoopGroup workerGroup; var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workerGroup = new WorkerEventLoopGroup(dispatcher); try { var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel <TcpServerChannel>(); bootstrap .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("SRV-LSTN")) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler("SRV-CONN")); pipeline.AddLast("framing-enc", new LengthFieldPrepender(2)); pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); pipeline.AddLast("echo", new SocketServerHandler()); })); IChannel boundChannel = await bootstrap.BindAsync(port); Console.ReadLine(); await boundChannel.CloseAsync(); } finally { await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } }
public async Task StartAsync(CancellationToken cancellationToken) { if (configuration.TcpPort <= 0) { return; } var bootstrap = new ServerBootstrap(); serverBufferAllocator = new PooledByteBufferAllocator(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workerGroup = new WorkerEventLoopGroup(dispatcher); bootstrap.Channel <TcpServerChannel>(); bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } else { bossGroup = new MultithreadEventLoopGroup(1); workerGroup = new MultithreadEventLoopGroup(); bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap.Group(bossGroup, workerGroup); bootstrap .Option(ChannelOption.SoBacklog, configuration.SoBacklog) .ChildOption(ChannelOption.Allocator, serverBufferAllocator) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { var pipeline = channel.Pipeline; using var scope = serviceProvider.CreateScope(); pipeline.AddLast(new IdleStateHandler(configuration.ReaderIdleTimeSeconds, configuration.WriterIdleTimeSeconds, configuration.AllIdleTimeSeconds)); pipeline.AddLast(scope.ServiceProvider.GetRequiredService <TcpMetadataDecoder>()); pipeline.AddLast(scope.ServiceProvider.GetRequiredService <TcpMetadataEncoder>()); pipeline.AddLast(scope.ServiceProvider.GetRequiredService <BranchTcpServerHandler>()); })); logger.LogInformation($"TCP Server start at {IPAddress.Any}:{configuration.TcpPort}."); bootstrapChannel = await bootstrap.BindAsync(configuration.TcpPort); }
public Task StartAsync(CancellationToken cancellationToken) { bossGroup = new DispatcherEventLoopGroup(); workerGroup = new WorkerEventLoopGroup(bossGroup, configuration.EventLoopCount); serverBufferAllocator = new PooledByteBufferAllocator(); //serverBufferAllocator = new UnpooledByteBufferAllocator(); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } bootstrap .Option(ChannelOption.SoBacklog, configuration.SoBacklog) .ChildOption(ChannelOption.Allocator, serverBufferAllocator) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; using (var scope = serviceProvider.CreateScope()) { channel.Pipeline.AddLast("jt808TcpBuffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }), Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag }))); channel.Pipeline.AddLast("jt808TcpDecode", scope.ServiceProvider.GetRequiredService <JT808TcpDecoder>()); channel.Pipeline.AddLast("jt808TcpEncode", scope.ServiceProvider.GetRequiredService <JT808TcpEncoder>()); channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler( configuration.ReaderIdleTimeSeconds, configuration.WriterIdleTimeSeconds, configuration.AllIdleTimeSeconds)); channel.Pipeline.AddLast("jt808TcpConnection", scope.ServiceProvider.GetRequiredService <JT808TcpConnectionHandler>()); channel.Pipeline.AddLast("jt808TcpService", scope.ServiceProvider.GetRequiredService <JT808TcpServerHandler>()); } })); logger.LogInformation($"JT808 TCP Server start at {IPAddress.Any}:{configuration.TcpPort}."); return(bootstrap.BindAsync(configuration.TcpPort) .ContinueWith(i => bootstrapChannel = i.Result)); }
public EventLoopGroups(ServerConfiguration serverConfiguration) { IEventLoopGroup bossGroup; IEventLoopGroup workGroup; if (serverConfiguration.Libuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } BossGroup = bossGroup; WorkerGroup = workGroup; }
public Task StartAsync(CancellationToken cancellationToken) { bossGroup = new DispatcherEventLoopGroup(); workerGroup = new WorkerEventLoopGroup(bossGroup, configuration.EventLoopCount); serverBufferAllocator = new PooledByteBufferAllocator(); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } bootstrap .Option(ChannelOption.SoBacklog, 8192) .ChildOption(ChannelOption.Allocator, serverBufferAllocator) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new CorsHandler(CorsConfigBuilder .ForAnyOrigin() .AllowNullOrigin() .AllowedRequestMethods(HttpMethod.Get, HttpMethod.Post, HttpMethod.Options, HttpMethod.Delete) .AllowedRequestHeaders((AsciiString)"origin", (AsciiString)"range", (AsciiString)"accept-encoding", (AsciiString)"referer", (AsciiString)"Cache-Control", (AsciiString)"X-Proxy-Authorization", (AsciiString)"X-Requested-With", (AsciiString)"Content-Type") .ExposeHeaders((StringCharSequence)"Server", (StringCharSequence)"range", (StringCharSequence)"Content-Length", (StringCharSequence)"Content-Range") .AllowCredentials() .Build())); pipeline.AddLast(new HttpObjectAggregator(int.MaxValue)); using (var scope = serviceProvider.CreateScope()) { pipeline.AddLast("JT1078HttpServerHandler", scope.ServiceProvider.GetRequiredService <JT1078HttpServerHandler>()); } })); logger.LogInformation($"JT1078 Http Server start at {IPAddress.Any}:{configuration.HttpPort}."); return(bootstrap.BindAsync(configuration.HttpPort) .ContinueWith(i => bootstrapChannel = i.Result)); }
public override void TestShutdownGracefullyNoQuietPeriod() { IEventLoopGroup loop = new DispatcherEventLoopGroup(); ServerBootstrap b = new ServerBootstrap(); b.Group(loop) .Channel <TcpServerChannel>() .ChildHandler(new ChannelHandlerAdapter()); // Not close the Channel to ensure the EventLoop is still shutdown in time. var cf = b.BindAsync(0); cf.GetAwaiter().GetResult(); var f = loop.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.FromMinutes(1)); Assert.True(loop.TerminationCompletion.Wait(TimeSpan.FromMilliseconds(600))); Assert.True(f.IsSuccess()); Assert.True(loop.IsShutdown); Assert.True(loop.IsTerminated); }
public async Task StartAsync() { var bootstrap = new DotNetty.Transport.Bootstrapping.ServerBootstrap(); if (UraganoOptions.DotNetty_Enable_Libuv.Value) { var dispatcher = new DispatcherEventLoopGroup(); BossGroup = dispatcher; WorkerGroup = new WorkerEventLoopGroup(dispatcher); bootstrap.Channel <TcpServerChannel>(); } else { BossGroup = new MultithreadEventLoopGroup(1); WorkerGroup = new MultithreadEventLoopGroup(UraganoOptions.DotNetty_Event_Loop_Count.Value); bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Group(BossGroup, WorkerGroup) .Option(ChannelOption.SoBacklog, UraganoOptions.Server_DotNetty_Channel_SoBacklog.Value) .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default) .ChildOption(ChannelOption.ConnectTimeout, UraganoOptions.DotNetty_Connect_Timeout.Value) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { var pipeline = channel.Pipeline; if (ServerSettings.X509Certificate2 != null) { pipeline.AddLast(TlsHandler.Server(ServerSettings.X509Certificate2)); } //pipeline.AddLast(new LoggingHandler("SRV-CONN")); pipeline.AddLast(new LengthFieldPrepender(4)); pipeline.AddLast(new LengthFieldBasedFrameDecoder(int.MaxValue, 0, 4, 0, 4)); pipeline.AddLast(new MessageDecoder <IInvokeMessage>(Codec)); pipeline.AddLast(new MessageEncoder <IServiceResult>(Codec)); pipeline.AddLast(new ServerMessageHandler(ServiceFactory, ServiceProvider, Logger)); })); Logger.LogTrace($"DotNetty listening {ServerSettings.IP}:{ServerSettings.Port}"); Channel = await bootstrap.BindAsync(new IPEndPoint(ServerSettings.IP, ServerSettings.Port)); }
private ServerBootstrap CreateServerBootstrap(bool useLibuv, out IEventLoopGroup bossGroup, out IEventLoopGroup workerGroup) { Logger.LogInformation( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Logger.LogDebug($"Server garbage collection: {GCSettings.IsServerGC}"); Logger.LogDebug($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); Logger.LogDebug("\n"); if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workerGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workerGroup = new MultithreadEventLoopGroup(); } Logger.LogDebug("Transport type: " + (useLibuv ? "Libuv" : "Socket")); var bootstrap = new ServerBootstrap().Group(bossGroup, workerGroup); Logger.LogDebug($"Use boss group: {bossGroup.GetType().GetDisplayNameWithNamespace()}"); Logger.LogDebug($"Use worker group: {workerGroup.GetType().GetDisplayNameWithNamespace()}"); return(bootstrap); }
public Task ListenAsync() { if (EventLoopGroup == null) { var EventLoopGroup = new DispatcherEventLoopGroup(); WorkerGroup = new WorkerEventLoopGroup(EventLoopGroup); ServerBootstrap = new ServerBootstrap(); ServerBootstrap.Group(EventLoopGroup, WorkerGroup); ServerBootstrap.Channel <TcpServerChannel>(); ServerBootstrap .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("SRV-LSTN")) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler("SRV-CONN")); pipeline.AddLast("framing-enc", new LengthFieldPrepender(4)); pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(int.MaxValue, 0, 4, 0, 4)); pipeline.AddLast("network-handler", new NetworkHandler(true, this)); })); if (EnableHeartbeat) { Ping(false); } } try { Console.WriteLine($"Listen ip {this.Address} port {this.Port}"); return(ServerBootstrap.BindAsync(new IPEndPoint(IPAddress.Parse(this.Address), this.Port))); } catch (Exception ex) { Console.WriteLine(ex); return(Task.FromResult(0)); } }
public async Task StartAsync() { DispatcherEventLoopGroup bossGroup = new DispatcherEventLoopGroup(); WorkerEventLoopGroup workerGroup = new WorkerEventLoopGroup(bossGroup, 4); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup) .Channel <TcpServerChannel>() .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("SRV-LSTN")) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler("SRV-CONN")); pipeline.AddLast("framing-enc", new LengthFieldPrepender(4)); pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(int.MaxValue, 0, 4, 0, 4)); pipeline.AddLast(new ReadServerMessageChannelHandler(_serializer, _logger)); pipeline.AddLast("echo", new RpcServerHandler(async(context, message) => { await OnReceived(context, message); })); })); _channel = await bootstrap.BindAsync(_address.CreateEndPoint()); _logger.Info("服务器启动成功"); } catch (Exception e) { _logger.Error($"错误日志: {e.Message}", e); } }
static async Task Main(string[] args) { ExampleHelper.SetConsoleLogger(); Console.WriteLine( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); bool useLibuv = ServerSettings.UseLibuv; Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket")); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"Server garbage collection : {(GCSettings.IsServerGC ? "Enabled" : "Disabled")}"); Console.WriteLine($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); Console.WriteLine("\n"); IEventLoopGroup bossGroup; IEventLoopGroup workGroup; IEventLoopGroup bossGroup2 = null; IEventLoopGroup workGroup2 = null; if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); dispatcher = new DispatcherEventLoopGroup(); bossGroup2 = dispatcher; workGroup2 = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } IChannel http2Channel = null; IChannel httpChannel = null; try { Http2Server http2 = useLibuv ? new Http2Server(bossGroup2, workGroup2) : new Http2Server(bossGroup, workGroup); http2Channel = await http2.StartAsync(); Console.WriteLine("Open your web browser and navigate to " + "http://127.0.0.1:" + HttpServer.PORT); HttpServer http = new HttpServer(bossGroup, workGroup); httpChannel = await http.StartAsync(); Console.WriteLine("按任意键退出"); Console.ReadKey(); } catch (Exception exc) { Console.WriteLine(exc.ToString()); Console.ReadKey(); } finally { if (http2Channel != null) { await http2Channel.CloseAsync(); } if (httpChannel != null) { await httpChannel.CloseAsync(); } if (workGroup2 != null) { await workGroup2.ShutdownGracefullyAsync(); } if (bossGroup2 != null) { await bossGroup2.ShutdownGracefullyAsync(); } await workGroup.ShutdownGracefullyAsync(); await bossGroup.ShutdownGracefullyAsync(); } }
public async Task StartAsync(CancellationToken cancellationToken) { _Logger.LogInformation( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } _Logger.LogInformation($"Server garbage collection : {(GCSettings.IsServerGC ? "Enabled" : "Disabled")}"); _Logger.LogInformation($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); string websocketPath = _Configuration.GetSection("WebSocket")["path"]; bool libuv = bool.Parse(_Configuration.GetSection("WebSocket")["libuv"]); int port = int.Parse(_Configuration.GetSection("WebSocket")["port"]); ssl = bool.Parse(_Configuration.GetSection("WebSocket")["ssl"]); if (libuv) { var dispatcher = new DispatcherEventLoopGroup(); _BossGroup = dispatcher; _WorkGroup = new WorkerEventLoopGroup(dispatcher); } else { _BossGroup = new MultithreadEventLoopGroup(1); _WorkGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (ssl) { tlsCertificate = new X509Certificate2(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dotnetty.com.pfx"), "password"); } _BootstrapChannel = null; _Bootstrap = new ServerBootstrap(); _Bootstrap.Group(_BossGroup, _WorkGroup); if (libuv) { _Bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { _Bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { _Bootstrap.Channel <TcpServerSocketChannel>(); } _Bootstrap .Option(ChannelOption.SoBacklog, 8192) //.Handler(new LoggingHandler("LSTN")) .Handler(new ServerChannelRebindHandler(OnRebind)) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (ssl) { pipeline.AddLast(TlsHandler.Server(tlsCertificate)); } pipeline.AddLast("idleStateHandler", new IdleStateHandler(0, 0, 120)); //pipeline.AddLast(new LoggingHandler("CONN")); //pipeline.AddLast(new HttpRequestDecoder()); //pipeline.AddLast(new HttpResponseEncoder()); pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new HttpObjectAggregator(65536)); pipeline.AddLast(new WebSocketServerCompressionHandler()); pipeline.AddLast(new WebSocketServerProtocolHandler( websocketPath: websocketPath, subprotocols: null, allowExtensions: true, maxFrameSize: 65536, allowMaskMismatch: true, checkStartsWith: false, dropPongFrames: true, enableUtf8Validator: false)); pipeline.AddLast(new WebSocketServerHttpHandler(websocketPath, _LoggerFactory)); pipeline.AddLast(new WebSocketFrameAggregator(65536)); pipeline.AddLast(new WebSocketServerFrameHandler(_ClusterClient, _LoggerFactory)); })); _BootstrapChannel = await _Bootstrap.BindAsync(IPAddress.Loopback, port); async void OnRebind() { await _BootstrapChannel.CloseAsync(); _Logger.LogInformation("rebind......"); var ch = await _Bootstrap.BindAsync(IPAddress.Loopback, port); _Logger.LogInformation("rebind complate"); Interlocked.Exchange(ref _BootstrapChannel, ch); } }
static async Task Main(string[] args) { ExampleHelper.SetConsoleLogger(); Console.WriteLine( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); bool useLibuv = ServerSettings.UseLibuv; Console.WriteLine($"Transport type : {(useLibuv ? "Libuv" : "Socket")}"); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"Server garbage collection : {(GCSettings.IsServerGC ? "Enabled" : "Disabled")}"); Console.WriteLine($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); Console.WriteLine("\n"); IEventLoopGroup bossGroup; IEventLoopGroup workGroup; if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (ServerSettings.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password"); } try { int port = ServerSettings.Port; IChannel bootstrapChannel = null; var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workGroup); if (useLibuv) { bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Option(ChannelOption.SoBacklog, 8192) .Handler(new LoggingHandler("LSTN")) //.Handler(new ServerChannelRebindHandler(DoBind)) .ChildHandler(new Http2ServerInitializer(tlsCertificate)); bootstrapChannel = await bootstrap.BindAsync(IPAddress.Loopback, port); //async void DoBind() //{ // await bootstrapChannel.CloseAsync(); // Console.WriteLine("rebind......"); // var ch = await bootstrap.BindAsync(IPAddress.Loopback, port); // Console.WriteLine("rebind complate"); // Interlocked.Exchange(ref bootstrapChannel, ch); //} Console.WriteLine("Open your HTTP/2-enabled web browser and navigate to " + (ServerSettings.IsSsl ? "https" : "http") + "://127.0.0.1:" + ServerSettings.Port + '/'); Console.WriteLine("Press any key to exit"); Console.ReadKey(); await bootstrapChannel.CloseAsync(); } finally { await Task.WhenAll( workGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)) ); } }
public async Task Listen() { var bootstrap = new ServerBootstrap(); if (_rpcOptions.UseLibuv) { var dispatcher = new DispatcherEventLoopGroup(); m_bossGroup = dispatcher; m_workerGroup = new WorkerEventLoopGroup(dispatcher); bootstrap.Channel <TcpServerChannel>(); } else { m_bossGroup = new MultithreadEventLoopGroup(1); m_workerGroup = new MultithreadEventLoopGroup(); bootstrap.Channel <TcpServerSocketChannel>(); } X509Certificate2 tlsCertificate = null; if (_rpcOptions.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(_hostEnvironment.ContentRootPath, _rpcOptions.SslCertificateName), _rpcOptions.SslCertificatePassword); } bootstrap .Option(ChannelOption.SoBacklog, _rpcOptions.SoBacklog) .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default) .Group(m_bossGroup, m_workerGroup) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { var pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast("tls", TlsHandler.Server(tlsCertificate)); } pipeline.AddLast(new LengthFieldPrepender(8)); pipeline.AddLast(new LengthFieldBasedFrameDecoder(int.MaxValue, 0, 8, 0, 8)); pipeline.AddLast(new TransportMessageChannelHandlerAdapter(_transportMessageDecoder)); pipeline.AddLast(new ServerHandler((channelContext, message) => { if (message.IsInvokeMessage()) { var sender = new DotNettyTcpServerMessageSender(channelContext); OnReceived(sender, message); } }, _healthCheck)); })); try { m_boundChannel = await bootstrap.BindAsync(_hostAddress.IPEndPoint); Logger.LogInformation($"服务监听者启动成功,监听地址:{_hostAddress},通信协议:{_hostAddress.ServiceProtocol}"); } catch (Exception e) { Logger.LogError( $"服务监听启动失败,监听地址:{_hostAddress},通信协议:{_hostAddress.ServiceProtocol},原因: {e.Message}"); throw; } }
static async Task Main(string[] args) { ExampleHelper.SetConsoleLogger(); Console.WriteLine( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); bool useLibuv = ServerSettings.UseLibuv; Console.WriteLine($"Transport type : {(useLibuv ? "Libuv" : "Socket")}"); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"Server garbage collection: {GCSettings.IsServerGC}"); Console.WriteLine($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); IEventLoopGroup group; IEventLoopGroup workGroup; if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); group = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { group = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (ServerSettings.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password"); } try { var bootstrap = new ServerBootstrap(); bootstrap.Group(group, workGroup); if (useLibuv) { bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Option(ChannelOption.SoBacklog, 200) #if DEBUG .Handler(new LoggingHandler("LSTN")) #endif .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast(TlsHandler.Server(tlsCertificate)); } #if DEBUG pipeline.AddLast(new LoggingHandler("CONN")); #endif //pipeline.AddLast("encoder", new HttpResponseEncoder()); //pipeline.AddLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false)); pipeline.AddLast(new HttpServerCodec(4096, 8192, 8192, false)); //pipeline.AddLast(new HttpObjectAggregator(65536)); pipeline.AddLast(new HttpServerExpectContinueHandler()); pipeline.AddLast("handler", new HelloServerHandler()); })); IChannel bootstrapChannel = await bootstrap.BindAsync(IPAddress.IPv6Any, ServerSettings.Port); Console.WriteLine($"Httpd started. Listening on {bootstrapChannel.LocalAddress}"); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { group.ShutdownGracefullyAsync().Wait(); } }
static async Task RunServerAsync() { //设置输出日志到Console ExampleHelper.SetConsoleLogger(); // 主工作线程组 IEventLoopGroup bossGroup; // 工作线程组 IEventLoopGroup workerGroup; /* * IEventLoopGroup 是用来处理I/O操作的多线程事件循环器, * Netty 提供了许多不同的 EventLoopGroup 的实现用来处理不同的传输。 * 在这个例子中我们实现了一个服务端的应用,因此会有2个 NioEventLoopGroup 会被使用。 * 第一个经常被叫做‘boss’,用来接收进来的连接。第二个经常被叫做‘worker’。 * 用来处理已经被接收的连接,一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。 * 如何知道多少个线程已经被使用,如何映射到已经创建的 Channel上都需要依赖于 * IEventLoopGroup 的实现,并且可以通过构造函数来配置他们的关系。 */ if (ServerSettings.UseLibuv) { // 主工作线程组,设置为1个线程 var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; // 子工作线程组,设置为1个线程 workerGroup = new WorkerEventLoopGroup(dispatcher); } else { //设置为1个线程 bossGroup = new MultithreadEventLoopGroup(1); //默认为内核数*2的线程数 workerGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; //如果使用加密通道 if (ServerSettings.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password"); } try { /* * 声明一个服务端Bootstrap,每个Netty服务端程序,都由ServerBootstrap控制, * 通过链式的方式组装需要的参数。 * ServerBootstrap 是一个启动 Transport 服务的辅助启动类。 * 你可以在这个服务中直接使用 Channel,但是这会是一个复杂的处理过程, * 在很多情况下你并不需要这样做。 */ var bootstrap = new ServerBootstrap(); // 设置主和工作线程组 bootstrap.Group(bossGroup, workerGroup); // 设置通道模式为TcpSocket if (ServerSettings.UseLibuv) { bootstrap.Channel <TcpServerChannel>(); } else { //这里我们指定使用 TcpServerChannel类来举例说明一个新的 Channel 如何接收进来的连接。 bootstrap.Channel <TcpServerSocketChannel>(); } // 设置网络IO参数等,这里可以设置很多参数,当然你对网络调优和参数设置非常了解的话,你可以设置,或者就用默认参数吧 //你可以设置这里指定的 Channel 实现的配置参数。我们正在写一个TCP/IP 的服务端,因此我们被允许设置 socket 的参数选项比如tcpNoDelay 和 keepAlive。 bootstrap.Option(ChannelOption.SoBacklog, 100) //初始化服务端可连接队列 //.Handler(new LoggingHandler("SRV-LSTN")) //在主线程组上设置一个打印日志的处理器 /* * ChannelInitializer 是一个特殊的处理类,他的目的是帮助使用者配置一个新的 Channel。 * 也许你想通过增加一些处理类比如DiscardServerHandler 来配置一个新的 Channel, * 或者其对应的ChannelPipeline 来实现你的网络程序。 * 当你的程序变的复杂时,可能你会增加更多的处理类到 pipline 上, * 然后提取这些匿名类到最顶层的类上。 */ .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { //工作线程连接器 是设置了一个管道, //服务端主线程所有接收到的信息都会通过这个管道一层层往下传输 //同时所有出栈的消息 也要这个管道的所有处理器进行一步步处理 IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) //Tls的加解密 { pipeline.AddLast("tls", TlsHandler.Server(tlsCertificate)); } //添加日志拦截器 //pipeline.AddLast(new LoggingHandler("SRV-CONN")); //出栈消息,通过这个handler 在消息顶部加上消息的长度 //LengthFieldPrepender(2):使用2个字节来存储数据的长度。 pipeline.AddLast("framing-enc", new LengthFieldPrepender(2)); /* * 自定义长度帧解码器 * 入栈消息通过该Handler,解析消息的包长信息,并将正确的消息体发送给下一个处理Handler * 1.MaxFrameLength = ushort.MaxValue,发送的数据包最大长度 * 2.LengthFieldOffset = 0,长度域偏移量,指的是长度域位于整个数据包字节数组中的下标。因为不存在包头,所以为0 * 3.LengthFieldLength = 2,长度域的自己的字节数长度,int整型为4个字节。Client出栈时添加两个字节,所以为2 * 4.LengthAdjustment = 0,长度域的偏移量矫正。 如果长度域的值,除了包含有效数据域的长度外,还包含了其他域(如长度域自身)长度,那么,就需要进行矫正。公式:包长 = 长度域偏移 + 长度域的值 + 长度域长 + 矫正值。 * 5.InitialBytesToStrip = 2,读取时需要跳过的字节数,Client出栈时添加2个字节数据长度 */ pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); //业务handler ,这里是实际处理Echo业务的Handler pipeline.AddLast("echo", new EchoServerHandler()); })); // bootstrap绑定到指定端口的行为 就是服务端启动服务,同样的Serverbootstrap可以bind到多个端口,多次调用 bind() 方法(基于不同绑定地址)。 IChannel boundChannel = await bootstrap.BindAsync(ServerSettings.Port); Console.ReadLine(); //关闭服务 await boundChannel.CloseAsync(); } finally { //释放工作组线程 //使用完成后,优雅的释放掉指定的工作组线程,当然,你可以选择关闭程序,但这并不推荐。 await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } }
static async Task RunServerAsync() { Console.WriteLine( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); bool useLibuv = ServerSettings.UseLibuv; Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket")); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"Server garbage collection : {(GCSettings.IsServerGC ? "Enabled" : "Disabled")}"); Console.WriteLine($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); Console.WriteLine("\n"); IEventLoopGroup bossGroup; IEventLoopGroup workGroup; if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (ServerSettings.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password"); } try { var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workGroup); if (useLibuv) { bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Option(ChannelOption.SoBacklog, 8192) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast(TlsHandler.Server(tlsCertificate)); } pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new HttpObjectAggregator(65536)); pipeline.AddLast(new WebSocketServerHandler()); })); int port = ServerSettings.Port; IChannel bootstrapChannel = await bootstrap.BindAsync(IPAddress.Loopback, port); Console.WriteLine("Open your web browser and navigate to " + $"{(ServerSettings.IsSsl ? "https" : "http")}" + $"://127.0.0.1:{port}/"); Console.WriteLine("Listening on " + $"{(ServerSettings.IsSsl ? "wss" : "ws")}" + $"://127.0.0.1:{port}/websocket"); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { workGroup.ShutdownGracefullyAsync().Wait(); bossGroup.ShutdownGracefullyAsync().Wait(); } }
static async Task RunServerAsync() { ExampleHelper.SetConsoleLogger(); IEventLoopGroup bossGroup; IEventLoopGroup workerGroup; if (ServerSettings.UseLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workerGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workerGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (ServerSettings.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password"); } try { var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); if (ServerSettings.UseLibuv) { bootstrap.Channel <TcpServerChannel>(); } else { bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("SRV-LSTN")) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast("tls", TlsHandler.Server(tlsCertificate)); } pipeline.AddLast(new LoggingHandler("SRV-CONN")); pipeline.AddLast("framing-enc", new LengthFieldPrepender(2)); pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); pipeline.AddLast("echo", new TestServerHandler()); })); IChannel boundChannel = await bootstrap.BindAsync(ServerSettings.Port); Console.ReadLine(); await boundChannel.CloseAsync(); } finally { await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } }
static async Task RunServerAsync() { Console.WriteLine( $"\n{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}" + $"\n{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}" + $"\nProcessor Count : {Environment.ProcessorCount}\n"); bool useLibuv = ServerSettings.UseLibuv; Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket")); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"Server garbage collection : {(GCSettings.IsServerGC ? "Enabled" : "Disabled")}"); Console.WriteLine($"Current latency mode for garbage collection: {GCSettings.LatencyMode}"); Console.WriteLine("\n"); IEventLoopGroup bossGroup; IEventLoopGroup workGroup; if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { //其实质是实例化一个SingleThreadEventLoop对象,负责接收新连接 bossGroup = new MultithreadEventLoopGroup(1); //其实质是实例化当前处理器*2个SingleThreadEventLoop对象,不断循环接收新消息 workGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (ServerSettings.IsSsl) { tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password"); } try { //声明一个服务端Bootstrap,每个Netty服务端程序,都由ServerBootstrap控制,通过链式的方式组装需要的参数 var bootstrap = new ServerBootstrap(); //设置主和工作线程组 bootstrap.Group(bossGroup, workGroup); if (useLibuv) { bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { //声明服务端通信通道为TcpServerSocketChannel bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Option(ChannelOption.SoBacklog, 8192) /* * ChannelInitializer 是一个特殊的处理类,他的目的是帮助使用者配置一个新的 Channel。 * 也许你想通过增加一些处理类比如DiscardServerHandler 来配置一个新的 Channel 或者其对应的ChannelPipeline 来实现你的网络程序。 * 当你的程序变的复杂时,可能你会增加更多的处理类到 pipline 上,然后提取这些匿名类到最顶层的类上。 */ .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { /* * 工作线程连接器是设置了一个管道,服务端主线程所有接收到的信息都会通过这个管道一层层往下传输, * 同时所有出栈的消息 也要这个管道的所有处理器进行一步步处理。 */ IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast(TlsHandler.Server(tlsCertificate)); } pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new HttpObjectAggregator(65536)); // 业务handler pipeline.AddLast(new WebSocketServerHandler()); })); int port = ServerSettings.Port; // bootstrap绑定到指定端口的行为就是服务端启动服务,同样的Serverbootstrap可以bind到多个端口 IChannel bootstrapChannel = await bootstrap.BindAsync(IPAddress.Loopback, port); Console.WriteLine("Open your web browser and navigate to " + $"{(ServerSettings.IsSsl ? "https" : "http")}" + $"://127.0.0.1:{port}/"); Console.WriteLine("Listening on " + $"{(ServerSettings.IsSsl ? "wss" : "ws")}" + $"://127.0.0.1:{port}/websocket"); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { workGroup.ShutdownGracefullyAsync().Wait(); bossGroup.ShutdownGracefullyAsync().Wait(); } }
static async Task RunServerAsync() { ExampleHelper.SetConsoleLogger(); // 申明一个主回路调度组 var dispatcher = new DispatcherEventLoopGroup(); /* * Netty 提供了许多不同的 EventLoopGroup 的实现用来处理不同的传输。 * 在这个例子中我们实现了一个服务端的应用,因此会有2个 NioEventLoopGroup 会被使用。 * 第一个经常被叫做‘boss’,用来接收进来的连接。第二个经常被叫做‘worker’,用来处理已经被接收的连接,一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。 * 如何知道多少个线程已经被使用,如何映射到已经创建的 Channel上都需要依赖于 IEventLoopGroup 的实现,并且可以通过构造函数来配置他们的关系。 */ // 主工作线程组,设置为1个线程 IEventLoopGroup bossGroup = dispatcher; // (1) // 子工作线程组,设置为1个线程 IEventLoopGroup workerGroup = new WorkerEventLoopGroup(dispatcher); try { // 声明一个服务端Bootstrap,每个Netty服务端程序,都由ServerBootstrap控制,通过链式的方式组装需要的参数 var serverBootstrap = new ServerBootstrap(); // (2) // 设置主和工作线程组 serverBootstrap.Group(bossGroup, workerGroup); if (ServerSettings.UseLibuv) { // 申明服务端通信通道为TcpServerChannel serverBootstrap.Channel <TcpServerChannel>(); // (3) } serverBootstrap // 设置网络IO参数等 .Option(ChannelOption.SoBacklog, 100) // (5) // 在主线程组上设置一个打印日志的处理器 .Handler(new LoggingHandler("SRV-LSTN")) // 设置工作线程参数 .ChildHandler( /* * ChannelInitializer 是一个特殊的处理类,他的目的是帮助使用者配置一个新的 Channel。 * 也许你想通过增加一些处理类比如DiscardServerHandler 来配置一个新的 Channel 或者其对应的ChannelPipeline 来实现你的网络程序。 * 当你的程序变的复杂时,可能你会增加更多的处理类到 pipline 上,然后提取这些匿名类到最顶层的类上。 */ new ActionChannelInitializer <IChannel>( // (4) channel => { /* * 工作线程连接器是设置了一个管道,服务端主线程所有接收到的信息都会通过这个管道一层层往下传输, * 同时所有出栈的消息 也要这个管道的所有处理器进行一步步处理。 */ IChannelPipeline pipeline = channel.Pipeline; // 添加日志拦截器 pipeline.AddLast(new LoggingHandler("SRV-CONN")); // 添加出栈消息,通过这个handler在消息顶部加上消息的长度。 // LengthFieldPrepender(2):使用2个字节来存储数据的长度。 pipeline.AddLast("framing-enc", new LengthFieldPrepender(2)); /* * 入栈消息通过该Handler,解析消息的包长信息,并将正确的消息体发送给下一个处理Handler * 1,InitialBytesToStrip = 0, //读取时需要跳过的字节数 * 2,LengthAdjustment = -5, //包实际长度的纠正,如果包长包括包头和包体,则要减去Length之前的部分 * 3,LengthFieldLength = 4, //长度字段的字节数 整型为4个字节 * 4,LengthFieldOffset = 1, //长度属性的起始(偏移)位 * 5,MaxFrameLength = int.MaxValue, //最大包长 */ pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); // 业务handler pipeline.AddLast("echo", new EchoServerHandler()); })); // bootstrap绑定到指定端口的行为就是服务端启动服务,同样的Serverbootstrap可以bind到多个端口 IChannel boundChannel = await serverBootstrap.BindAsync(ServerSettings.Port); // (6) Console.WriteLine("wait the client input"); Console.ReadLine(); // 关闭服务 await boundChannel.CloseAsync(); } finally { // 释放指定工作组线程 await Task.WhenAll( // (7) bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)) ); } }
public async Task RunServerAsync(ServerConfigModel configModel) { Console.WriteLine("WebSocket服务器启动"); Console.WriteLine( $"系统版本:{RuntimeInformation.OSArchitecture} {RuntimeInformation.OSDescription}\r\n" + $".NET版本:{RuntimeInformation.ProcessArchitecture} {RuntimeInformation.FrameworkDescription}\r\n" + $"CPU核心数:{Environment.ProcessorCount}"); Console.WriteLine("传输类型:" + (configModel.UserLibuv ? "Libuv" : "Socket")); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } Console.WriteLine($"服务器垃圾回收机制:{(GCSettings.IsServerGC ? "启用" : "禁用")}"); Console.WriteLine($"垃圾回收延迟模式:{GCSettings.LatencyMode}"); IEventLoopGroup bossGroup; IEventLoopGroup workGroup; if (configModel.UserLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } X509Certificate2 tlsCertificate = null; if (configModel.IsSsl) { tlsCertificate = new X509Certificate2(configModel.CertificatePath, configModel.CertificatePassword); } try { var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workGroup); if (configModel.UserLibuv) { bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap.Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap.Option(ChannelOption.SoBacklog, 8192) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast(TlsHandler.Server(tlsCertificate)); } pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new HttpObjectAggregator(65536)); if (configModel.ServerHandler is BaseDotNettyServerHandler serverHandler) { pipeline.AddLast(serverHandler); } })); IPAddress iPAddress = IPAddress.Parse(configModel.Host); IChannel bootstrapChannel = await bootstrap.BindAsync(iPAddress, configModel.Port); Console.WriteLine("打开你的浏览器跳转到:" + $"{(configModel.IsSsl ? "https" : "http")}" + $"://{iPAddress}:{configModel.Port}/api"); Console.WriteLine("监听中:" + $"{(configModel.IsSsl ? "wss" : "ws")}" + $"://{iPAddress}:{configModel.Port}/websocket"); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { workGroup.ShutdownGracefullyAsync().Wait(); bossGroup.ShutdownGracefullyAsync().Wait(); } }
public static async Task RunServerAsync(IConfigurationRoot config) { bool useLibuv = true; Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket")); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; } IEventLoopGroup bossGroup; IEventLoopGroup workGroup; if (useLibuv) { var dispatcher = new DispatcherEventLoopGroup(); bossGroup = dispatcher; workGroup = new WorkerEventLoopGroup(dispatcher); } else { bossGroup = new MultithreadEventLoopGroup(1); workGroup = new MultithreadEventLoopGroup(); } try { var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workGroup); if (useLibuv) { bootstrap.Channel <TcpServerChannel>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } } else { bootstrap.Channel <TcpServerSocketChannel>(); } bootstrap .Option(ChannelOption.SoBacklog, 8192) .ChildHandler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast("SocketChoose", new SocketChooseHandler()); pipeline.AddLast("TCPHandler", new EchoServerHandler()); pipeline.AddLast(new HttpServerCodec()); pipeline.AddLast(new HttpObjectAggregator(65536)); pipeline.AddLast("WebSocketHandler", new WebSocketServerHandler()); })); int port = string.IsNullOrEmpty(config.GetSection("WebSocket")["port"]) ? 4321 : Convert.ToInt32(config.GetSection("WebSocket")["port"]); IPAddress ip = IPAddress.Parse("0.0.0.0"); Console.WriteLine(ip.ToString() + ":" + port.ToString()); IChannel bootstrapChannel = await bootstrap.BindAsync(ip, port); Console.WriteLine("WebSocket Starting"); while (true) { } } finally { workGroup.ShutdownGracefullyAsync().Wait(); bossGroup.ShutdownGracefullyAsync().Wait(); } }