Netty笔记(1)-入门

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搭建项目

    
    <dependency>
      <groupId>io.nettygroupId>
      <artifactId>netty-allartifactId>
      <version>4.1.45.Finalversion>
    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服务器了
Netty笔记(1)-入门_第1张图片
没有问题,8088端口有响应。
Netty笔记(1)-入门_第2张图片
在cmd状态下输入curl localhost:8088的时候,也没问题,正常响应。
chrome浏览器下的表现如图
Netty笔记(1)-入门_第3张图片
我们开始的时候设置的response参数也起了作用。
但是打开idea控制台的时候我们会发现,
Netty笔记(1)-入门_第4张图片
请求一次居然有了四个输出,我们可以在输出远程地址的时候加个判断,判断是否和HttpRequest的对象类型一致,也就是说,判断其是不是浏览器发出的请求

  if (msg instanceof HttpRequest) {
            //输出远程地址
            System.out.println("remote Address:" + channel.remoteAddress());
        }

重启一遍发现输出变为2个。
在SimpleChannelHandlerInbound中,我们可以覆写好多方法
Netty笔记(1)-入门_第5张图片
这些方法一定含义上表达了一段生命周期,后面再说,
Netty笔记(1)-入门_第6张图片

你可能感兴趣的:(netty)