Channel
Channel的常用方法
close()
关闭channelcloseFuture()
处理关闭channel后要执行的操作sync()
方法是同步等待channel的关闭addListener()
方法是异步等待channel的关闭
pipeline()
添加处理器write()
将数据写入,netty里面其实还有一个缓冲区,当我们执行flush()方法后或者是缓冲区中数据达到一个数量了就会将缓冲区的数据发送出去writeAndFlush()
将数据写入并刷出
ChannelFuture
解决客户端连接服务器 connect()方法 异步非阻塞 问题
一个普通netty客户端的代码如下
public class HelloClient2 {
public static void main(String[] args) throws InterruptedException {
ChannelFuture channelFuture = new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new StringEncoder());
}
})
// 连接服务器 该方法返回的就是ChannelFuture
.connect("localhost", 8080);
// 这个sync()方法必须调用,如果不调用直接运行的话,下面发送给服务器的数据没有发送成功
channelFuture.sync();
Channel channel = channelFuture.channel();
channel.writeAndFlush("aaa");
}
}
为什么调用该方法channelFuture.sync();
就能发送数据成功嘞?
这是因为上面一行连接服务器的代码.connect("localhost", 8080);
该方法是异步非阻塞的,主线程发起了连接服务器的操作,但是连接服务器是NioEventLoopGroup中的一个线程执行,如果不调用sync()方法就会出现还没有连接成功服务器,就执行了获取channel的语句并通过获取的channel发送数据,
以后我们看到Future 或者是 Promise 的类型都是和异步方法配套使用的,他俩的用途就是正确处理结果
上面出现了问题,解决方法也有几种:
-
第一种就是调用ChannelFuture类中的sync()方法,主线程就会阻塞,当客户端与服务器连接成功后才会往下面执行,
-
第二种解决 调用addListener() 异步处理结果
public static void main(String[] args) throws InterruptedException {
ChannelFuture channelFuture = new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new StringEncoder());
}
})
// 连接服务器 该方法返回的就是ChannelFuture 该方法是异步非阻塞的
.connect("localhost", 8080);
// 第一种解决方法,方法同步处理结果,这里阻塞住,等客户端与服务器连接成功后在往下执行
// channelFuture.sync();
// Channel channel = channelFuture.channel();
// channel.writeAndFlush("aaa");
// 第二种解决 调用addListener() 异步处理结果,上面的同步处理结果是主线程等另一个线程连接成功后再自己拿到连接成功的结果channel
// 然后自己发送数据。而这里的异步是主线程完全就是甩手掌柜,通过channel发送数据也让其他线程来做,主线程只是提供一个回调对象
// 当客户端与服务器连接成功后,EventLoop会自动调用ChannelFutureListener对象中的operationComplete()方