免费A级毛片无码专区网站-成人国产精品视频一区二区-啊 日出水了 用力乖乖在线-国产黑色丝袜在线观看下-天天操美女夜夜操美女-日韩网站在线观看中文字幕-AV高清hd片XXX国产-亚洲av中文字字幕乱码综合-搬开女人下面使劲插视频

八 Netty 學(xué)習(xí):新連接接入源碼說明

Netty 學(xué)習(xí)(八):新連接接入源碼說明作者: Grey
原文地址:
博客園:Netty 學(xué)習(xí)(八):新連接接入源碼說明
CSDN:Netty 學(xué)習(xí)(八):新連接接入源碼說明
新連接的接入分為3個過程

  1. 檢測到有新連接 。
  2. 將新連接注冊到 worker 線程 。
  3. 注冊新連接的讀事件 。
檢測新連接的代碼在NioEventLoop中的processSelectedKey()方法中
private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {......final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe();......// Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead// to a spin loopif ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {unsafe.read();}.....}啟動一個 Netty 服務(wù)端和 Netty 客戶端,在unsafe.read()這一行打斷點(diǎn),可以得到這里的unsafe就是NioMessageUnsafe,進(jìn)入NioMessageUnsaferead()方法,
這個方法主要做的事情就是:創(chuàng)建,設(shè)置并綁定NioSocketChannel
private final List<Object> readBuf = new ArrayList<Object>();@Overridepublic void read() {......do {// 創(chuàng)建`NioSocketChannel`int localRead = doReadMessages(readBuf);......} while (continueReading(allocHandle));......// 設(shè)置并綁定 NioSocketChannelint size = readBuf.size();for (int i = 0; i < size; i ++) {readPending = false;pipeline.fireChannelRead(readBuf.get(i));}readBuf.clear();allocHandle.readComplete();pipeline.fireChannelReadComplete();......}}創(chuàng)建NioSocketChannel調(diào)用的是doReadMessages()方法,通過Debug,可以看到doReadMessage()來自于NioServerSocketChannel
@Overrideprotected int doReadMessages(List<Object> buf) throws Exception {SocketChannel ch = SocketUtils.accept(javaChannel());try {if (ch != null) {buf.add(new NioSocketChannel(this, ch));return 1;}} catch (Throwable t) {logger.warn("Failed to create a new channel from an accepted socket.", t);try {ch.close();} catch (Throwable t2) {logger.warn("Failed to close a socket.", t2);}}return 0;}可以看到此時調(diào)用的是 Java 底層的accept()方法,創(chuàng)建了一條 JDK 層面的Channel, Netty 將其封裝成自定義的NioSocketChannel,并加入一個List
繼續(xù) Debug,進(jìn)入 NioSocketChannel 的構(gòu)造方法中,調(diào)用的是AbstractNioByteChannel的構(gòu)造方法
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {super(parent, ch, SelectionKey.OP_READ);}這個方法類似在 NIO 編程中,注冊 OP_READ 事件,表示 Channel 對讀事件感興趣 。
【八 Netty 學(xué)習(xí):新連接接入源碼說明】接下來是設(shè)置并綁定NioSocketChannel,處理每個NioSocketChannel,通過 Debug 可以來到AbstractUnsaferegister0()方法
private void register0(ChannelPromise promise) {// 注冊SelectordoRegister();// 執(zhí)行 handlerpipeline.invokeHandlerAddedIfNeeded();// 傳播 ChannelRegistered事件pipeline.fireChannelRegistered();// 注冊讀事件if (isActive()) {if (firstRegistration) {pipeline.fireChannelActive();} else if (config().isAutoRead()) {// This channel was registered before and autoRead() is set. This means we need to begin read// again so that we process inbound data.//// See https://github.com/netty/netty/issues/4805beginRead();}}}這個方法主要完成的事情就是:
  1. NioSocketChannel注冊到Selector
  2. 配置自定義的Handler
  3. 將連接注冊事件傳播下去,調(diào)用了每個HandlerchannelRegistered方法 。

    經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