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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

getbook netty实战_Netty 入门教程

發(fā)布時(shí)間:2025/3/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 getbook netty实战_Netty 入门教程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

Netty是一個(gè)異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架,用于快速開發(fā)可維護(hù)的高性能協(xié)議服務(wù)器和客戶端。

Netty 是一個(gè)廣泛使用的 Java 網(wǎng)絡(luò)編程框架(Netty 在 2011 年獲得了Duke's Choice Award,見https://www.java.net/dukeschoice/2011)。它活躍和成長(zhǎng)于用戶社區(qū),像大型公司 Facebook 和 Instagram 以及流行 開源項(xiàng)目如 Infinispan, HornetQ, Vert.x, Apache Cassandra 和 Elasticsearch 等,都利用其強(qiáng)大的對(duì)于網(wǎng)絡(luò)抽象的核心代碼。

設(shè)計(jì)

針對(duì)多種傳輸類型的統(tǒng)一接口 - 阻塞和非阻塞

簡(jiǎn)單但更強(qiáng)大的線程模型

真正的無(wú)連接的數(shù)據(jù)報(bào)套接字支持

鏈接邏輯支持復(fù)用

易用性

完善的Javadoc

全面的代碼示例

性能

比核心的 Java API 更好的吞吐量,較低的延時(shí)

資源消耗更少,這個(gè)得益于共享池和重用

減少內(nèi)存拷貝

健壯性

消除由于慢、快、或重載連接產(chǎn)生的OutOfMemoryError

消除經(jīng)常發(fā)現(xiàn)在 NIO 在高速網(wǎng)絡(luò)中的應(yīng)用中的不公平讀/寫比

安全

完整的 SSL/ TLS 和 StartTLS 的支持

運(yùn)行在受限的環(huán)境例如 Applet 或 OSGI

社區(qū)

社區(qū)完善、更新/發(fā)布頻繁

背景1 - Reactor模型

wiki:

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.

幾個(gè)關(guān)鍵點(diǎn):

事件驅(qū)動(dòng)(event handling)

可以處理一個(gè)或多個(gè)輸入源(one or more inputs)

通過Service Handler同步的將輸入事件(Event)采用多路復(fù)用分發(fā)給相應(yīng)的Request Handler(多個(gè))處理

背景2 - Java網(wǎng)絡(luò)編程(BIO)

經(jīng)典的BIO服務(wù)端:

一個(gè)主線程監(jiān)聽某個(gè)port,等待客戶端連接

當(dāng)接收到客戶端發(fā)起的連接時(shí),創(chuàng)建一個(gè)新的線程去處理客戶端請(qǐng)求

主線程重新回到監(jiān)聽port,等待下一個(gè)客戶端連接

缺點(diǎn):

每個(gè)新的客戶端Socket連接,都需要?jiǎng)?chuàng)建一個(gè)Thread處理,將會(huì)創(chuàng)建大量的線程

線程開銷較大,連接多時(shí),內(nèi)存耗費(fèi)大,CPU上下文切換開銷也大

背景3 - Java NIO

Java NIO 由以下幾個(gè)核心部分組成:

Channels

Buffers

Selectors

傳統(tǒng)IO基于字節(jié)流和字符流進(jìn)行操作,而NIO基于Channel和Buffer(緩沖區(qū))進(jìn)行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。Selector(選擇區(qū))用于監(jiān)聽多個(gè)通道的事件(比如:連接打開,數(shù)據(jù)到達(dá))。因此,單個(gè)線程可以監(jiān)聽多個(gè)數(shù)據(jù)通道。

NIO和傳統(tǒng)IO(一下簡(jiǎn)稱IO)之間第一個(gè)最大的區(qū)別是,IO是面向流的,NIO是面向緩沖區(qū)的。

Netty的重要組件

下面枚舉所有的Netty應(yīng)用程序的基本構(gòu)建模塊,包括客戶端和服務(wù)端。

BOOTSTRAP

Netty 應(yīng)用程序通過設(shè)置bootstrap(引導(dǎo))類的開始,該類提供了一個(gè)用于應(yīng)用程序網(wǎng)絡(luò)配置的容器。Netty有兩種類型的引導(dǎo): 客戶端(Bootstrap)和服務(wù)端(ServerBootstrap)

CHANNEL

底層網(wǎng)絡(luò)傳輸API必須提供給應(yīng)用I/O操作的接口,傳入(入站)或者傳出(出站)數(shù)據(jù)的載體,如讀,寫,連接,綁定等等。對(duì)于我們來(lái)說,這結(jié)構(gòu)幾乎總是會(huì)成為一個(gè)"socket"。

CHANNELHANDLER

