摘要:上一篇文章偽異步和我們使用的原生類庫進行異步的開發(fā)現(xiàn)在我們使用來進行開發(fā)示例代碼綁定端口同步等待成功等待服務端監(jiān)聽端口關閉創(chuàng)建兩個實例是個線程組它包含了一組線程專門用于網(wǎng)絡事件的處理實際上它們就是線程組這里創(chuàng)建兩個的原因是一個用于服務端接
上一篇文章 BIO、偽異步 IO、AIO和NIO 我們使用 JDK 的 NIO 原生類庫進行異步 IO 的開發(fā). 現(xiàn)在我們使用 Netty 來進行開發(fā).
示例代碼public class TimeServer { public void bind(int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .childHandler(new ChildChannelHandler()); // 綁定端口, 同步等待成功 ChannelFuture f = b.bind(port).sync(); // 等待服務端監(jiān)聽端口關閉 f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } private class ChildChannelHandler extends ChannelInitializer{ @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeServerHandler()); } } private class TimeServerHandler extends ChannelHandlerAdapter { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buffer = (ByteBuf) msg; byte[] req = new byte[buffer.readableBytes()]; buffer.readBytes(req); String body = new String(req, "UTF-8"); System.out.println(body); ByteBuf resp = Unpooled.copiedBuffer("6666".getBytes()); ctx.write(resp); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } } }
創(chuàng)建兩個 NioEventLoopGroup 實例. NioEventLoopGroup 是個線程組, 它包含了一組 NIO 線程, 專門用于網(wǎng)絡事件的處理, 實際上它們就是 Reactor 線程組. 這里創(chuàng)建兩個的原因是一個用于服務端接收客戶端的連接, 另一個用于進行 SocketChannel 的網(wǎng)絡讀寫.
創(chuàng)建 ServerBootstrap 對象, 它是 Netty 用于啟動 NIO 服務端的輔助啟動類, 目的是降低服務端的開發(fā)復雜度.
調(diào)用 ServerBootstrap 的 group 方法, 將兩個 NIO 線程組當作參數(shù)傳遞到 ServerBootstrap 中. 并且設置 Channel 為 NioServerSocketChannel, 它的功能對于 JDK NIO 類庫中的 ServerSocketChannel 類. 然后配置 NioServerSocketChannel 的 TCP 參數(shù), 此處將它的 backlog 設置為 1024. 最后綁定 IO 事件的處理類 ChildChannelHandler, 它的作用類似于 Reactor 模式中的 Handler 類, 主要用于處理網(wǎng)絡 IO 事件, 例如記錄日志, 對消息進行編解碼等.
ChannelOption.SO_BACKLOG 對應的是 tcp/ip 協(xié)議 listen 函數(shù)中的 backlog 參數(shù), 函數(shù) listen(int socketfd,int backlog) 用來初始化服務端可連接隊列, 服務端處理客戶端連接請求是順序處理的, 所以同一時間只能處理一個客戶端連接, 多個客戶端來的時候, 服務端將不能處理的客戶端連接請求放在隊列中等待處理, backlog參數(shù)指定了隊列的大小. ChannelOption 連接
服務端啟動輔助類配置完成之后, 調(diào)用它的 bind 方法綁定監(jiān)聽端口, 隨后, 調(diào)用同步阻塞方法 sync 等待綁定操作完成. 完成之后 Netty 會返回一個 ChannelFuture, 它的功能類似于 JDK 的 java.util.concurrent.Future, 主要用于異步操作的通知回調(diào).
f.channel().closeFuture().sync(); 方法進行阻塞, 等待服務端鏈路關閉之后 main 函數(shù)才退出.
調(diào)用 NIO 線程組的 shutdownGracefully 進行優(yōu)雅退出, 它會釋放跟 shutdownGracefully 相關聯(lián)的資源.
TimeServerHandler 繼承自 ChannelHandlerAdapter, 它用于對網(wǎng)絡事件進行讀寫操作, 通常我們只需要關注 channelRead 和 exceptionCaught 方法.
在 channelRead 方法中, 將 msg 轉(zhuǎn)換成 Netty 的 ByteBuf 對象. ByteBuf 類似與 JDK 中的 java.nio.ByteBuffer 對象, 不過它提供了更加強大和靈活的功能. 通過 ByteBuf 的 readableBytes 方法可以獲取緩沖區(qū)可讀的字節(jié)數(shù). 然后使用 readBytes 方法將緩沖區(qū)中的字節(jié)數(shù)組復制到新建的 byte 數(shù)組中.
我們還調(diào)用了 ChannelHandlerContext 的 flush 方法, 它的作用是將消息發(fā)送隊列中的消息寫入到 SocketChannel 中發(fā)送給對方. 從性能角度考慮, 為了防止頻繁的喚醒 Selector 進行消息發(fā)送, Netty 的 write 方法并不直接將消息寫入 SocketChannel 中.
注意: write 方法只是將要發(fā)送的消息放到消息發(fā)送隊列中, 再通過調(diào)用 flush 方法, 將發(fā)送緩沖區(qū)中的消息全部寫到 SocketChannel 中.
在 exceptionCaught 方法中, 如果出現(xiàn)異常, 就關閉 ChannelHandlerContext, 釋放和 ChannelHandlerContext 相關聯(lián)的句柄等資源.
總結(jié)EventLoopGroup: 線程組, 專門用于網(wǎng)絡事件的處理, 實際上它們就是 Reactor 線程組.
ServerBootstrap 是 Netty 用于啟動 NIO 服務端的輔助啟動類.
group方法: 第一個參數(shù) parent (acceptor), 第二個參數(shù) child (client).
NioServerSocketChannel: 它的功能對于 JDK NIO 類庫中的 ServerSocketChannel 類.
ServerSocketChannel: 允許我們監(jiān)聽TCP鏈接請求, 每個請求會創(chuàng)建會一個 SocketChannel.
ChannelHandlerAdapter類: 它用于對網(wǎng)絡事件進行讀寫操作.
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/72718.html
摘要:提供異步的事件驅(qū)動的網(wǎng)絡應用程序框架和工具,用以快速開發(fā)高性能高可靠性的網(wǎng)絡服務器和客戶端程序。總結(jié)我們完成了服務端的簡單搭建,模擬了聊天會話場景。 之前一直在搞前端的東西,都快忘了自己是個java開發(fā)。其實還有好多java方面的東西沒搞過,突然了解到netty,覺得有必要學一學。 介紹 Netty是由JBOSS提供的一個java開源框架。Netty提供異步的、事件驅(qū)動的網(wǎng)絡應用程序框...
摘要:而用于主線程池的屬性都定義在中本篇只是簡單介紹了一下引導類的配置屬性,下一篇我將詳細介紹服務端引導類的過程分析。 從Java1.4開始, Java引入了non-blocking IO,簡稱NIO。NIO與傳統(tǒng)socket最大的不同就是引入了Channel和多路復用selector的概念。傳統(tǒng)的socket是基于stream的,它是單向的,有InputStream表示read和Outpu...
時間:2018年04月11日星期三 說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):https://www.imooc.com 教學源碼:https://github.com/zccodere/s... 學習源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 什么是Netty 高性能、事件驅(qū)動、異步非阻塞的IO Java開源框架 基于NIO的客戶...
摘要:分布式高并發(fā)微服務問阿里京東螞蟻等大廠面試真題解析道跳槽漲薪必備精選面試題最新版大廠面試真題集點擊這里免費領取點擊這里免費領取 估計很多Java程序員平時主要的工作就是一些Web系統(tǒng)的業(yè)務開發(fā),對于服務端IO程序以及網(wǎng)絡通信編程做得并不多,但是對于高級或者資深程序員來說,IO通信以及服務端編...
閱讀 2449·2021-10-08 10:17
閱讀 1824·2021-09-06 15:02
閱讀 2539·2019-08-29 17:30
閱讀 2663·2019-08-29 13:24
閱讀 1522·2019-08-29 11:12
閱讀 3337·2019-08-28 17:52
閱讀 666·2019-08-26 11:30
閱讀 3577·2019-08-26 11:01