Netty学习三:Netty框架之引导器

一、基于Netty搭建简单的Http服务器

基于Netty搭建简单得Http服务器,只需要创建服务启动类和业务逻辑处理类即可

服务启动类
public class HttpServer {
  public void start(int port) throws Exception {
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
      ServerBootstrap b = new ServerBootstrap();
      b.group(bossGroup, workerGroup)
          .channel(NioServerSocketChannel.class)
          .localAddress(new InetSocketAddress(port))
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) {
              ch.pipeline()
                  .addLast("codec", new HttpServerCodec())         // HTTP 编解码
                  .addLast("compressor", new HttpContentCompressor())   // HttpContent 压缩
                  .addLast("aggregator", new HttpObjectAggregator(65536)) // HTTP 消息聚合
                  .addLast("handler", new HttpServerHandler());      // 自定义业务逻辑处理器
            }
          })
          .childOption(ChannelOption.SO_KEEPALIVE, true);
      ChannelFuture f = b.bind().sync();
      System.out.println("Http Server started, Listening on " + port);
      f.channel().closeFuture().sync();
    } finally {
      workerGroup.shutdownGracefully();
      bossGroup.shutdownGracefully();
    }
  }
  
  public static void main(String[] args) throws Exception {
    new HttpServer().start(8088);
  }
}
业务逻辑处理类
public class HttpServerHandler extends SimpleChannelInboundHandler&lt;FullHttpRequest&gt; {
  @Override
  protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) {
    String content = String.format("Receive http request, uri: %s, method: %s, content: %s%n", msg.uri(), msg.method(), msg.content().toString(CharsetUtil.UTF_8));
    FullHttpResponse response = new DefaultFullHttpResponse(
        HttpVersion.HTTP_1_1,
        HttpResponseStatus.OK,
        Unpooled.wrappedBuffer(content.getBytes()));
    ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
  }
}
测试:
  • 启动 HttpServer 的 main 函数。
  • 终端或浏览器发起 HTTP 请求。
$ curl http://localhost:8088/abc
$ Receive http request, uri: /abc, method: GET, content:

二、引导器实践指南

Netty服务端的启动过程大致分为:

  • 配置线程池
  • Channel初始化
  • 端口绑定
1. 配置线程池

通过参数设置,可以支持三种Reactor模式:单线程模型、多线程模型、主从多线程模型

  • 单线程模型:所有I/O操作由一个线程完成,只启动一个EventLoopGroup线程池,线程池类只有一个EventLoop线程
EventLoopGroup group = new NioEventLoopGroup(1);
ServerBootstrap b = new ServerBootstrap();
b.group(group)
  • 多线程模型:与单线程类似,但EventLoopGroup不需要参数,默认启动2倍CPU核数的EventLoop线程,也至此自定义线程数
EventLoopGroup group = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(group)
  • 主从多线程模型:Boss 是主 Reactor,Worker 是从 Reactor。它们分别使用不同的 NioEventLoopGroup,主 Reactor 负责处理 Accept,然后把 Channel 注册到从 Reactor 上,从 Reactor 主要负责 Channel 生命周期内的所有 I/O 事件。
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
2. Channel初始化

NIO 模型是 Netty 中最成熟且被广泛使用的模型。因此,推荐 Netty 服务端采用NioServerSocketChannel 作为 Channel 的类型,客户端采用 NioSocketChannel。

通过childHandler()方法注册ChannelHandler。ChannelInitializer是实现了 ChannelHandler接口的匿名类,通过实例化 ChannelInitializer 作为 ServerBootstrap 的参数。

ChannelInitializer的initChannel()绑定提个PipeLine,用于服务编排。向PipeLine中按顺序添加多个ChannelHandler。

通过option()和childOption()方法设置Channel属性,option 主要负责设置 Boss 线程组,而 childOption 对应的是 Worker 线程组。Netty 提供了默认参数设置ChannelOption,具体参数参考:
https://www.cnblogs.com/googlemeoften/p/6082785.html

3. 端口绑定

完成Netty配置后,bind() 方法会真正触发启动,sync() 方法则会阻塞,直至整个启动过程完成。

三、Netty实现HTTP客户端

public class HttpClient {
  public void connect(String host, int port) throws Exception {
    EventLoopGroup group = new NioEventLoopGroup();
    try {
      Bootstrap b = new Bootstrap();
      b.group(group);
      b.channel(NioSocketChannel.class);
      b.option(ChannelOption.SO_KEEPALIVE, true);
      b.handler(new ChannelInitializer&lt;SocketChannel&gt;() {
        @Override
        public void initChannel(SocketChannel ch) {
          ch.pipeline().addLast(new HttpResponseDecoder());
          ch.pipeline().addLast(new HttpRequestEncoder());
          ch.pipeline().addLast(new HttpClientHandler());
        }
      });
      ChannelFuture f = b.connect(host, port).sync();
      URI uri = new URI("http://127.0.0.1:8088");
      String content = "hello world";
      DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
          uri.toASCIIString(), Unpooled.wrappedBuffer(content.getBytes(StandardCharsets.UTF_8)));
      request.headers().set(HttpHeaderNames.HOST, host);
      request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
      request.headers().set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());
      f.channel().write(request);
      f.channel().flush();
      f.channel().closeFuture().sync();
    } finally {
      group.shutdownGracefully();
    }
  }
  
  public static void main(String[] args) throws Exception {
    HttpClient client = new HttpClient();
    client.connect("127.0.0.1", 8088);
  }
}

public class HttpClientHandler extends ChannelInboundHandlerAdapter {
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) {
    if (msg instanceof HttpContent) {
      HttpContent content = (HttpContent) msg;
      ByteBuf buf = content.content();
      System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));
      buf.release();
    }
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Netty入门实战: 仿写微信IM即时通讯系统》是一本关于网络编程框架Netty的实践指南。本书以仿写微信IM即时通讯系统为例,通过实际的项目案例引导读者学习和掌握Netty的使用。 Netty是一款基于Java的网络编程框架,提供了高性能、异步、事件驱动的特性。在本书中,作者基于Netty框架,通过分析微信IM即时通讯系统的架构和功能需求,逐步引入Netty的概念和使用方法。 首先,本书介绍了Netty的基本概念和工作原理,解释了Netty的事件驱动模型以及异步IO操作的优势。接着,读者会学习到如何使用Netty构建网络服务和客户端,以及如何处理网络通信中的数据包、编解码、心跳检测等问题。同时,本书也强调了Netty在高并发情况下的性能优势,示范了如何使用Netty进行性能优化和扩展。 通过跟随本书的实例代码,读者将逐步了解和掌握Netty的各项功能和使用方法。同时,通过仿写微信IM即时通讯系统的实践项目,读者也能够更好地理解Netty框架在实际项目中的应用场景和解决方案。 总而言之,《Netty入门实战: 仿写微信IM即时通讯系统》通过实际案例的方式,帮助读者深入理解Netty框架的使用和原理,并将其应用于实际的项目中。无论是对于新手还是有一定经验的开发者来说,本书都是一个很好的学习和实践指南,能够帮助读者快速入门和提升自己在网络编程领域的技能水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值