2.启动netty服务器流程
EventLoopGroup bossGroup = new NioEventLoopGroup();//bossGroup线程池用来接受客户端的连接请求 EventLoopGroup workerGroup = new NioEventLoopGroup();//workerGroup线程池用来处理boss线程池里面的连接的数据 try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new StringDecoder());//设置服务器端的编码和解码 pipeline.addLast(new StringEncoder()); pipeline.addLast(new ServerMessageHandler());//服务器接收到的数据逻辑类 } }); );//ChannelInitializer是一个特殊的handler,用来初始化ChannelPipeline里面的handler链.这个特殊的ChannelInitializer在加入到pipeline后,在initChannel调用结束后,自身会被remove掉,从而完成初始化的效果. b.option(ChannelOption.SO_KEEPALIVE, true);//设置长连接 b.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT);//动态设置数组大小 b.childOption(ChannelOption.SO_BACKLOG, 128); ChannelFuture channelFuture = b.bind(8080).sync(); channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } NioEventLoopGroup初始化 当NioEventLoopGroup构造方法被调用时,首先初始化父类MultithreadEventLoopGroup,触发父类获得默认的线程数,其值默认是Runtime.getRuntime().availableProcessors() * 2 主要任务:创建NioEventLoopGroup对象 获得默认线程池数目大小,数值为N 设置线程池名称和线程名称 循环创建出来 N个NioEventLoop对象,每个NioEventLoop都设置了相同的parent,executor和不同的selector实例,可以同时并发处理成百上千个客户端Channel,由于读写操作都是非阻塞的,这就可以充分提升IO线程的运行效率,避免由于频繁IO阻塞导致的线程挂起. 当进行Socket IO读写的时候,为了避免从堆内存拷贝一份副本到直接内存,Netty的ByteBuf分配器直接创建非堆内存避免缓冲区的二次拷贝,通过“零拷贝”来提升读写性能。 ServerBootstrap 初始化 ServerBootstrap b = new ServerBootstrap(); 设置group属性是bossGroup,childGroup属性是workerGroup.最主要值得一提的是channel方法的设计,通过传递class对象,然后通过反射来实例化具体的Channel实例. childHandler这个方法是处理客户端的关键回调方法当有客户端链接的时候都先回调此ChannelInitializer下的方法方法(客户端链接从此开始)走进ServerMessageHandler(SimpleChannelInboundHandler<Object>)三个主要方法 1 channelRead 处理客户端发送过来的数据 2 channelInactive 监听客户端断开链接的消息 3 channelActive 客户端启动时执行的方法 ChannelFuture主要职责是:future上面addListener添加监听器或者相对应的返回结果后调用相对应的处理方法.因为netty是异步的,一般所有的IO操作会执行之后会马上返回,而不是像是阻塞IO一样一直等待,知道返回结果. channelfuture主要解决:NIO操作完成之后会回调,并且修改channelFuture的值,而值一旦被修改,就是状态的变更,那么就能获取到返回的结果,这时候触发相对应的监听器. pipeline.addLast(ObjectHandler())启动新线程维护此handler维护长连接的心跳包即可在此处添加. 客户端的创建和服务器大多相似,但是客户端的SocketChannel没有父channel的概念所以不需要使用childOption方法. 加密解密的Decoder和Encoder均可自定义哦.