日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty组件

發布時間:2025/6/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty组件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

1、NioEventLoopGroup

一個Netty服務端啟動時,通常會有兩個NioEventLoopGroup:一個boss,一個worker。第一個NioEventLoopGroup正常只需要一個EventLoop,主要負責客戶端的連接請求,然后打開一個Channel,交給第二個NioEventLoopGroup中的一個EventLoop來處理這個Channel上的所有讀寫事件。一個Channel只會被一個EventLoop處理,而一個EventLoop可能會被分配給多個Channel。

2、ChannelFuture 接口

由于Netty中的所有I/O操作都是異步的,因此Netty為了解決調用者如何獲取異步操作結果的問題而專門設計了ChannelFuture接口.?

可以調用ChannelFuture里的方法獲取channel,Channel與ChannelFuture可以說形影不離的.

3、Channel(通道)
可以理解為該類對socket進行了封裝,提供了數據的讀取和寫入功能。

4、ChannelHandler

Netty 定義了下面兩個重要的ChannelHandler 子接口:

ChannelInboundHandler(入站handler) —— channel上有消息可讀時,netty就會將該消息交給入站處理器處理??梢杂羞^個處理器,形成一個鏈條。

內部方法:

當某個 ChannelInboundHandler 的實現重寫 channelRead()方法時,可以顯式地釋放與池化的 ByteBuf 實例相關的內存。Netty 為此提供了一個實用方法 ReferenceCountUtil.release();比如

但是以這種方式管理資源可能很繁瑣,一個更加簡單的方式是使用SimpleChannelInboundHandler 會自動釋放資源。如下:

?

ChannelOutboundHandler(出站handler) —— channel寫出數據時,會經過出站處理器的處理后,再發送到網絡上。可以有多個處理器,形成一個鏈條。

內部方法:

ChannelPromise與ChannelFuture:ChannelOutboundHandler中的大部分方法都需要一個ChannelPromise參數,以便在操作完成時得到通知。ChannelPromise是ChannelFuture的一個子類,其定義了一些可寫的方法,如setSuccess()和setFailure(),從而使ChannelFuture不可變。

注意:

如果一個消息被消費或者丟棄了,并且沒有傳遞給 ChannelPipeline 中的下一個ChannelOutboundHandler,那么用戶就有責任調用 ReferenceCountUtil.release()。

比如:

如果消息到達了實際的傳輸層,那么當它被寫入時或者 Channel 關閉時,都將被自動釋放。

5、ChannelPipeline

Netty會把出站Handler和入站Handler放到一個Pipeline中,同屬一個方向的Handler則是有順序的,因為上一個Handler處理的結果往往是下一個Handler的要求的輸入。

6、ChannelHandlerContext

ChannelHandlerContext 代表了 ChannelHandler 和 ChannelPipeline 之間的關聯,每當有 ChannelHandler 添加到 ChannelPipeline 中時,都會創建 ChannelHandlerContext。ChannelHandlerContext 的主要功能是管理它所關聯的 ChannelHandler 和在同一個 ChannelPipeline 中的其他 ChannelHandler之間的交互。

內部方法:

消息向下傳遞ctx.fireChannelRead(msg); 這個方法可能你可能會用到,其次就是write相關方法比較常用。

?

7、 實戰多個入站和出站處理器

7.1 服務端

Message對象:

