private async Task RunServerAsync() { var bossGroup = new MultithreadEventLoopGroup(1); var workerGroup = new MultithreadEventLoopGroup(); try { var bootstrap = new ServerBootstrap(); bootstrap .Group(bossGroup, workerGroup) .Channel <TcpServerSocketChannel>() .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel => { var pipeline = channel.Pipeline; _channelGroup.Add(channel); _channels.Add(channel.Id.AsLongText(), channel); pipeline.AddLast(new LengthFieldBasedFrameDecoder(ByteOrder.BigEndian, ushort.MaxValue, 0, 2, 0, 2, true)); pipeline.AddLast(new LengthFieldPrepender(ByteOrder.BigEndian, 2, 0, false)); pipeline.AddLast(new SoupBinTcpMessageDecoder()); pipeline.AddLast(new SoupBinTcpMessageEncoder()); pipeline.AddLast("LoginRequestFilter", new LoginRequestFilterHandler()); pipeline.AddLast(new IdleStateHandler(15, 1, 0)); pipeline.AddLast(new ServerTimeoutHandler(Listener)); pipeline.AddLast("ServerHandshake", new ServerHandshakeHandler(Listener)); })); _serverChannel = await bootstrap.BindAsync(5500); await Listener.OnServerListening(); _cancellationToken.WaitHandle.WaitOne(); if (_serverChannel.Active) { await _channelGroup.WriteAndFlushAsync(new LogoutRequest()); await _serverChannel.CloseAsync(); } await Listener.OnServerDisconnect(); } finally { await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } }
private async Task RunServerAsync() { var bossGroup = new MultithreadEventLoopGroup(1); var workerGroup = new MultithreadEventLoopGroup(); try { var bootstrap = new ServerBootstrap(); bootstrap .Group(bossGroup, workerGroup) .Channel <TcpServerSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.SoKeepalive, true) .Option(ChannelOption.SoReuseaddr, true) .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel => { var pipeline = channel.Pipeline; _channelGroup.Add(channel); _channels.Add(channel.Id.AsLongText(), channel); pipeline.AddLast( new LengthFieldBasedFrameDecoder(byteOrder: ByteOrder.BigEndian, maxFrameLength: ushort.MaxValue, lengthFieldOffset: 0, lengthFieldLength: 2, lengthAdjustment: 0, initialBytesToStrip: 2, failFast: true)); pipeline.AddLast( new LengthFieldPrepender(byteOrder: ByteOrder.BigEndian, lengthFieldLength: 2, lengthAdjustment: 0, lengthFieldIncludesLengthFieldLength: false)); pipeline.AddLast(new SoupBinTcpMessageDecoder()); pipeline.AddLast(new SoupBinTcpMessageEncoder()); pipeline.AddLast("LoginRequestFilter", new LoginRequestFilterHandler()); pipeline.AddLast( new IdleStateHandler( readerIdleTimeSeconds: 15, writerIdleTimeSeconds: 1, allIdleTimeSeconds: 0)); pipeline.AddLast(new ServerTimeoutHandler(Listener)); pipeline.AddLast("ServerHandshake", new ServerHandshakeHandler(Listener)); })); _serverChannel = await bootstrap.BindAsync(5500); await Listener.OnServerListening(); // Wait here _cancellationToken.WaitHandle.WaitOne(); if (_serverChannel.Active) { await _channelGroup.WriteAndFlushAsync(new LogoutRequest()); await _serverChannel.CloseAsync(); } await Listener.OnServerDisconnect(); } finally { await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } }