Netty是什么?
Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。
Netty 是一个广泛使用的 Java 网络编程框架(Netty 在 2011 年获得了Duke’s Choice Award,见https://www.java.net/dukeschoice/2011)。它活跃和成长于用户社区,像大型公司 Facebook 和 Instagram 以及流行 开源项目如 Infinispan, HornetQ, Vert.x, Apache Cassandra 和 Elasticsearch 等,都利用其强大的对于网络抽象的核心代码。
搭建
我们用maven搭建项目
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.45.Final</version>
</dependency>
首先从maven仓库中引入maven包。
我们新建两个组,一个是boss组,一个是worker组
下面是编写的一个Server端,可以看到netty的编写风格属于建造者模式一类,也就是说链式调用,调用起来一直的点下去也是非常的清爽,底层实现我还没深究,大家可以和我探讨。
public static void main(String[] args) {
//新建boss组
EventLoopGroup bossGroup = new NioEventLoopGroup();
//新建员工组
EventLoopGroup workGroup = new NioEventLoopGroup();
//服务器启动组件
ServerBootstrap serverBootstrap = new ServerBootstrap();
try {
//将boss组和员工组并入启动组件中
serverBootstrap.group(bossGroup, workGroup)
//channel类型为NioServerSocketChannel
.channel(NioServerSocketChannel.class)
//自定义处理器(我们先赋个空值)
.childHandler(null);
ChannelFuture channelFuture = serverBootstrap
//绑定端口 案例中我绑定到了8088
.bind(8088)
//同步处理
.sync();
//关闭channel
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//优雅的关闭两个组
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
自定义handler
public class ServerInitial extends ChannelInitializer<NioServerSocketChannel> {
@Override
protected void initChannel(NioServerSocketChannel ch) throws Exception {
ChannelPipeline channelPipeline = ch.pipeline();
channelPipeline.addLast("HttpServerCodec",new HttpServerCodec());
channelPipeline.addLast("ServerHandler",new ServerHandler());
}
public class ServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
//从上下文中获取channel
Channel channel = ctx.channel();
//输出远程地址
System.out.println("remote Address:" + channel.remoteAddress());
//ByteBuf是netty数据包,我们给它定义个字符串,编码格式为UTF-8
ByteBuf content = Unpooled.copiedBuffer("Hello Netty", CharsetUtil.UTF_8);
//设置httpVersion,响应状态码,内容
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK,
content);
//响应头设置内容类别为 text/plain(也就是说支持各种格式,text/html啦,text/javascript啦,
//application/json之类的
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
//响应头设置内容长度数据内容为可读字节
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
//写入响应到浏览器中
ctx.writeAndFlush(response);
}
}
}
这样,我们就可以完成一个简单的netty服务器了
没有问题,8088端口有响应。
在cmd状态下输入curl localhost:8088的时候,也没问题,正常响应。
chrome浏览器下的表现如图
我们开始的时候设置的response参数也起了作用。
但是打开idea控制台的时候我们会发现,
请求一次居然有了四个输出,我们可以在输出远程地址的时候加个判断,判断是否和HttpRequest的对象类型一致,也就是说,判断其是不是浏览器发出的请求
if (msg instanceof HttpRequest) {
//输出远程地址
System.out.println("remote Address:" + channel.remoteAddress());
}
重启一遍发现输出变为2个。
在SimpleChannelHandlerInbound中,我们可以覆写好多方法
这些方法一定含义上表达了一段生命周期,后面再说,