一.入门
1.前言
NIO跟BIO最大的区别是,NIO有管道(channel)的概念,开启一个管道,传送一批数据,管道里面的Selector充当列车的角色,这个列车来回传输数据。
之所以选用netty,主要原因是因为使用简单,入门快,可以保证在开发的过程中保证项目的稳定以及扩展。
2.入门基础代码
2.1 启动类
首先需要定义一个启动类,netty主要启动代码为
serverBootstrap.group(mainGrp,subGrp)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new WebSocketChanneInit());这个方法需要三个参数,也是最基本的参数,首先是需要指定现场池,然后是通道的类型,指定完这两个之后需要定义一个通道初始化类,用来加载当通道接收到消息后的业务处理
//创建两个线程池
        NioEventLoopGroup mainGrp = new NioEventLoopGroup();
        NioEventLoopGroup subGrp = new NioEventLoopGroup();
        try {
            //创建netty服务器启动对象
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //初始化服务启动对象
            serverBootstrap.group(mainGrp,subGrp)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new WebSocketChanneInit());
            //绑定服务器端口(同步的方式)
            ChannelFuture future = serverBootstrap.bind(9001).sync();
            //等待服务器关闭
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //关闭
            mainGrp.shutdownGracefully();
            subGrp.shutdownGracefully();
        }2.2通道初始化器(处理webSocket)
public class WebSocketChanneInit extends ChannelInitializer<SocketChannel> {
    //初始化通道
    //在这个方法加载对应的channelHandler
    protected void initChannel(SocketChannel ch) throws Exception {
        //获取管道
        ChannelPipeline pipeline = ch.pipeline();
        //添加一个http解码器
        pipeline.addLast(new HttpServerCodec());
        //添加一个用于大数据流的支持
        pipeline.addLast(new ChunkedWriteHandler());
        //添加一个聚合器
        pipeline.addLast(new HttpObjectAggregator(1024 * 64));
        //需要指定接收请求的路由,必须使用ws后缀结尾的url才能进行访问
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        //添加自定义的handler
        pipeline.addLast(new ChatHandler());
    }
}2.3 自定义Handler(处理业务)
 private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
//当接收到数据后会自动调用
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //获取客服端文本消息
        String text = msg.text();
        System.out.println("接收到客户端的消息:"+text);
        for (Channel client: clients ) {
            //将消息发送到所有的客户端
            client.writeAndFlush(new TextWebSocketFrame(sdf.format(new Date()) + "接收到消息: "+text ));
        }
    }
//当有新的客户端连接后会自动调用这个方法
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        //将新的通道放入到clients中
        clients.add(ctx.channel());
    }