ChannelHandler 支持很多協(xié)議,并且提供用于數(shù)據(jù)處理的容器。我們已經(jīng)知道ChannelHandler由特定事件觸發(fā)。ChannelHandler可專用于幾乎所有的動(dòng)作,包括一個(gè)對(duì)象轉(zhuǎn)為字節(jié),執(zhí)行過程中拋出的異常處理。

常用的一個(gè)接口是 ChannelInboundHandler,這個(gè)類型接收到入站事件(包括接收到的數(shù)據(jù))可以處理應(yīng)用程序邏輯。

當(dāng)你需要提供相應(yīng)時(shí),你也可以從ChannelInboundHandler沖刷數(shù)據(jù)。一句話,業(yè)務(wù)邏輯經(jīng)常存活于一個(gè)或者多個(gè)ChannelInboundHandler。

CHANNELPIPELINE

ChannelPipline提供了一個(gè)容器給 ChannelHandler鏈并提供了一個(gè)API用于管理沿著鏈入站和出站事件的流動(dòng)。每個(gè)Channel都有自己的ChannelPipeline,當(dāng)Channel創(chuàng)建時(shí)自動(dòng)創(chuàng)建的。

EVENTLOOP

EventLoop 用于處理 Channel 的 I/O 操作,控制流、多線程和并發(fā)。一個(gè)單一的 EventLoop通常會(huì)處理多個(gè) Channel 事件。一個(gè) EventLoopGroup 可以含有多于一個(gè)的 EventLoop 和 提供了一種迭代用于檢索清單中的下一個(gè)。

CHANNELFUTURE

Netty 所有的 I/O 操作都是異步。因?yàn)橐粋€(gè)操作可能無(wú)法立即返回,我們需要有一種方法在以后確定它的結(jié)果。

出于這個(gè)目的,Netty 提供了接口 ChannelFuture,它的 addListener 方法注冊(cè)了一個(gè) ChannelFutureListener ,當(dāng)操作完成時(shí),可以被異步通知(不管成功與否)。

以上組件的關(guān)系:

[站外圖片上傳中...(image-67dbed-1563459279939)]

幾點(diǎn)重要的約定:

一個(gè)EventLoopGroup包含一個(gè)或多個(gè)EventLoop

一個(gè)EventLoop在其生命周期內(nèi)只能和一個(gè)Thread綁定

EventLoop處理的I/O事件都由它綁定的Thread處理

一個(gè)Channel在其生命周期內(nèi),只能注冊(cè)于一個(gè)EventLoop

一個(gè)EventLoop可能被分配處理多個(gè)Channel。也就是EventLoop與Channel是1:n的關(guān)系

一個(gè)Channel上的所有ChannelHandler的事件由綁定的EventLoop中的I/O線程處理

不要阻塞Channel的I/O線程,可能會(huì)影響該EventLoop中其他Channel事件處理

第一個(gè) Netty 應(yīng)用: Echo client / server

本應(yīng)用的源碼請(qǐng)見 netty倉(cāng)庫(kù)中的example目錄。

接下來(lái),我們來(lái)構(gòu)建一個(gè)完整的Netty客戶端和服務(wù)器,更完整地了解Netty的API是如何實(shí)現(xiàn)客戶端和服務(wù)器的。

先來(lái)看看 Netty 應(yīng)用 - Echo client/server 總覽:

[站外圖片上傳中...(image-5996c5-1563459279939)]

echo應(yīng)用的客服端和服務(wù)器的交互很簡(jiǎn)單: 客戶端啟動(dòng)后,建立一個(gè)連接并發(fā)送一個(gè)或多個(gè)消息到服務(wù)端,服務(wù)端接受到的每個(gè)消息再返回給客戶端。

服務(wù)端代碼

一個(gè)信息處理器(handler): 這個(gè)實(shí)現(xiàn)是服務(wù)端的業(yè)務(wù)邏輯部分,當(dāng)連接創(chuàng)建后和接收信息后的處理類。

服務(wù)器: 主要通過ServerBootstrap設(shè)置服務(wù)器的監(jiān)聽端口等啟動(dòng)部分。

EchoServerHandler

通過繼承ChannelInboundHandlerAdapter,這個(gè)類提供了默認(rèn)的ChannelInboundHandler實(shí)現(xiàn),只需覆蓋以下的方法:

channelRead() - 每個(gè)消息入站都會(huì)調(diào)用

channelReadComplete() - 通知處理器最后的channelRead()是當(dāng)前批處理中的最后一條消息時(shí)調(diào)用

exceptionCaught() - 捕獲到異常時(shí)調(diào)用

@ChannelHandler.Sharable // 標(biāo)識(shí)這類的實(shí)例之間可以在 channel 里面共享

