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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Netty框架入门

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

一、概述

? ??Netty是由JBOSS提供的一個java開源框架。

????Netty提供異步的、事件驅動的網絡應用程序框架和工具,用以快速開發高性能、高可靠性的網絡服務器和客戶端程序。

?

二、體系結構圖

?  

三、Netty的核心結構

????Netty是典型的Reactor模型結構,在實現上,Netty中的Boss類充當mainReactor,NioWorker類充當subReactor(默認NioWorker的個數是當前服務器的可用核數)。

????在處理新來的請求時,NioWorker讀完已收到的數據到ChannelBuffer中,之后觸發ChannelPipeline中的ChannelHandler流。

????Netty是事件驅動的,可以通過ChannelHandler鏈來控制執行流向。因為ChannelHandler鏈的執行過程是在subReactor中同步的,所以如果業務處理handler耗時長,將嚴重影響可支持的并發數。

?  

四、客戶端和服務器端通信Demo

????Server-main:

ChannelFactory factory = new?NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());

ServerBootstrap bootstrap = new?ServerBootstrap(factory);

bootstrap.setPipelineFactory(new?ChannelPipelineFactory(){?

????@Override

????public?ChannelPipeline getPipeline() throws Exception {

????????return?Channels.pipeline(new?TimeServerHandler());

????}

});

bootstrap.setOption("child.tcpNoDelay", true);

bootstrap.setOption("child.keepAlive", true);

bootstrap.bind(new?InetSocketAddress(1989));

????ChannelFactory 是一個創建和管理Channel通道及其相關資源的工廠接口,它處理所有的I/O請求并產生相應的I/O ChannelEvent通道事件。這個工廠并自己不負責創建I/O線程。應當在其構造器中指定該工廠使用的線程池,這樣我們可以獲得更高的控制力來管理應用環境中使用的線程。

????ServerBootstrap 是一個設置服務的幫助類。設置了一個繼承自ChannelPipelineFactory的匿名類,用來作為ChannelPipeline通道,當服務器接收到一個新的連接,一個新的ChannelPipeline管道對象將被創建,并且所有在這里添加的ChannelHandler對象將被添加至這個新的ChannelPipeline管道對象。

????Server-Handler:

@Override

public?void?channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws?Exception {

????//TimeServer???

????Channel ch = e.getChannel();

????ChannelBuffer time = ChannelBuffers.buffer(8);

????time.writeLong(System.currentTimeMillis());

????ChannelFuture future = ch.write(time);?

????future.addListener(new?ChannelFutureListener() {???????

????????@Override??????

????????public?void?operationComplete(ChannelFuture arg0) throws?Exception {???????

????????????Channel ch = arg0.getChannel();

????????????ch.close();

????????}

????});

}

????Handler中是我們的業務邏輯,在Server的Handler里重載了channelConnected方法,當收到連接請求時,將當前服務器時間寫入到Channel,并且在寫完后觸發關閉Channel。


????Client-main:

ChannelFactory factory = new?NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());

ClientBootstrap bootstrap = new?ClientBootstrap(factory);

bootstrap.setPipelineFactory(new?ChannelPipelineFactory() {

????@Override??

????public?ChannelPipeline getPipeline() throws?Exception {

????????return?Channels.pipeline(new?TimeClientHandler());

????}

});

bootstrap.setOption("tcpNoDelay",true);

bootstrap.setOption("keepAlive", true);

bootstrap.connect(new?InetSocketAddress("127.0.0.1", 1989));

????Client端初始化Netty的過程和Server類似,只是將使用到的類替換為Client端的。
????Client-Handler:

@Override

public?void?messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws?Exception {

????ChannelBuffer buf = (ChannelBuffer)e.getMessage();

????Long currentTimeMillis = buf.readLong();

????System.out.println(new?Date(currentTimeMillis));

????e.getChannel().close();

}

????Client端的Handler里,我們將從服務器端接收到的信息轉換為時間打印到控制臺。

?

五、基于HTTP協議的服務器端實現

//HttpServerPipelineFactory.java

public?class?HttpServerPipelineFactory implements?ChannelPipelineFactory {

????@Override

????public?ChannelPipeline getPipeline() throws?Exception {

????????ChannelPipeline pipeline = Channels.pipeline();

????????pipeline.addLast("decoder", new?HttpRequestDecoder());

????????pipeline.addLast("encoder", new?HttpResponseEncoder());

????????pipeline.addLast("handler", new?HttpServerHandler());

????????return?pipeline;

????}

}

????新建一個HttpServerPipelineFactory類,在getPipeline()方法中添加了對Http協議的支持。

// HttpServer.java

bootstrap.setPipelineFactory(new?HttpServerPipelineFactory());

????在Server里面使用我們新建的HttpServerPipelineFactory。

//HttpServerHandler.java

public?void?messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws?Exception {

????DefaultHttpRequest defaultHttpRequest = (DefaultHttpRequest)e.getMessage();

????String uri = defaultHttpRequest.getUri();

????byte[] data = defaultHttpRequest.getContent().array();

????String content = URLDecoder.decode(new?String(data),"utf-8").trim();

????System.out.println(uri+"|"+content);

????Channel ch = e.getChannel();

????HttpResponse response = new?DefaultHttpResponse(HTTP_1_1, OK);

????ChannelBuffer buffer = new?DynamicChannelBuffer(2048);

????buffer.writeBytes("200".getBytes("UTF-8"));

????response.setContent(buffer);

????response.setHeader("Content-Type", "text/html;charset=UTF-8");

????response.setHeader("Content-Length", response.getContent().writerIndex());

????if?(ch.isOpen() && ch.isWritable()) {??

????????ChannelFuture future = ch.write(response);?

????????future.addListener(new?ChannelFutureListener() {???????

????????????@Override??????

????????????public?void?operationComplete(ChannelFuture arg0) throws?Exception {???????????

????????????????Channel ch = arg0.getChannel();????????

????????????????ch.close();

????????????}??

????????});

????}

}

????在Handler里面我們可以直接拿到DefaultHttpRequest類型的對象,因為Netty已經用HttpRequestDecoder幫我們把接受到的數據都轉換為HttpRequest類型了。

????使用了多個Handler后,通過下圖,Netty的事件驅動就可以被很好的理解了:

  

????UpstreamEvent是被UpstreamHandler們自底向上逐個處理,DownstreamEvent是被DownstreamHandler們自頂向下逐個處理,這里的上下關系就是向ChannelPipeline里添加Handler的先后順序關系。

?

六、總結

????Netty是一個簡單卻不失強大的架構。這個架構由三部分組成——緩沖(Buffer)、通道(Channel)、事件模型(Event Model)——所有的高級特性都構建在這三個核心組件之上。

?

七、深入學習

????http://netty.io/

????https://github.com/netty/netty

from:?https://www.cnblogs.com/baronzhao/p/netty_1.html

總結

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

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