netty tcp服务端主动断开客户端_「Netty核心技术」6-ChannelPipeline源码
ChannelPipeline是Channelhandler的容器,它負責ChannelHandler的管理和事件攔截與調度。
土話:
ChannelPipeline就是用來管理Channelhandler有增刪功能。還有一些事件的攔截,交給ChannelHandler處理。
關于閱讀源碼的步驟,請參考這份源碼閱讀步驟你值得擁有
ChannelPipeline的功能
管理ChannelHandler
- addXXX:增加ChannelHandler
- get:獲得ChannelHandler
- remove:移除ChannelHandler
- replace:代替ChannelHander
攔截ChannelHandler的事件,這里比較重要
從圖中看
- 從Socket.read()經過ChannelHandler1,ChannelHandler2....ChannelHandlerN開始稱為inbound事件。
- 從ChannelHandlerContext開始經過ChannelHandlerN,ChannelHandlerN-1,...一直到ChannelHandler1,Socket.write()稱為outbound事件。
inbound事件對應ChannelInboundInvoker類
inbound事件通常由I/O線程觸發,例如TCP鏈路建立事件,鏈路關閉事件,讀事件,異常通知事件等。
public interface ChannelInboundInvoker { //Channel注冊事件 //Channel注冊成功后會執行該方法,對應的地方AbstractChannel.register0方法 ChannelInboundInvoker fireChannelRegistered(); //取消注冊事件 //取消注冊后調用,對應的地方AbstractChannel.deregister ChannelInboundInvoker fireChannelUnregistered(); //TCP鏈路建立成功,Channel激活事件,客戶端與服務端建立連接 //客戶端發起請求后 //服務端會從ServerBootstrapAcceptor會收到channelRead,childGroup注冊一個child //對應的地方是AbstractChannel.register0 //客戶端則再連接成功后對應的地方AbstractNioChannel.fulfillConnectPromise ChannelInboundInvoker fireChannelActive(); //客戶端與服務端斷開連接的時候調用 ChannelInboundInvoker fireChannelInactive(); //異常的通知事件 ChannelInboundInvoker fireExceptionCaught(Throwable cause); //用戶自定義事件 //就是我們定義ChannelHandler的時候可以調用我們自定義的fireUserEventTriggered ChannelInboundInvoker fireUserEventTriggered(Object event); //讀數據事件 //對應調用的地方是NioUnsafe.read ChannelInboundInvoker fireChannelRead(Object msg); //讀操作完成 //對應調用的地方是NioUnsafe.read讀完后調用 ChannelInboundInvoker fireChannelReadComplete(); //channel的可寫狀態變化通知事件 ChannelInboundInvoker fireChannelWritabilityChanged();}上面的每個方法都很重要,我們要自定義ChannelHandler的時候必須要知道怎么調用這些方法。
outbound事件對應ChannelOutboundInvoker類
outbound通常是由用戶主動發起的網絡I/O操作,例如用戶發起的連接操作,綁定操作,消息發送等操作。
public interface ChannelOutboundInvoker { //bind本地地址事件 ChannelFuture bind(SocketAddress localAddress); //連接服務端事件 ChannelFuture connect(SocketAddress remoteAddress); ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress); //斷開連接事件 ChannelFuture disconnect(); //關閉當前channel事件 ChannelFuture close(); //取消注冊事件 ChannelFuture deregister(); ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise); ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise); ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); ChannelFuture disconnect(ChannelPromise promise); ChannelFuture close(ChannelPromise promise); ChannelFuture deregister(ChannelPromise promise); //讀事件 ChannelOutboundInvoker read(); //發送事件 ChannelFuture write(Object msg); ChannelFuture write(Object msg, ChannelPromise promise); //刷新事件 ChannelOutboundInvoker flush(); //寫和刷新事件 ChannelFuture writeAndFlush(Object msg, ChannelPromise promise); ChannelFuture writeAndFlush(Object msg); ChannelPromise newPromise(); ChannelProgressivePromise newProgressivePromise(); ChannelFuture newSucceededFuture(); ChannelFuture newFailedFuture(Throwable cause); ChannelPromise voidPromise();}我們擴展事件一般是在inbound事件。
核心類DefaultChannelPipeline
DefaultChannelPipeline是Netty用來管理ChannelHandler的核心類
DefaultChannelPipeline
protected DefaultChannelPipeline(Channel channel) { this.channel = ObjectUtil.checkNotNull(channel, "channel"); succeededFuture = new SucceededChannelFuture(channel, null); voidPromise = new VoidChannelPromise(channel, true); tail = new TailContext(this); head = new HeadContext(this); head.next = tail; tail.prev = head;}分析DefaultChannelPipeline關鍵成員變量
分析AbstractChannelHandlerContext類
ChannelHandlerContext就是結合了ChannelInboundInvoker和ChannelOutboundInvoker,然后多了一些Handler的處理,比如說名稱,獲得ChannelHandler等等。
閱讀源碼知識點:
剛開始設計框架的時候,開發者也不會說設計的很完善,都是后面設計之后,慢慢抽象出來的。例如你要問我為什么要設計一個ChannelHandlerContext出來,我只能跟你說,有一些抽象方法ChannelInboundInvoker和ChannelOutboundInvoker沒有必須要有一個新的接口聚合它兩,并且要提供一些方法。
再來看AbstractChannelHandlerContext成員變量
AbstractChannelHandlerContext的結構是一個雙鏈表
AbstractChannelHandlerContext結構
再來分析DefaultChannelHandlerContext類
final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext { private final ChannelHandler handler; DefaultChannelHandlerContext( DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) { super(pipeline, executor, name, isInbound(handler), isOutbound(handler)); if (handler == null) { throw new NullPointerException("handler"); } this.handler = handler; }主要就是封裝handler成一個Context
分析HeadContext類
final class HeadContext extends AbstractChannelHandlerContext implements ChannelOutboundHandler, ChannelInboundHandlerHeadContext實現了ChannelOutboundHandler,ChannelInboundHandler。上面說過outbound事件是一些網絡I/O操作,例如用戶發起的連接操作,綁定操作,消息發送等操作。intbound:CP鏈路建立事件,鏈路關閉事件,讀事件,異常通知事件等。
分析TailContext類
final class TailContext extends AbstractChannelHandlerContext implements ChannelInboundHandlerTailContext只實現了ChannelInboundHandler,但是它的一些inbound事件都不能使用,因為HeadContext已經使用了。
@Override public void channelActive(ChannelHandlerContext ctx) throws Exception { onUnhandledInboundChannelActive(); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { onUnhandledInboundChannelInactive(); } @Override public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { onUnhandledChannelWritabilityChanged(); }onUnhandledXXXX:就表示do noting。
小結一下,本篇講解了
下篇講解ChannelPipeline源碼解析二,主要分析DefaultChannelPipeline中的核心方法。
建議閱讀
「Netty核心技術」5-客戶端啟動
「Netty核心技術」4-服務端啟動
「Netty核心技術」3-AbstractBootStrap
「Netty核心技術」2-HelloWorld
「Netty核心技術」1-序言
總結
以上是生活随笔為你收集整理的netty tcp服务端主动断开客户端_「Netty核心技术」6-ChannelPipeline源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断非负整数是否是3的倍数_六年级小升初
- 下一篇: 内网和外网的区别_无需服务器,树莓派使用