理解Netty中的回调与Future

回调

回调理解起来很简单,在Netty中,如下即是回调:

1
2
3
4
5
6
7
8

public class ConnectHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Client " + ctx.channel().remoteAddress() + " connected.");
    }
}

Netty在内部使用了回调来处理事件,当一个回调被触发时,相关的事件可以被ChannelHandler的实现处理。

Future

Future提供了另一种在操作完成时通知应用程序的方式。这个对象可以看做是一个异步操作的结果的占位符,它将在未来的某个时刻完成,并提供对其结果的访问。

JDK内置的Future接口只允许手动检查对应的操作是否已经完成,或者一直阻塞直到它完成。这样很繁琐,所以Netty提供了自己的实现ChannelFuture,用于在执行异步操作的时候使用。

每个Netty的出站IO操作都将返回一个ChannelFuture。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

Channel channel = ...;
channel.connect(ADDRESS, PORT).addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
        if (future.isSuccess()) {
            ByteBuf buf = Unpooled.copiedBuffer("Hello", StandardCharsets.UTF_8);
            // writeAndFlush这个IO操作又产生了一个ChannelFuture
            ChannelFuture channelFuture1 = future.channel().writeAndFlush(buf);
        } else {
            Throwable cause = future.cause();
            cause.printStackTrace();
        }
    }
});

(这块代码有两点需要注意:1.不是用Bootstrap进行Connect,而是用Channel,这种写法我从来没用过;2.我第一次在ChannelFutureListener中处理异常)