@Data public class Message implements Serializable{//消息內容private String content;//消息時間戳long time; }

入站處理器1:將Byte轉為Messag對象

/*** 將ByteBuf數據 轉為對象*/ public class EchoServerInHandler1 extends ChannelInboundHandlerAdapter {/*** 服務端讀取到網絡數據后的處理* @param ctx* @param msg* @throws Exception*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {//ByteBuf為netty實現的緩沖區ByteBuf in = (ByteBuf)msg;String msgStr = in.toString(CharsetUtil.UTF_8);System.out.println("EchoServerInHandler1 處理:" + msgStr);Message message = JSON.parseObject(msgStr,new TypeReference<Message>(){});ReferenceCountUtil.release(msg);//通過使用 ReferenceCountUtil.realse(...)方法釋放資源ctx.fireChannelRead(message);}}

?

入站處理器2:業務處理

public class EchoServerInHandler2 extends SimpleChannelInboundHandler<Message> {/*** 服務端讀取到網絡數據后的處理* @param ctx* @param msg* @throws Exception*/@Overridepublic void channelRead0(ChannelHandlerContext ctx, Message msg)throws Exception {System.out.println("EchoServerInHandler2 收到消息:" + msg);Message message = new Message();message.setContent("success");ctx.writeAndFlush(message);} }

?

出站處理器1:將Message對象轉為字節發送到網絡

public class EchoServerOutHandler1 extends ChannelOutboundHandlerAdapter{@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {System.out.println("EchoServerOutHandler1 處理:"+msg);Message message = (Message)msg;String messageJson = JSON.toJSONString(message);ByteBuf byteBuf = Unpooled.copiedBuffer(messageJson, CharsetUtil.UTF_8);ctx.write(byteBuf, promise);} }

出站處理器2:給Message對象加上時間戳

public class EchoServerOutHandler2 extends ChannelOutboundHandlerAdapter{@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {System.out.println("EchoServerOutHandler2 處理:"+msg);Message message = (Message) msg;message.setTime(System.currentTimeMillis());ctx.write(msg, promise);} }

?

在pipeline上添加入站和出站處理器

public class EchoServer {private int port;private EventLoopGroup bossGroup;private EventLoopGroup workGroup;private ServerBootstrap b;public EchoServer(int port) {this.port = port;//第一個線程組是用于接收Client連接的bossGroup = new NioEventLoopGroup(1);//第二個線程組是用于消息的讀寫操作workGroup = new NioEventLoopGroup(2);//服務端輔助啟動類b = new ServerBootstrap();b.group(bossGroup, workGroup)//需要指定使用NioServerSocketChannel這種類型的通道.channel(NioServerSocketChannel.class)//向ChannelPipeline里添加業務處理handler.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//出站處理器 先注冊后執行ch.pipeline().addLast(new EchoServerOutHandler1());//out 1ch.pipeline().addLast(new EchoServerOutHandler2());//out 2//入站處理器 先注冊先執行ch.pipeline().addLast(new EchoServerInHandler1());//in1ch.pipeline().addLast(new EchoServerInHandler2());//in2}});}/*** 啟動* @throws InterruptedException*/public void start() throws InterruptedException {try {//綁定到端口,阻塞等待直到完成b.bind(this.port).sync();System.out.println("服務器啟動成功");} finally {}}/*** 資源優雅釋放*/public void close() {try {if (bossGroup != null)bossGroup.shutdownGracefully().sync();if (workGroup != null)workGroup.shutdownGracefully().sync();} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException, IOException {int port = 9999;EchoServer echoServer = new EchoServer(port);try {echoServer.start();//防止主程序退出System.in.read();} finally {echoServer.close();}} }

需要注意處理器的順序:

先說最基本的,讀入數據,執行順序和注冊順序一致 in1 --> in2 ,他們之間通過?ctx.fireChannelRead(msg);進行傳遞。

從EchoServerInHandler1開始執行到EchoServerInHandler2,邏輯處理,進行數據發送返回, 通過ctx.writeAndFlush()就完成從in -->out的轉換。

ctx.writeAndFlush()從當前節點往前查找out類handler,所以就會以 out2----》out1 這樣一種方式執行。

假如下面這種順序, 出站處理器放到后面,這時調用ctx.writeAndFlush()往前找out類型的處理器就會找不到。這種情況要想執行outhandler的處理,應該執行ctx.channel().writeAndFlush();這是從鏈表結尾開始往前查找out類handler,這就是兩種writeAndFlush的區別

?

7.2 客戶端代碼

public class EchoClient {private final int port;private final String host;private Channel channel;private EventLoopGroup group;private Bootstrap b;public EchoClient(String host, int port) {this.host = host;this.port = port;//客戶端啟動輔助類b = new Bootstrap();//構建線程組 處理讀寫group = new NioEventLoopGroup();b.group(group)//指明使用NIO進行網絡通訊.channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//出站處理器 先注冊后執行ch.pipeline().addLast(new EchoClientOutHandler1());ch.pipeline().addLast(new EchoClientOutHandler2());//入站處理器 先注冊先執行ch.pipeline().addLast(new EchoClientInHandler1());ch.pipeline().addLast(new EchoClientInHandler2());}});}public void start() {try {//連接到遠程節點,阻塞等待直到連接完成ChannelFuture f = b.connect(new InetSocketAddress(host, port)).sync();//同步獲取channel(通道,實際上是對socket的封裝支持讀取和寫入)channel = f.sync().channel();} catch (InterruptedException e) {e.printStackTrace();}}/*** 發送消息* @param msg* @return*/public boolean send(String msg) {Message message = new Message();message.setContent(msg);channel.writeAndFlush(message);return true;}/*** 關閉釋放資源*/public void close(){try {if (group != null)group.shutdownGracefully().sync();} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException {EchoClient client = new EchoClient("127.0.0.1", 9999);try {client.start();Scanner scanner = new Scanner(System.in);while (true) {String msg = scanner.next();client.send(msg);}}finally {client.close();}} }public class EchoClientInHandler1 extends ChannelInboundHandlerAdapter{/**讀取數據* @param ctx* @param msg* @throws Exception*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {//ByteBuf為netty實現的緩沖區ByteBuf in = (ByteBuf)msg;String msgStr = in.toString(CharsetUtil.UTF_8);System.out.println("EchoClientInHandler1 處理:" + msgStr);Message message = JSON.parseObject(msgStr,new TypeReference<Message>(){});ctx.fireChannelRead(message);}/*** 當Channel 處于活動狀態時被調用;Channel 已經連接/綁定并且已經就緒* @param ctx* @throws Exception*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("EchoClientInHandler1 channelActive");}/*** exceptionCaught()事件處理方法當出現Throwable對象才會被調用* 即當Netty由于IO錯誤或者處理器在處理事件時拋出的異常時* @param ctx* @param cause* @throws Exception*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {cause.printStackTrace();ctx.close();} }public class EchoClientInHandler2 extends SimpleChannelInboundHandler<Message> {/*** 客戶端讀取到數據* @param ctx* @param msg* @throws Exception*/@Overridepublic void channelRead0(ChannelHandlerContext ctx, Message msg)throws Exception {System.out.println("EchoClientInHandler2 handler:" + msg);} }/*** 該處理器將對象轉為字節 發送到網絡上*/ public class EchoClientOutHandler1 extends ChannelOutboundHandlerAdapter {@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {System.out.println("EchoClientOutHandler1 處理:"+msg);Message message = (Message)msg;String messageJson = JSON.toJSONString(message);ByteBuf byteBuf = Unpooled.copiedBuffer(messageJson, CharsetUtil.UTF_8);ctx.write(byteBuf, promise);} }/*** 該處理器給message加上時間戳*/ public class EchoClientOutHandler2 extends ChannelOutboundHandlerAdapter{@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {System.out.println("EchoClientOutHandler2 處理:"+msg);Message message = (Message) msg;message.setTime(System.currentTimeMillis());ctx.write(msg, promise);} }

?

啟動服務端和客戶端,然后發送消息

轉載于:https://my.oschina.net/suzheworld/blog/3006174

總結

以上是生活随笔為你收集整理的Netty组件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产裸体美女永久免费无遮挡 | 丰满人妻翻云覆雨呻吟视频 | 爱情岛成人 | 娇小6一8小毛片 | 国产熟女一区二区丰满 | 一本色道久久综合狠狠躁 | 人人搞人人插 | 乱淫的女高中暑假调教h | 日日夜夜亚洲 | 成人精品一区二区三区四区 | 欧美日韩蜜桃 | 少妇av一区二区三区无码 | 免费又黄又爽又色的视频 | 亚洲第一成人网站 | 欧美日韩国产不卡 | 激情小视频在线观看 | 亚洲第一黄色网 | 精品无码久久久久成人漫画 | 97免费在线视频 | 国产不卡视频在线观看 | 337p日本欧洲亚洲大胆精筑 | 日韩久久久久久 | 日韩av首页 | 80日本xxxxxxxxx96 亚洲国产精品视频在线 | 国产视频1区2区3区 国产欧美一区二区精品性色99 | 国产探花在线精品一区二区 | 91在线视频免费播放 | av黄色免费在线观看 | 亚洲妇女体内精汇编 | 国产a免费 | 日本久色| 久久久午夜电影 | 国产真实乱人偷精品 | 殴美黄色大片 | www.狠狠艹| 免费在线成人网 | 欧美亚洲视频在线观看 | 日剧再来一次第十集 | 国产精品影院在线观看 | 狂野欧美性猛交xxxx巴西 | 欧美aⅴ在线 | 国产免费观看视频 | 欧美mv日韩mv国产网站app | 国产一二区在线观看 | 国产免费av一区 | 操操操网站 | 黄色一级一片免费播放 | 久久嫩草精品久久久久 | 国产老女人乱淫免费可以 | 中国妇女做爰视频 | 欧美精品免费看 | 午夜视频免费在线观看 | 韩国一区二区在线观看 | 色戒在线免费 | 成人激情视频在线 | 欲求不满的岳中文字幕 | 亚洲熟女少妇一区二区 | 天堂久久一区 | 99re6在线精品视频免费播放 | 天堂在线免费观看视频 | 亚州精品国产精品乱码不99按摩 | 五月婷婷中文 | 香港一级淫片免费放 | 欧美一二| 快播怡红院 | 少妇免费毛片久久久久久久久 | 一区二区三区久久 | 老司机精品福利导航 | 国产人澡人澡澡澡人碰视频 | 亚洲av不卡一区二区 | 亚洲av成人精品毛片 | 欧产日产国产精品 | 啦啦啦视频在线观看 | 综合色亚洲 | 亚洲黄色大全 | 精品国产露脸精彩对白 | 蜜臀少妇久久久久久久高潮 | 青青青青青草 | 欧美天天爽 | 一起操网站| 中文字幕在线视频日韩 | 中文字幕色哟哟 | a中文在线| 日本精品视频在线播放 | 久久99精品国产麻豆婷婷洗澡 | 国产91视频在线 | 一级做a视频 | 亚洲精品久久久久avwww潮水 | 5566毛片 | 色网导航站 | 俺去久久 | 尤物自拍 | 国产中文字幕二区 | 欧美一区三区三区高中清蜜桃 | 国产成人一区二区 | 欧美调教视频 | 东方伊甸园av在线 | 91嫩草精品 | 在线视频日本 |