Handler和pipeline
我们会将多个Handler添加进pipeline中,Handler主要分为两类,入站和出站。需要注意的就是多个handler的执行顺序、入站Handler需要将处理后的消息传递给下一个入站Handler,出站Handler需要触发可写事件再回执行。
- 入站处理器通常是ChannelInboundHandlerAdapter的子类,主要用来读取客户端数据
- 出站处理器通常是ChannelOutboundHandlerAdapter的子类,主要用于对写回数据加工
执行顺序
假如我现在的Pipeline是如下所示:
hear -> h1 -> h2 -> h3 -> h4 -> h5 -> h6 -> tail
h1 h2 h3 是入站 h4 h5 h6 是出站 ; 那么当客户端连接服务器后,客户端往服务器发送数据,服务器并往客户端写回数据,handler的执行顺序就是 h1 -> h2 -> h3 -> h6 -> h5 -> h4 如果是入站,handler的执行顺序会按照我们添加的循序来,出站正好相反。
服务器往客户端写回数据才会触发执行出站的handler,如果没有写操作,出站的handler是不会执行的。
上面的hear -> h1 -> h2 -> h3 -> h4 -> h5 -> h6 -> tail 执行器链 底层其实是双向链表。
例如如下代码
public static void main(String[] args) {
new ServerBootstrap()
.group(new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
// 首先通过NioSocketChannel获得Pipeline对象
ChannelPipeline pipeline = nioSocketChannel.pipeline();
// 再添加handler 参数1字符串表示为这个handler起一个名字
pipeline.addLast("h1",new ChannelInboundHandlerAdapter(){
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.debug("1");
super.channelRead(ctx, msg);
}
});
pipeline.addLast("h2",new ChannelInboundHandlerAdapter(){
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception