本文介绍了Netty的核心API以及他们的使用。

Netty核心API介绍

ChannelHandler及其实现类

API关系如下:









«Interface»

ChannelHandler


ChannelHandlerAdapter

«Interface»

ChannelInboundHandler


ChannelInboundHandlerAdapter

«Interface»

ChannelOutboundHandler


ChannelOutboundHandlerAdapter


如果图片无法显示,请看这里

netty android使用 nettyapi详解_服务端

Netty开发中需要定义一个Handler类去实现ChannelHandler接口或其子类或其实现类,然后通过重写相关方法实现业务逻辑:

  • public void channelActive(ChannelHandlerContext ctx):通道就绪事件
  • public void read(ChannelHandlerContext ctx, Object msg):通道读取数据事件
  • public void readComplete(ChannelHandlerContext ctx):数据读取完毕事件
  • publi void exceptionCaught(ChannelHandlerContext ctx, Throwable cause):通道发生异常事件
ChannelPipline

ChannelPipline是一个handler集合,它负责处理和拦截inbound和outbound事件和操作,相当于一个贯穿Netty的责任链。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WNEw8ZsM-1651643410762)(https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220420120120457.png)]

如果客户端和服务端的handler是一样的,那么消息从客户端到服务端或者反过来,每个inbound类型或许outbound类型只会经过一次,混合类型(同时实现了inbound和outbound的handler)的handler会经过两次。

ChannelPipline中的每个ChannelHandlerContext中都含有一个ChannelHandler。

InboundHandler是按照Pipline的加载顺序顺序执行,OutboundHandler是按照Pipline的加载顺序逆序执行。

ChannelHandlerContext

事件处理器上下文对象,Pipline链中的实际处理节点。

每个处理节点ChannelhandlerContxet包含一个具体的处理器ChannelHandler,同时ChannelHandlerContext中也绑定了对应的ChannelPipline和Channel的信息,方便对ChannelHandler进行调用。常用方法如下:

  • ChannelFuture close():关闭通道
  • ChannelOutboundInvoker flush():刷新
  • ChannelFuture writeAndFlush(Object msg):将数据写入ChannelPipline中当前ChannelHandler的下一个ChannelHandler开始处理(出站)
ChannelOption

Netty在创建Channel实例后,一般都需要设置ChannelOption参数。

ChannelOption是socket的标准参数,不是Netty特有的。常见的参数如下:

  • ChannelOption.SO_BACKLOG:对应TCP/IP协议listen函数中的backlog参数,用来初始化服务器可连接队列大小。
    服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接。
    多个客户端来的时候,服务端将不能处理的客户端请求放在等待队列里,backlog参数指定了队列的大小。
  • ChannelOption.SO_KEEPALIVE:一直保存连接处于活动状态。该参数用于设置TCP连接。
    当设置该选项之后,会测试连接的状态,用于可能长时间没有数据交流的连接。
    当设置该选项后,如果两小时内没有数据通信时,TCP会自动发送一个活动探测数据报文。
ChannelFuture

表示Channel中异步I/O操作的结果。

在Netty中所有的I/O操作都是异步的,IO的调用会直接返回,调用者并不能立即获得结果,但是可以通过ChannelFuture来获取I/O操作的处理状态。

常用方法如下:

  • Channel channel():返回当前正在进行IO操作的通道
  • ChannelFuture sync():等待异步操作执行完毕,将异步改为同步
EventLoopGroup和实现类NioEventLoopGroup

EventLoopGroup是一组EventLoop的抽象,Netty为了更好的利用多核CPU的资源,一般会有多个EventLoop同时同工作,每个EventLoop维护着一个Selector对象。

EventLoopGroup提供next接口,可以从组里面按照一定规则,获取其中一个EventLoop来处理任务。

在Netty的服务端编程中,一般需要提供两个EventLoopGroup,例如:BossEventLoopGroup和WorkerEventLoopGroup。

通常一个服务端口就是一个ServerSocketChannel,对应一个Selector和一个EventLoop线程。

BossEventLoop负责接收客户端连接,并将SocketChannel交给WorkerEventLoopGroup进行I/O处理。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXFq82KD-1651643410762)(https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220420180506604.png)]

BossEventLoopGroup通常是一个单线程的EventLoop,EventLoop维护者一个注册了ServerSocketChannel的Selector实例。

BossEventLoop不断轮询Selector,将连接事件分离出来,通常是ON_ACCEPT事件,然后将接收到的SocketChannel交给WorkerEventLoopGroup。

WorkerEventLoopGroup会由next选择其中一个EventLoopGroup来讲这个SocketChannel注册到其维护的Selector,并对其后的IO事件进行处理。

一般情况下都是使用NioEventLoopGroup,常用方法如下:

  • public NioEventLoopGroup():构造方法,创建线程组
  • public Future<?> shutdownGracefully():断开连接,关闭线程
ServerBootStrap和Bootstrap

ServerBootstrap是Netty中的服务端启动助手,通过它可以完成服务端的各种配置。

Bootstrap是Netty中的客户端启动助手,通过它可以完成客户端的各种配置。常见方法如下:

  • public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup):用于服务端,用于设置两个EventLoop
  • public B group(EventLoopGroup group):用于客户端,用于设置一个EventLoop
  • public B channel(Class<? Extends C> channelClass):该方法用于设置服务端的通道实现
  • public B option(ChannelOption option, T value):用来给ServerChannel添加配置
  • public ServerBootstrap childOption(ChannelOption option, T value):用来给接收到的通道添加配置
  • public ServerBootstrap childHandler(ChannelHandler childHandler):该方法设置业务处理类,自定义Handler
  • public ChannelFuture bind(int inetPort):该方法用于服务端,用来设置占用的端口号
  • public ChannelFuture connect(String inetPort, int inetPort):该方法用于客户端,用于连接服务端
Unpooled类

这是Netty提供的一个专门用来操作缓冲区的工具类,常用方法如下:

  • public static ByteBuf copiedBuffer(CharSequence string, Charset charset):通过给定的数据和字符编码返回一个BuyeBuf对象,类似于NIO中的ByteBuffer对象。