public class EchoServerHandler extends ChannelInboundHandlerAdapter {

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

ByteBuf in = (ByteBuf) msg;

System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));

ctx.write(in); // 將所接收的消息返回給發(fā)送者

}

@Override

public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) // 沖刷所有待審消息到遠(yuǎn)程節(jié)點(diǎn)。關(guān)閉通道后,操作完成

.addListener(ChannelFutureListener.CLOSE);

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

cause.printStackTrace();

ctx.close();

}

}

EchoServer

創(chuàng)建ServerBootstrap實(shí)例來(lái)引導(dǎo)服務(wù)器,本服務(wù)端分配了一個(gè)NioEventLoopGroup實(shí)例來(lái)處理事件的處理,如接受新的連接和讀/寫數(shù)據(jù),然后綁定本地端口,分配EchoServerHandler實(shí)例給Channel,這樣服務(wù)器初始化完成,可以使用了。

public class EchoServer {

private final int port;

public EchoServer(int port) {

this.port = port;

}

public void start() throws Exception {

NioEventLoopGroup group = new NioEventLoopGroup(); // 創(chuàng)建 EventLoopGroup

try {

ServerBootstrap bootstrap = new ServerBootstrap(); // 創(chuàng)建 ServerBootstrap

bootstrap.group(group)

.channel(NioServerSocketChannel.class) // 指定使用 NIO 的傳輸 Channel

.localAddress(new InetSocketAddress(port)) // 設(shè)置 socket 地址使用所選的端口

.childHandler(new ChannelInitializer() { // 添加 EchoServerHandler 到 Channel 的 ChannelPipeline

@Override

protected void initChannel(SocketChannel socketChannel) throws Exception {

socketChannel.pipeline().addLast(new EchoServerHandler());

}

});

ChannelFuture future = bootstrap.bind().sync(); // 綁定的服務(wù)器;sync 等待服務(wù)器關(guān)閉

System.out.println(EchoServer.class.getName() + " started and listen on " + future.channel().localAddress());

future.channel().closeFuture().sync(); // 關(guān)閉 channel 和 塊,直到它被關(guān)閉

} finally {

group.shutdownGracefully().sync(); // 關(guān)閉 EventLoopGroup,釋放所有資源。

}

}

public static void main(String[] args) throws Exception {

int port = 4567;

if (args.length == 1) {

port = Integer.parseInt(args[0]);

}

new EchoServer(port).start(); // 設(shè)計(jì)端口、啟動(dòng)服務(wù)器

}

}

客戶端代碼

客戶端要做的是:

連接服務(wù)器

發(fā)送消息

等待和接受服務(wù)器返回的消息

關(guān)閉連接

EchoClientHandler

繼承SimpleChannelInboundHandler來(lái)處理所有的事情,只需覆蓋三個(gè)方法:

channelActive() - 服務(wù)器的連接被建立后調(diào)用

channelRead0() - 從服務(wù)器端接受到消息調(diào)用

exceptionCaught() - 捕獲異常處理調(diào)用

@ChannelHandler.Sharable // @Sharable 標(biāo)記這個(gè)類的實(shí)例可以在channel里共享

public class EchoClientHandler extends SimpleChannelInboundHandler {

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8)); // 當(dāng)被通知該 channel 是活動(dòng)的時(shí)候就發(fā)送信息

}

@Override

protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {

System.out.println("Client received: " + byteBuf.toString(CharsetUtil.UTF_8)); // 記錄接收到的消息

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

// 記錄日志錯(cuò)誤并關(guān)閉 channel

cause.printStackTrace();

ctx.close();

}

}

EchoClient

通過Bootstrap引導(dǎo)創(chuàng)建客戶端,另外需要 host 、port 兩個(gè)參數(shù)連接服務(wù)器。

public class EchoClient {

private final String host;

private final int port;

public EchoClient(String host, int port) {

this.host = host;

this.port = port;

}

public void start() throws Exception {

EventLoopGroup group = new NioEventLoopGroup();

try {

Bootstrap bootstrap = new Bootstrap(); // 創(chuàng)建 Bootstrap

bootstrap.group(group) // 指定EventLoopGroup來(lái)處理客戶端事件。由于我們使用NIO傳輸,所以用到了 NioEventLoopGroup 的實(shí)現(xiàn)

.channel(NioSocketChannel.class) // 使用的channel類型是一個(gè)用于NIO傳輸

.remoteAddress(new InetSocketAddress(host, port)) // 設(shè)置服務(wù)器的InetSocketAddr

.handler(new ChannelInitializer() { // 當(dāng)建立一個(gè)連接和一個(gè)新的通道時(shí)。創(chuàng)建添加到EchoClientHandler實(shí)例到 channel pipeline

@Override

protected void initChannel(SocketChannel socketChannel) throws Exception {

socketChannel.pipeline().addLast(new EchoClientHandler());

}

});

ChannelFuture future = bootstrap.connect().sync(); // 連接到遠(yuǎn)程;等待連接完成

future.channel().closeFuture().sync(); // 阻塞到遠(yuǎn)程; 等待連接完成

} finally {

group.shutdownGracefully().sync(); // 關(guān)閉線程池和釋放所有資源

}

}

public static void main(String[] args) throws Exception {

final String host = "127.0.0.1";

final int port = 4567;

new EchoClient(host, port).start();

}

}

