Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

## Reactor模式

Netty 那些事儿 ——— Reactor模式详解

Netty Reactor 工作架构图

## bind() 方法

### AbstractNioChannel

io.netty.channel.nio.AbstractNioChannel#AbstractNioChannel

io.netty.channel.AbstractChannel

### NioServerSocketChannelConfig

io.netty.channel.DefaultChannelConfig

### AdaptiveRecvByteBufAllocator

io.netty.channel.AdaptiveRecvByteBufAllocator

The RecvByteBufAllocator that automatically increases and decreases the predicted buffer size on feed back.
It gradually increases the expected number of readable bytes if the previous read fully filled the allocated buffer. It gradually decreases the expected number of readable bytes if the read operation was not able to fill a certain amount of the allocated buffer two times consecutively. Otherwise, it keeps returning the same prediction.

### Pipeline

io.netty.channel.AbstractChannel

io.netty.channel.DefaultChannelPipeline#DefaultChannelPipeline

### ChannelPipeline

io.netty.channel.ChannelPipeline

A list of ChannelHandlers which handles or intercepts inbound events and outbound operations of a Channel. ChannelPipeline implements an advanced form of the Intercepting Filter pattern to give a user full control over how an event is handled and how the ChannelHandlers in a pipeline interact with each other.

Creation of a pipeline

Each channel has its own pipeline and it is created automatically when a new channel is created.

How an event flows in a pipeline

The following diagram describes how I/O events are processed by ChannelHandlers in a ChannelPipeline typically. An I/O event is handled by either a ChannelInboundHandler or a ChannelOutboundHandler and be forwarded to its closest handler by calling the event propagation methods defined in ChannelHandlerContext, such as ChannelHandlerContext.fireChannelRead(Object) and ChannelHandlerContext.write(Object).

An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the diagram. The inbound data is often read from a remote peer via the actual input operation such as SocketChannel.read(ByteBuffer). If an inbound event goes beyond the top inbound handler, it is discarded silently, or logged if it needs your attention.

An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests. If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the Channel. The I/O thread often performs the actual output operation such as SocketChannel.write(ByteBuffer)

For example, let us assume that we created the following pipeline:

In the example above, the class whose name starts with Inbound means it is an inbound handler. The class whose name starts with Outbound means it is a outbound handler.

In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound. When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle, ChannelPipeline skips the evaluation of certain handlers to shorten the stack depth:

• 3 and 4 don’t implement ChannelInboundHandler, and therefore the actual evaluation order of an inbound event will be: 1, 2, and 5.
• 1 and 2 don’t implement ChannelOutboundHandler, and therefore the actual evaluation order of a outbound event will be: 5, 4, and 3.
• If 5 implements both ChannelInboundHandler and ChannelOutboundHandler, the evaluation order of an inbound and a outbound event could be 125 and 543 respectively.

Forwarding an event to the next handler

As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in ChannelHandlerContext to forward an event to its next handler. Those methods include:

• Inbound event propagation methods
• ChannelHandlerContext.fireChannelRegistered()
• hannelHandlerContext.fireChannelActive()
• ChannelHandlerContext.fireChannelRead(Object)
• ChannelHandlerContext.fireChannelReadComplete()
• ChannelHandlerContext.fireExceptionCaught(Throwable)
• ChannelHandlerContext.fireUserEventTriggered(Object)
• ChannelHandlerContext.fireChannelWritabilityChanged()
• ChannelHandlerContext.fireChannelInactive()
• ChannelHandlerContext.fireChannelUnregistered()
• Outbound event propagation methods:
• ChannelHandlerContext.bind(SocketAddress, ChannelPromise)
• ChannelHandlerContext.connect(SocketAddress, SocketAddress, ChannelPromise)
• ChannelHandlerContext.write(Object, ChannelPromise)
• ChannelHandlerContext.flush()
• ChannelHandlerContext.read()
• ChannelHandlerContext.disconnect(ChannelPromise)
• ChannelHandlerContext.close(ChannelPromise)
• ChannelHandlerContext.deregister(ChannelPromise)

and the following example shows how the event propagation is usually done:

Building a pipeline (重点)

A user is supposed to have one or more ChannelHandlers in a pipeline to receive I/O events (e.g. read) and to request I/O operations (e.g. write and close). For example, a typical server will have the following handlers in each channel’s pipeline, but your mileage may vary depending on the complexity and characteristics of the protocol and business logic:

• Protocol Decoder - translates binary data (e.g. ByteBuf) into a Java object.
• Protocol Encoder - translates a Java object into binary data.
• Business Logic Handler - performs the actual business logic (e.g. database access).

and it could be represented as shown in the following example:

Thread safety

A ChannelHandler can be added or removed at any time because a ChannelPipeline is thread safe. For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it after the exchange.

## init() 方法

io.netty.bootstrap.ServerBootstrap#init

### ChannelOption

io.netty.channel
public class ChannelOption
extends AbstractConstant>

A ChannelOption allows to configure a ChannelConfig in a type-safe way. Which ChannelOption is supported depends on the actual implementation of ChannelConfig and may depend on the nature of the transport it belongs to.

Type parameters:

- the type of the value which is valid for the ChannelOption

ChannelOption <T> 主要维护 TCP/IP 的一些底层的设定，T 表示值的类型

ChannelOption 继承了 AbstractConstantAbstractConstant 有是 Constant 的一个基本的实现

io.netty.util.Constant

io.netty.util
public interface Constant>
extends Comparable

A singleton which is safe to compare via the == operator. Created and managed by ConstantPool.

Type parameters:

- the type of objects that this object may be compared to

io.netty.util.ConstantPool

io.netty.util.ConstantPool#newConstant

### AttributeKey

io.netty.util.AttributeKey

io.netty.util
public final class AttributeKey
extends AbstractConstant>

Key which can be used to access Attribute out of the AttributeMap. Be aware that it is not be possible to have multiple keys with the same name.

Type parameters:

- the type of the Attribute which can be accessed via this AttributeKey.

### ChannelInitializer

io.netty.bootstrap.ServerBootstrap#init

io.netty.channel.ChannelInitializer

io.netty.channel
@Sharable
public abstract class ChannelInitializer
extends ChannelInboundHandlerAdapter

A special ChannelInboundHandler which offers an easy way to initialize a Channel once it was registered to its EventLoop. Implementations are most often used in the context of Bootstrap.handler(ChannelHandler) , ServerBootstrap.handler(ChannelHandler) and ServerBootstrap.childHandler(ChannelHandler) to setup the ChannelPipeline of a Channel.

>

Be aware that this class is marked as ChannelHandler.Sharable and so the implementation must be safe to be re-used.

Type parameters:

- A sub-type of Channel

## addLast() 方法

io.netty.channel.DefaultChannelPipeline#addLast

AbstractChannelHandlerContext 定义了一个上下文，找到实现的一个接口 ChannelHandlerContext

io.netty.channel.ChannelHandlerContext

-------------本文结束感谢您的阅读-------------

0%