Netty学习笔记(一)
1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式。
2.netty5废弃原因,ForkJoinPool使netty开发复杂且性能提升不高。
3.netty大纲深度解读--本节内容:
了解google protobuf:Protocol Buffers\thrift\http\websocket这些概念
书籍推荐netty in action
4.项目环境搭建秘Gradle配置--本节内容
学习方法:先对整体了解,再去研究局部
Gradle:简洁,强大,灵活 推荐使用
Gradle安装方法:
1.下载
2.设置环境变量
For running Gradle, firstly add the environment variable GRADLE_HOME. This should point to the unpacked files from the Gradle website. Next add GRADLE_HOME/bin to your PATH environment variable. Usually, this is sufficient to run Gradle.
5.Netty执行流程分析与重要组件介绍--本节内容
本节实现了一个hello world例子,例子开始之前,我先把原理说一下(个人理解):
Netty服务器通过监听通道发来的请求,并处理返回;在启动之前 ,要创建好处理请求的Event,同时定义监听的端口及处理请求的handler,最后关闭。具体 看代码
build.gradle文件
plugins { id 'java' } group 'com.nettydemo' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { //mavenCentral() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } dependencies { compile( "io.netty:netty-all:4.1.0.Final" ) }
TestServer.java
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; public class TestServer { public static void main(String[] args) throws InterruptedException { //接收客户端的请求,分配给workGroup EventLoopGroup bossGroup = new NioEventLoopGroup(); //真正的对连接处理的是workGroup EventLoopGroup workGroup = new NioEventLoopGroup(); try{ //简化服务端启动 ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class) .childHandler(new TestServerInitializer());//自定义的handler ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } }
TestServerInitializer.java
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpServerCodec; public class TestServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("httpServerCodec",new HttpServerCodec());//非单例 pipeline.addLast("testHttpServerHandler",new TestHttpServerHandler()); } }
TestHttpServerHandler.java
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; public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> { @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { //读取客户端发来的请求,并返回响应 ByteBuf content = Unpooled.copiedBuffer("Hello World!", CharsetUtil.UTF_8);//向客户端返回的数据 FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,content); response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes()); ctx.writeAndFlush(response); } }
...