美文网首页
netty4.x使用详解

netty4.x使用详解

作者: 左洁 | 来源:发表于2019-12-06 14:34 被阅读0次

    1.环境

    • jdk11
    • netty 4.1.43.Final

    1.1介绍

    netty是异步事件驱动网络框架,提供快速开发高性能和高可靠网络协议服务和客户端,官网地址 ,

    netty底层实现采用nio实现,所以必须了解selector模型

    2 nio流程图

    nio流程图.png

    服务端:

    selector线程:监听socket事件,例如连接事件 可读事件等

    服务端channel :处理客户连接和读写请求,和selector是不同线程,两者异步处理各自业务

    客户端:

    channel直接连接服务器

    3.EventLoopGroup和线程池模型

    eventLoop.png

    EventLoopGroup继承ScheduledExecutorService接口,增强了jdk并发包下线程池功能,NioEventLoopGroup默认线程大小NettyRuntime.availableProcessors() * 2 ,线程池处理IO任务

    EventLoopGroup2.png

    一旦一个channel被分配个一个EventLoop,它将在他的整个生命周期都使用整个EventLoop(以及相关联的Thread),请记住这一点,因为它可以使你从担忧你的channelHandler实现中的线程安全和同步问题解脱出来

    4.服务端ServerBootstrap引导类

    服务端代码片段

    EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap(); // (2)
    
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class) // (3)
                        .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                            @Override
                            public void initChannel(SocketChannel ch) throws Exception {
                                ch.pipeline().addLast(new DiscardServerHandler());
                            }
                        })
                        .option(ChannelOption.SO_BACKLOG, 128)          // (5)
                        .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
    
                // 绑定和接受请求
                ChannelFuture f = b.bind(port).sync(); // (7)
    
              
                // 关闭
                f.channel().closeFuture().sync();
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
    
    ServerBootstrap流程图.png

    5下面案例分析

    服务端代码

    ……………………   
    public void run() throws Exception {
            // (1)创建处理serverChannel线程池
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            //创建处理连接线程池
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                // (2)创建服务端引导类
                ServerBootstrap b = new ServerBootstrap();
    
                //设置父子线程池关系
                b.group(bossGroup, workerGroup)
                        // (3)服务端使用selector模型
                        .channel(NioServerSocketChannel.class)
                        // (4)设置处理channel管道数据handler
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch) throws Exception {
                                ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
                                ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
                                ch.pipeline().addLast(new DiscardServerHandler());
    
                            }
                        })
                        // (5)
                        .option(ChannelOption.SO_BACKLOG, 128)
                        // (6)
                        .childOption(ChannelOption.SO_KEEPALIVE, true);
    
                 //(7) 绑定和等待接收请求
                ChannelFuture f = b.bind(port).sync();
    
    
                // (8)关闭channel
                f.channel().closeFuture().sync();
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        }
    ………………
    

    客户端代码

    public class DiscardClient {
        public static void main(String[] args) {
            //创建发送数据线程池
            EventLoopGroup group = new NioEventLoopGroup();
            //设置客户端引导类
            Bootstrap bootstrap = new Bootstrap();
    
    
            bootstrap.group(group).
                    //设置selector模型
                    channel(NioSocketChannel.class).
                    //添加处理连接请求handler
                    handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
                            ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
                            ch.pipeline().addLast(new DiscardClientHandler());
                        }
                    });
    
            //设置请求连接配置
            ChannelFuture future = bootstrap.connect(new InetSocketAddress("127.0.0.1",8088));
    
            future.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                        if (future.isSuccess()){
                            System.out.println("connn estable");
                        }else {
                            System.out.println("connn faild");
                            future.cause().printStackTrace();
                        }
                }
            });
        }
    }
    

    源码地址

    相关文章

      网友评论

          本文标题:netty4.x使用详解

          本文链接:https://www.haomeiwen.com/subject/ulhegctx.html