Netty 執行流程分析與重要元件介紹
阿新 • • 發佈:2018-12-15
Netty的應用場景:
1、Netty可以作為RBC的通訊框架或是通訊的協議、通訊的庫,實現了遠端過程的呼叫,是基於socket的方式。這是在Netty開發裡面很大的應用場景。
2、Netty可以作為長連線的伺服器,就是基於websocket的長連線伺服器,實現伺服器與客戶端之間的長連線的通訊。
3、Netty還可以作為HTTP的伺服器,類似於Tomcat 等servlet容器。但是當它充當HTTP伺服器的時候,它的程式設計模型、獲取請求的引數等並不是基於servlet規範的。可以通過瀏覽器去訪問的。
一、使用者向伺服器傳送請求,伺服器返回一個helloworld的情景 (第三種應用場景)
1、channel :通道,相當於一個連線
2、channelHandler:通道的處理器,類似於處理器、攔截器這樣的概念。請求過來之後,會一個一個的通過channelHandler來得到一個一個的處理,處理之後交給業務方法完成真正的處理,然後按照相反的順序進行原路的返回
3、pipeline:管道。一個 pipeline是由多個channelHandler 構成的,構成管道的形式。請求過來的時候,會通過一個一個的處理器沿著管道不斷的往前走
程式碼:本人建立的是gradel的專案
①、build.gradle
plugins { id 'java' } group 'com.cxm' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile group: 'io.netty', name: 'netty-all', version: '4.1.29.Final' }
②、TestServer
package com.cxm.netty.firstexample; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * @Date: 2018/10/16 15:35 * @Description: 伺服器啟動程式碼 */ public class TestServer { public static void main(String[] args) throws Exception{ //定義兩個事件迴圈組 (兩個執行緒組) //NioEventLoopGroup()可以理解為死迴圈。不斷的接受客戶端發起的連線,連線進來之後對連線進行處理,緊接著迴圈繼續執行 // boosGroup --》執行緒組不斷的從客戶端那邊接受連線,但是不對連線做任何的處理,直接傳給worker // workerGroup --》執行緒組接收到boosGroup傳過來的連線,真正的完成對連線的處理。例如獲取連線的引數,進行實際的業務處理,把結果返回給客戶端 EventLoopGroup boosGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ //ServerBootstrap 服務端啟動,他實際上是一個比較方便的輕鬆的啟動服務端的類 ServerBootstrap serverBootstrap = new ServerBootstrap(); // childHandler 子處理器 自己編寫的處理器,請求到來時,有我們編寫的處理器進行處理。 serverBootstrap.group(boosGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); }finally { //優雅的關閉 boosGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
③、TestServerInitializer
package com.cxm.netty.firstexample;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
/**
* @Date: 2018/10/16 16:00
* @Description: 初始化器
*/
public class TestServerInitializer extends ChannelInitializer<SocketChannel> {
//連線被建立之後會立刻執行 initChannel 回撥方法
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//pipeline 是 根據業務請求完成處理
ChannelPipeline pipeline = ch.pipeline();
//在最後新增 自定義的若干個處理器
pipeline.addLast("httpServerCodec ",new HttpServerCodec());
//新增自定義的處理器
pipeline.addLast("testHttpServerHandler",new TestHttpServerHandler());
}
}
④、TestHttpServerHandler
package com.cxm.netty.firstexample;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
/**
* @Date: 2018/10/16 16:08
* @Description: 定義自己的處理器
*/
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
//channelRead0 ---》 讀取客戶端傳送過來真正的請求,並且向客戶端返回響應
//相當於 messageReceived
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest){
//構造響應的字串
ByteBuf byteBuffer = Unpooled.copiedBuffer("Hello World" , CharsetUtil.UTF_8);
//構造響應
FullHttpResponse response =new DefaultFullHttpResponse(HttpVersion.HTTP_1_1 , HttpResponseStatus.OK,content);
//設定 Response 頭資訊
response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text_plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());
//返回給客戶端的response物件
ctx.writeAndFlush(response);
}
}
}
執行:
執行TestServer, Linux開啟 curl 'http://localhost:8899';就會出現
執行流程:
1、首先會啟動 Bootstrap 伺服器,伺服器裡面會關聯兩個事件迴圈組(boosGroup,workerGroup)
2、在伺服器啟動的時候呢,會關聯一個相應的處理器childHandler
3、在childHandler 裡面定義的處理器 TestServerInitializer ,回撥方法裡面定義的若干個自定義的處理器,
也可以定義Netty本身內建的ChannelHandler,按照順序往下走,
最終會走到我們自己提供的一個處理器TestHttpServerHandler,然後返回結果給客戶端。
以上就是最基本的入門程式!!
用網站來請求,他會請求你網站的圖示,就如圖的 favicon.ico