Netty服务端Server代码说明

本文是简单的Netty启动服务端代码理解笔记

public class MyServer {
    public static void main(String[] args) throws Exception{
        //创建两个线程组,Boss用来接收,Worke用来处理已经建立连接的Channel
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //默认8个NioEventLoop CPU核心*2
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //创建一个服务端启动器
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //为服务端启动器指定两个时间循环组(NIOEventGroup),前者用来Accept,后者处理已经连接的Channel
            serverBootstrap.group(bossGroup, workerGroup);
            //为服务端指定ServerSocketChannel的类型是NioServerSocketChannel
            serverBootstrap.channel(NioServerSocketChannel.class);
            //handler是指为BossGroup添加处理程序
            serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));
            //childhandler是指WorkGroup,也就是为处理事件循环组添加处理方法,在这儿添加了一个Channel(通道)初始化器
            //这个初始化器主要是传递SocketChannel
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            //得到这个传递进来的SocketChannel之后,获取它的管道,这个管道本质是一个双向链表
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline pipeline = ch.pipeline();
                    //加入一个netty 提供 IdleStateHandler
                    /*
                    说明
                    1. IdleStateHandler 是netty 提供的处理空闲状态的处理器
                    2. long readerIdleTime : 表示多长时间没有读, 就会发送一个心跳检测包检测是否连接
                    3. long writerIdleTime : 表示多长时间没有写, 就会发送一个心跳检测包检测是否连接
                    4. long allIdleTime : 表示多长时间没有读写, 就会发送一个心跳检测包检测是否连接
                    5. 文档说明
                    triggers an {@link IdleStateEvent} when a {@link Channel} has not
                     performed
                     read, write, or both operation for a while.

                     6. 当 IdleStateEvent 触发后 , 就会传递给管道 的下一个handler去处理
                       通过调用(触发)下一个handler 的 userEventTiggered , 在该方法中去处理 IdleStateEvent(读空闲,写空闲,读写空闲)
                    */
                    pipeline.addLast(new IdleStateHandler(7000,7000,10, 					 								TimeUnit.SECONDS));
                    //加入一个对空闲检测进一步处理的handler(自定义)
                    pipeline.addLast(new MyServerHandler());
                }
            });
            //启动服务器,指定端口并且阻塞运行等待结果
            ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
public class MyServerHandler extends ChannelInboundHandlerAdapter {
    /**
     * @param ctx 上下文
     * @param evt 事件
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //userEventTriggered  用户事件触发
        if(evt instanceof IdleStateEvent) {
            //将  evt 向下转型 IdleStateEvent
            IdleStateEvent event = (IdleStateEvent) evt;
            String eventType = null;
            switch (event.state()) {
                case READER_IDLE:
                    eventType = "读空闲";
                    break;
                case WRITER_IDLE:
                    eventType = "写空闲";
                    break;
                case ALL_IDLE:
                    eventType = "读写空闲";
                    break;
            }
            System.out.println(ctx.channel().remoteAddress() + "--超时时间--" + eventType);
            System.out.println("服务器做相应处理..");
            //如果发生空闲,我们关闭通道
            // ctx.channel().close();
        }
    }
}
posted @ 2021-01-10 21:19  等不到的口琴  阅读(405)  评论(0编辑  收藏  举报