<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前文傳送門:Netty使用者端處理接入事件handle建立
public void read() { //必須是NioEventLoop方法呼叫的, 不能通過外部執行緒呼叫 assert eventLoop().inEventLoop(); //伺服器端channel的config final ChannelConfig config = config(); //伺服器端channel的pipeline final ChannelPipeline pipeline = pipeline(); //處理伺服器端接入的速率 final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle(); //設定設定 allocHandle.reset(config); boolean closed = false; Throwable exception = null; try { try { do { //建立jdk底層的channel //readBuf用於臨時承載讀到連結 int localRead = doReadMessages(readBuf); if (localRead == 0) { break; } if (localRead < 0) { closed = true; break; } //分配器將讀到的連結進行計數 allocHandle.incMessagesRead(localRead); //連線數是否超過最大值 } while (allocHandle.continueReading()); } catch (Throwable t) { exception = t; } int size = readBuf.size(); //遍歷每一條使用者端連線 for (int i = 0; i < size; i ++) { readPending = false; //傳遞事件, 將建立NioSokectChannel進行傳遞 //最終會呼叫ServerBootstrap的內部類ServerBootstrapAcceptor的channelRead()方法 pipeline.fireChannelRead(readBuf.get(i)); } readBuf.clear(); allocHandle.readComplete(); pipeline.fireChannelReadComplete(); //程式碼省略 } finally { //程式碼省略 } }
我們繼續剖析int localRead = doReadMessages(readBuf)這一部分邏輯
private final List<Object> readBuf = new ArrayList<Object>();
這裡只是簡單的定義了一個ArrayList, doReadMessages(readBuf)方法就是將讀到的連結放在這個list中, 因為這裡是NioServerSocketChannel所以這走到了NioServerSocketChannel的doReadMessage()方法
跟到doReadMessage()方法中:
protected int doReadMessages(List<Object> buf) throws Exception { //根據當前jdk底層的serverSocketChannel拿到jdk底層channel SocketChannel ch = javaChannel().accept(); try { if (ch != null) { //封裝成一個NioSokectChannel扔到buf中 buf.add(new NioSocketChannel(this, ch)); return 1; } } catch (Throwable t) { //程式碼省略 } return 0; }
首先根據jdk的ServerSocketChannel拿到jdk的Channel, 熟悉Nio的小夥伴應該不會陌生
封裝成一個NioSokectChannel扔到Readbuf中
這裡的NioSocketChannel是對jdk底層的SocketChannel的包裝, 我們看到其構造方法傳入兩個引數, this代表當前NioServerSocketChannel, ch代表jdk的SocketChannel
我們跟到NioSocketChannel的構造方法中:
public NioSocketChannel(Channel parent, SocketChannel socket) { super(parent, socket); config = new NioSocketChannelConfig(this, socket.socket()); }
這裡看到呼叫了父類別構造方法, 傳入兩個引數, parent代表建立自身channel的, NioServerSocketChannel, socket代表jdk底層的socketChannel
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) { super(parent, ch, SelectionKey.OP_READ); }
其中SelectionKey.OP_READ代表其監聽事件是讀事件
繼續跟父類別的構造方法:
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) { super(parent); this.ch = ch; this.readInterestOp = readInterestOp; try { //設定為非阻塞 ch.configureBlocking(false); } catch (IOException e) { //程式碼省略 } }
這裡初始化了自身成員變數ch, 就是jdk底層的SocketChannel, 並初始化了自身的監聽事件readInterestOp, 也就是讀事件
ch.configureBlocking(false)這一步熟悉nio的小夥伴也不陌生, 就是將jdk的SocketChannel設定為非阻塞
我們繼續跟到父類別構造方法中:
protected AbstractChannel(Channel parent) { this.parent = parent; id = newId(); unsafe = newUnsafe(); pipeline = newChannelPipeline(); }
這裡初始化parent, 也就是建立自身的NioServerSocketChannel, 併為自身建立了唯一id
初始化unsafe, 我們跟到newUnsafe()方法中
由於此方法是NioEventLoop呼叫的, 所以會走到其父類別AbstractNioByteChannel的newUnsafe()
跟到newUnsafe()中:
protected AbstractNioUnsafe newUnsafe() { return new NioByteUnsafe(); }
這裡建立了NioByteUnsafe物件, 所以NioSocketChannel對應的unsafe是NioByteUnsafe
繼續往下跟, 我們看到其初始化了pipeline, 有關pipline的知識, 我們會在下一章節中講到
回到NioSocketChannel中的構造方法:
public NioSocketChannel(Channel parent, SocketChannel socket) { super(parent, socket); config = new NioSocketChannelConfig(this, socket.socket()); }
同NioServerSocketChannel一樣, 這裡也初始化了一個Config屬性, 傳入兩個引數, 當前NioSocketChannel自身和jdk的底層SocketChannel的socket物件
private NioSocketChannelConfig(NioSocketChannel channel, Socket javaSocket) { super(channel, javaSocket); }
同樣, 這個類是NioSocketChannel的內部類
繼續跟父類別構造方法:
public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) { super(channel); if (javaSocket == null) { throw new NullPointerException("javaSocket"); } //儲存當前javaSocket this.javaSocket = javaSocket; //是否禁止Nagle演演算法 if (PlatformDependent.canEnableTcpNoDelayByDefault()) { try { setTcpNoDelay(true); } catch (Exception e) { } } }
這裡儲存了SocketChannel的socket物件, 並且預設的情況禁止了Nagle演演算法, 有關Nagle, 感興趣的同學可以學習下相關知識
繼續跟到父類別構造方法中:
public DefaultChannelConfig(Channel channel) { this(channel, new AdaptiveRecvByteBufAllocator()); }
又跟到到了我們熟悉的部分了, 也就是說, 無論NioServerSocketChannel和NioSocketChannel, 最後都會初始化DefaultChannelConfig, 並建立可變ByteBuf分配器, 我們之前小節對此做過詳細剖析這裡不再贅述, 這部分忘記的內容可以閱讀之前小節內容進行回顧
這個分配器什麼時候真正分配位元組緩衝的呢?我們會在之後的章節進行詳細剖析
至此我們剖析完成了NioSocketChannel的初始化過程
以上就是Netty使用者端接入流程NioSocketChannel建立原始碼解析的詳細內容,更多關於Netty使用者端接入流程NioSocketChannel的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45