netty学习 -- Channel

netty学习 -- Channel

  • Channel
    • write()
    • ChannelFuture连接问题sync()和addListener()方法说明
      • sync()
      • addListener()
    • closeFuture()关闭

Channel

channel的主要作用

  • close()关闭channel
  • closeFuture()来处理channel的关闭
  • sync()方法等待异步就结束
  • addListener()方法增加回调操作
  • pipeline()方法添加处理器
  • write()方法写入
  • writeAndFlush()方法将数据写入并刷出

write()

HelloServer 服务端

@Slf4j(topic = "w.Test1")
public class HelloServer {
     
    public static void main(String[] args) {
     
        // 创建启动器
        new ServerBootstrap()
                // 创建EventLoop事件监听处理组
                .group(new NioEventLoopGroup())
                // 设置ServerSocketChannel的实现NioServerSocketChannel
                .channel(NioServerSocketChannel.class)
                // 设置处理器
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        // 添加处理工序 处理stringBuf为字符串
                        ch.pipeline().addLast(new StringDecoder());
                        // 自定义处理器
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
     
                            // 监听读时间
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
     
                                // 打印上一步转换好的字符串
                                log.debug((String) msg);
                            }
                        });
                    }
                }).bind(8080); // 绑定的监听端口
    }
}

HelloClient 客户端

@Slf4j(topic = "w.Test1")
public class HelloClient {
     
    public static void main(String[] args) throws InterruptedException {
     
        //1 启动类
        new Bootstrap()
                // 2.添加EventLoop
                .group(new NioEventLoopGroup())
                // 3.选择客服端channel实现
                .channel(NioSocketChannel.class)
                // 4 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        ch.pipeline().addLast(new StringEncoder());
                    }
                    // 连接地址
                }).connect(new InetSocketAddress("127.0.0.1", 8080))
                .sync()
                .channel()
                .write("hello world");
    }
}

都运行起来发现服务端并没有收到发送的"hello world"
netty学习 -- Channel_第1张图片
write方法本身是吧数据写入缓存去区中去了,并没有刷出,修改方法为writeAndFlush()
netty学习 -- Channel_第2张图片
netty学习 -- Channel_第3张图片
发现服务端正确的收到了发送的数据

ChannelFuture连接问题sync()和addListener()方法说明

sync()

netty学习 -- Channel_第4张图片

把上面代码的sync去掉,再重新跑起来发现没有办法服务端没有办法正确接收信息了
netty学习 -- Channel_第5张图片
发送的"hello world"并没有正确打印,这是因为建立连接和发送数据并不是一个线程,他们异步了,主线程不会等待工作线程的连接建立,当工作线程开始去建立连接时,main线程都已经把数据都发了,这时main线程就相当于发了个寂寞
netty学习 -- Channel_第6张图片
而用sync()会一直阻塞到连接的建立这时再去发送数据就没得问题了
netty学习 -- Channel_第7张图片
netty学习 -- Channel_第8张图片

addListener()

addListener添加一个回调方法在回调方法里面执行发送数据也是没有问题的

@Slf4j
public class HelloClient {
     
    public static void main(String[] args) throws InterruptedException {
     
        //1 启动类
        ChannelFuture connect = new Bootstrap()
                // 2.添加EventLoop
                .group(new NioEventLoopGroup())
                // 3.选择客服端channel实现
                .channel(NioSocketChannel.class)
                // 4 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        ch.pipeline().addLast(new StringEncoder());
                    }
                    // 连接地址
                }).connect(new InetSocketAddress("127.0.0.1", 8080));
//                .sync()
//                .channel()
//                .writeAndFlush("hello world");
        connect.addListener(new ChannelFutureListener() {
     
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
     
                Channel channel = channelFuture.channel();
                log.debug("连接完成{}", channel);
                channel.writeAndFlush("hello world");
            }
        });
    }
}

相当于我们给了一个回调函数,当工作线程建立连接后,在由它来调用operationComplete方法来执行发送

closeFuture()关闭

同步

@Slf4j
public class HelloClient {
     
    public static void main(String[] args) throws InterruptedException {
     
      NioEventLoopGroup group = new NioEventLoopGroup();
        //1 启动类
        ChannelFuture connect = new Bootstrap()
                // 2.添加EventLoop
                .group(group)
                // 3.选择客服端channel实现
                .channel(NioSocketChannel.class)
                // 4 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        ch.pipeline().addLast(new StringEncoder());
                    }
                    // 连接地址
                }).connect(new InetSocketAddress("127.0.0.1", 8080))
                // 同步关闭客户端
                .sync()
                .channel()
                .writeAndFlush("hello world") // 发送数据
                .sync()  // 等待数据发送完毕
                .channel() // 拿到channel
                .close()// 关闭他
                .channel()// 拿到channel
                .closeFuture()// 拿到closeFuture
                .sync(); // 等待关闭
        log.debug("关闭客户端");
        // 关闭线程组
        group.shutdownGracefully();
    }
}

成功关闭
netty学习 -- Channel_第9张图片
服务端也没有报错
在这里插入图片描述

异步关闭

@Slf4j
public class HelloClient {
     
    public static void main(String[] args) throws InterruptedException {
     
        NioEventLoopGroup group = new NioEventLoopGroup();
        //1 启动类
        ChannelFuture connect = new Bootstrap()
                // 2.添加EventLoop
                .group(group)
                // 3.选择客服端channel实现
                .channel(NioSocketChannel.class)
                // 4 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        ch.pipeline().addLast(new StringEncoder());
                    }
                    // 连接地址
                }).connect(new InetSocketAddress("127.0.0.1", 8080))
                // 同步关闭客户端
                .sync()
                .channel()
                .writeAndFlush("hello world") // 发送数据
                .sync()  // 等待数据发送完毕
                .channel() // 拿到channel
                .close()// 关闭他
                .channel()// 拿到channel
                .closeFuture();
        connect.addListener(new ChannelFutureListener() {
     
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
     
                log.debug("关闭客户端");
                // 关闭线程组
                group.shutdownGracefully();
            }
        });
    }
}

你可能感兴趣的:(笔记,java,netty)