Netty源碼分析之ChannelPipeline

每個channel內(nèi)部都會持有一個ChannelPipeline對象pipeline. pipeline默認(rèn)實(shí)現(xiàn)DefaultChannelPipeline內(nèi)部維護(hù)了一個DefaultChannelHandlerContext鏈表。


當(dāng)channel完成register、active、read等操作時,會觸發(fā)pipeline的相應(yīng)方法。

1、當(dāng)channel注冊到selector時,觸發(fā)pipeline的fireChannelRegistered方法。

2、當(dāng)channel的socket綁定完成時,觸發(fā)pipeline的fireChannelActive方法。

3、當(dāng)有客戶端請求時,觸發(fā)pipeline的fireChannelRead方法。

4、當(dāng)本次客戶端請求,pipeline執(zhí)行完fireChannelRead,觸發(fā)pipeline的fireChannelReadComplete方法。

接下去看看pipeline是如何組織并運(yùn)行handler對應(yīng)的方法。

DefaultChannelPipeline

其中DefaultChannelHandlerContext保存了當(dāng)前handler的上下文,如channel、pipeline等信息,默認(rèn)實(shí)現(xiàn)了head和tail。

class DefaultChannelPipeline implements ChannelPipeline {

final Channel channel; // pipeline所屬的channel

//head和tail都是handler上下文

final DefaultChannelHandlerContext head;

final DefaultChannelHandlerContext tail;

...

public DefaultChannelPipeline(AbstractChannel channel) {

if (channel == null) {

throw new NullPointerException("channel");

}

this.channel = channel;

? ? ? ? tail = new TailContext(this);

? ? ? ? head = new HeadContext(this);

? ? ? ? head.next = tail;

? ? ? ? tail.prev = head;

}

}

1、TailContext實(shí)現(xiàn)了ChannelOutboundHandler接口。

2、HeadContext實(shí)現(xiàn)了ChannelInboundHandler接口。

3、head和tail形成了一個鏈表。

對于Inbound的操作,當(dāng)channel注冊到selector時,觸發(fā)pipeline的fireChannelRegistered,從head開始遍歷,找到實(shí)現(xiàn)了ChannelInboundHandler接口的handler,并執(zhí)行其fireChannelRegistered方法。

@Override

public ChannelPipeline fireChannelRegistered() {

? ? head.fireChannelRegistered();

return this;

}

@Override

public ChannelHandlerContext fireChannelRegistered() {

final DefaultChannelHandlerContext next = findContextInbound();

EventExecutor executor = next.executor();

if (executor.inEventLoop()) {

next.invokeChannelRegistered();

} else {

? ? ? ? executor.execute(new Runnable() {

@Override

public void run() {

next.invokeChannelRegistered();

}

});

}

return this;

}

private DefaultChannelHandlerContext findContextInbound() {

DefaultChannelHandlerContext ctx = this;

do {

? ? ? ? ctx = ctx.next;

} while (!(ctx.handler() instanceof ChannelInboundHandler));

return ctx;

}

private void invokeChannelRegistered() {

try {

((ChannelInboundHandler) handler()).channelRegistered(this);

} catch (Throwable t) {

? ? ? ? notifyHandlerException(t);

}

}


假如我們通過pipeline的addLast方法添加一個inboundHandler實(shí)現(xiàn)。

public class ClientHandler extends ChannelInboundHandlerAdapter {

@Override

public void channelRegistered(ChannelHandlerContext ctx)

throws Exception {

super.channelRegistered(ctx);

System.out.println(" ClientHandler? registered channel ");

}

}

當(dāng)channel注冊完成時會觸發(fā)pipeline的channelRegistered方法,從head開始遍歷,找到ClientHandler,并執(zhí)行channelRegistered方法。

對于Outbound的操作,則從tail向前遍歷,找到實(shí)現(xiàn)ChannelOutboundHandler接口的handler,具體實(shí)現(xiàn)和Inbound一樣。

服務(wù)啟動過程中,ServerBootstrap在init方法中,會給ServerSocketChannel的pipeline添加ChannelInitializer對象,其中ChannelInitializer繼承ChannelInboundHandlerAdapter,并實(shí)現(xiàn)了ChannelInboundHandler接口,所以當(dāng)ServerSocketChannel注冊到selector之后,會觸發(fā)其channelRegistered方法。

public final void channelRegistered(ChannelHandlerContext ctx) throws Exception {

? ? initChannel((C) ctx.channel());

? ? ctx.pipeline().remove(this);

? ? ctx.fireChannelRegistered();

}

public void initChannel(Channel ch) throws Exception {

ChannelPipeline pipeline = ch.pipeline();

ChannelHandler handler = handler();

if (handler != null) {

? ? ? ? pipeline.addLast(handler);

}

? ? pipeline.addLast(new ServerBootstrapAcceptor(

? ? ? ? ? ? currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));

}

在initChannel實(shí)現(xiàn)中,添加ServerBootstrapAcceptor實(shí)例到pipeline中。

ServerBootstrapAcceptor繼承自ChannelInboundHandlerAdapter,負(fù)責(zé)把接收到的客戶端socketChannel注冊到childGroup中,由childGroup中的eventLoop負(fù)責(zé)數(shù)據(jù)處理。

public void channelRead(ChannelHandlerContext ctx, Object msg) {

final Channel child = (Channel) msg;

? ? child.pipeline().addLast(childHandler);

for (Entry<ChannelOption<?>, Object> e: childOptions) {

try {

if (!child.config().setOption((ChannelOption<Object>) e.getKey(), e.getValue())) {

? ? ? ? ? ? ? ? logger.warn("Unknown channel option: " + e);

}

} catch (Throwable t) {

? ? ? ? ? ? logger.warn("Failed to set a channel option: " + child, t);

}

}

for (Entry<AttributeKey<?>, Object> e: childAttrs) {

? ? ? ? child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());

}

try {

? ? ? ? childGroup.register(child).addListener(new ChannelFutureListener() {

@Override

public void operationComplete(ChannelFuture future) throws Exception {

if (!future.isSuccess()) {

? ? ? ? ? ? ? ? ? ? forceClose(child, future.cause());

}

}

});

} catch (Throwable t) {

? ? ? ? forceClose(child, t);

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容