Esempio n. 1
0
        static async Task RunClientAsync()
        {
            UsualHelper.SetConsoleLogger();

            var group = new MultithreadEventLoopGroup();

            X509Certificate2 cert       = null;
            string           targetHost = null;

            if (ClientSettings.IsSsl)
            {
                cert       = new X509Certificate2(Path.Combine(UsualHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
                targetHost = cert.GetNameInfo(X509NameType.DnsName, false);
            }
            try
            {
                var bootstrap = new Bootstrap();
                bootstrap
                .Group(group)
                .Channel <TcpSocketChannel>()
                .Option(ChannelOption.TcpNodelay, true)
                .Handler(new ActionChannelInitializer <ISocketChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;

                    if (cert != null)
                    {
                        pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost)));
                    }
                    pipeline.AddLast(new LoggingHandler());
                    pipeline.AddLast("framing-enc", new LengthFieldPrepender(2));
                    pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));

                    pipeline.AddLast("echo", new WorkClientHandler());
                }));

                IChannel clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(ClientSettings.Host, ClientSettings.Port));

                Console.ReadLine();

                await clientChannel.CloseAsync();
            }
            finally
            {
                await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }
Esempio n. 2
0
        public static async Task RunServerAsync()
        {
            //设置输出日志到Console
            UsualHelper.SetConsoleLogger();

            // 主工作线程组,设置为1个线程
            var bossGroup = new MultithreadEventLoopGroup(1);

            // 工作线程组,默认为内核数*2的线程数
            var workerGroup = new MultithreadEventLoopGroup();
            X509Certificate2 tlsCertificate = null;

            if (SevSettings.IsSsl) //如果使用加密通道
            {
                tlsCertificate = new X509Certificate2(Path.Combine(UsualHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
            }
            try
            {
                //声明一个服务端Bootstrap,每个Netty服务端程序,都由ServerBootstrap控制,
                //通过链式的方式组装需要的参数

                var bootstrap = new ServerBootstrap();
                bootstrap
                .Group(bossGroup, workerGroup)           // 设置主和工作线程组
                .Channel <TcpServerSocketChannel>()      // 设置通道模式为TcpSocket
                .Option(ChannelOption.SoBacklog, 100)    // 设置网络IO参数等,这里可以设置很多参数,当然你对网络调优和参数设置非常了解的话,你可以设置,或者就用默认参数吧
                .Handler(new LoggingHandler("SRV-LSTN")) //在主线程组上设置一个打印日志的处理器
                .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel =>
                {
                    //工作线程连接器 是设置了一个管道,服务端主线程所有接收到的信息都会通过这个管道一层层往下传输
                    //同时所有出栈的消息 也要这个管道的所有处理器进行一步步处理
                    var pipeline = channel.Pipeline;
                    if (tlsCertificate != null)     //Tls的加解密
                    {
                        pipeline.AddLast("tls", TlsHandler.Server(tlsCertificate));
                    }
                    //日志拦截器
                    pipeline.AddLast(new LoggingHandler("SRV-CONN"));

                    //出栈消息,通过这个handler 在消息顶部加上消息的长度
                    pipeline.AddLast("framing-enc", new LengthFieldPrepender(2));

                    //入栈消息通过该Handler,解析消息的包长信息,并将正确的消息体发送给下一个处理Handler,该类比较常用,后面单独说明
                    pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));

                    //业务handler ,这里是实际处理Echo业务的Handler
                    pipeline.AddLast("echo", new WorkServerHandler());
                }));

                // bootstrap绑定到指定端口的行为 就是服务端启动服务,同样的Serverbootstrap可以bind到多个端口
                var boundChannel = await bootstrap.BindAsync(SevSettings.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)));
            }
        }