編譯和運(yùn)行 Echo

首先編譯、運(yùn)行服務(wù)端,會(huì)看到以下log:

me.icro.samples.echo.server.EchoServer started and listen on /0:0:0:0:0:0:0:0:4567

下一步是編譯、運(yùn)行客服端后,服務(wù)端會(huì)先接收到信息:

Server received: Netty rocks!

然后客戶端收到反饋:

Client received: Netty rocks!

總結(jié)

以上,構(gòu)建并運(yùn)行你的第一 個(gè)Netty 的客戶端和服務(wù)器。雖然這是一個(gè)簡(jiǎn)單的應(yīng)用程序,它可以擴(kuò)展到幾千個(gè)并發(fā)連接。

我們可以在Netty的Github倉(cāng)庫(kù)看到的更多 Netty 如何簡(jiǎn)化可擴(kuò)展和多線程的例子。

下一步的深入學(xué)習(xí),網(wǎng)上教程很多,大伙可以參考:

(完)

總結(jié)

以上是生活随笔為你收集整理的getbook netty实战_Netty 入门教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成年人免费视频网站 | 奇米影视第四色7777 | 亚洲综合另类 | 高跟肉丝丝袜呻吟啪啪网站av | 色翁荡息又大又硬又粗又爽 | 小视频在线播放 | 亚洲成人二区 | 日本三级黄色大片 | 成人免费毛片片v | 88av在线播放 | 日本免费观看视频 | 国产a一区二区三区 | 午夜精品999 | 椎名空在线播放 | 樱花动漫无圣光 | 国产精品一区二区久久久 | 亚洲一区二区三区在线 | 天堂av√| 国产人伦精品一区二区三区 | 性v天堂 | 欧美在线一二 | 精品视频在线观看一区 | 午夜影院入口 | 国产精品伦一区二区 | 黑人巨茎大战欧美白妇 | 国产黄a三级三级三级 | 裸体视频软件 | 日韩在线观看 | 色视频在线观看 | 99精品一区二区三区无码吞精 | 亚洲女人在线 | 2019亚洲天堂 | 亚洲人妖在线 | 精品人妻无码中文字幕18禁 | 国产精品久久久91 | 又黄又爽的视频 | 欧美乱码精品一区二区 | 亚洲图片一区二区三区 | 久久天堂视频 | 第一av在线 | 香蕉a视频| 青娱乐91| 国产婷婷一区二区三区久久 | 日韩精品电影 | 国产ts在线视频 | 在线观看的黄网 | 加勒比一区在线 | 777777av| 爱av在线 | 性av网| 国产精品精品久久久久久 | 国产精品国产av | 午夜精品一区二区三区在线观看 | 久久国产精品久久久久久 | 国产婷婷色一区二区三区 | 久久影视一区 | 抖音视频在线观看 | 在线观看免费高清在线观看 | 欧美888 | 水蜜桃亚洲精品 | 成年人免费观看视频网站 | 国产人免费人成免费视频 | 人人爱超碰 | 久久96| 欧美精品小视频 | 电家庭影院午夜 | 国产免费黄色小视频 | 国产a一级片 | 日本免费一区二区三区视频 | 特级一级黄色片 | 国产亚洲精品久久久久久久久动漫 | 欧美成人精品在线视频 | 性无码专区无码 | 午夜美女视频 | 久久精品视频一区二区三区 | 最新日韩视频 | 精品国模一区二区三区欧美 | 91视频国产一区 | 国产三级视频网站 | 国产精品精品久久久久久 | 乌克兰极品av女神 | 中文字幕在线观看国产 | 日本一区二区高清视频 | 国产成人毛片 | 国产视频www| 精品一区免费 | 午夜视频 | 亚洲一区高清 | 欧美sm视频 | 久久精品在线免费观看 | 国产真人无遮挡作爱免费视频 | 国产99视频在线观看 | 最近最新中文字幕 | 第一福利av| 国产高潮国产高潮久久久91 | 日本精品在线观看 | 五月婷婷激情四射 | 亚洲精品www. | 国产精品一区在线免费观看 |