实现ChannelOutboundHandlerAdapter需要注意的点

1
2
3
4
5
6
7
8
9

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    UnixTime m = (UnixTime) msg;
    ByteBuf encode = ctx.alloc().buffer(4);
    encode.writeInt((int) m.value);
    ctx.write(encode, promise);
}

几点需要注意的地方:

  1. 调用ctx的write方法时需要将promise传递过去,我分析如果不传递的话,可能上一层的handler永远得不到通知

  2. 可以不用调用flush方法,因为ChannelOutboundHandlerAdapter中有如下方法(有点不理解,为什么可以不调用了,那谁在调用呢):

1
2
3
4
5
6
7

@Skip
@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
    ctx.flush();
}

测试不传递promise会怎样

代码如下,最终结果和我分析的一致:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

BootstrapUtils.runServer(new ChannelInitializer<SocketChannel>() {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ch.pipeline()
                .addLast(new ChannelOutboundHandlerAdapter() {
                    @Override
                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                        ctx.write(msg, promise);
                        System.out.println(promise);
                    }
                })
                .addLast(new ChannelOutboundHandlerAdapter() {
                    @Override
                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                        ctx.write(msg, promise);
                        System.out.println(promise);
                    }
                })
                .addLast(new ChannelInboundHandlerAdapter() {
                    @Override
                    public void channelActive(ChannelHandlerContext ctx) throws Exception {
                        ByteBuf buffer = ctx.alloc().buffer(4);
                        buffer.writeInt(100);
                        ChannelFuture channelFuture = ctx.writeAndFlush(buffer).addListener(new ChannelFutureListener() {
                            @Override
                            public void operationComplete(ChannelFuture future) throws Exception {
                                System.out.println("Write Success");
                            }
                        });
                        System.out.println(channelFuture);
                    }
                });

    }
});

而且在实验的过程中发现,InboundHandlerAdater中调用writeAndFlush得到的ChannelFuture和各个ChannelOutboundHandlerAdapter中的write方法中的promise参数是同一个对象。