写在前面
章节结构遵循netty-all.jar的结构,netty版本:4.1.48。并不是全部类均进行覆盖,我只挑基础的,有助于理解Netty的来写,而且,仅是分析这个类,这个方法干嘛,不一定会探究它的实现,而且我介于目前还有课程,所以不一定会每天更新,我会尽可能快的完成此文,请知悉。
此文主要是面向有一定Netty使用基础的人,对于新手可能有一定难度。鄙人能力有限,如果你发现了什么错误,请私信我,在这里表示万分感谢!愿我们可以共同进步。
需要的知识
a) Netty使用基础
b) Java SE 8.0+
io.netty
bootstrap
Bootstrap
用来为客户端启动一个Channel。
public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
// ...
}
AbstractBootstrap
是一个辅助类,辅助Bootstrap,支持链式方法调用。当不在ServerBootstrap上下文使用时,它对于无状态连接,比如数据报(UDP)就很有用。
buffer
channel
EventExecutorGroup
EventExecutorGroup是一个封装了ScheduledExecutorService的线程池,为事件处理提供线程支持,就是Netty的线程池的意思,没啥特殊的,作者造的轮子,懂吧?
public interface EventExecutorGroup extends ScheduledExecutorService, Iterable<EventExecutor> {
boolean isShuttingDown();
Future<?> shutdownGracefully();
Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit);
Future<?> terminationFuture();
@Override
@Deprecated
void shutdown();
@Override
@Deprecated
List<Runnable> shutdownNow();
EventExecutor next();
@Override
Iterator<EventExecutor> iterator();
@Override
Future<?> submit(Runnable task);
@Override
<T> Future<T> submit(Runnable task, T result);
@Override
<T> Future<T> submit(Callable<T> task);
@Override
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
@Override
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
@Override
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
@Override
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
}
EventExecutor
是扩展了EventExecutorGroup的一个类,除去EventExecuorGroup对于为事件提供线程支持的那些方法外,还提供了:next():一个指向自己的引用;parent():一个指向它的EventExecutorGroup父类的引用;剩下的方法看注释。
public interface EventExecutor extends EventExecutorGroup {
/**
* Returns a reference to itself.
*/
@Override
EventExecutor next();
/**
* Return the {@link EventExecutorGroup} which is the parent of this {@link EventExecutor},
*/
EventExecutorGroup parent();
/**
* Calls {@link #inEventLoop(Thread)} with {@link Thread#currentThread()} as argument
*/
boolean inEventLoop();
/**
* Return {@code true} if the given {@link Thread} is executed in the event loop,
* {@code false} otherwise.
*/
boolean inEventLoop(Thread thread);
/**
* Return a new {@link Promise}.
*/
<V> Promise<V> newPromise();
/**
* Create a new {@link ProgressivePromise}.
*/
<V> ProgressivePromise<V> newProgressivePromise();
/**
* Create a new {@link Future} which is marked as succeeded already. So {@link Future#isSuccess()}
* will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
* every call of blocking methods will just return without blocking.
*/
<V> Future<V> newSucceededFuture(V result);
/**
* Create a new {@link Future} which is marked as failed already. So {@link Future#isSuccess()}
* will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
* every call of blocking methods will just return without blocking.
*/
<V> Future<V> newFailedFuture(Throwable cause);
}

EventLoop
会处理一个已经注册的Channel的所有IO操作。
public interface EventLoop extends OrderedEventExecutor, EventLoopGroup {
@Override
EventLoopGroup parent();
}
这里重写的parent()会返回它所继承的EventLoopGroup父类。

EventLoopGroup
是一个EventLoop集合,包含多个EventLoop用于处理IO操作。除去线程操作,只有三个方法,next():获取一个EventLoop用于处理IO事件,register()用于注册一个管道流或注册一个带有管道流的ChannelPromise。注意,注册实际上是注册给EventLoopGroup的众多EventLoop之一的,而不是注册给EventLoopGroup,它只是一个壳,并不能轮询事件并处理。
它的继承者有很多,除去对于它的针对于各种场景的实现外,就只剩EventLoop了。
public interface EventLoopGroup extends EventExecutorGroup {
/**
* Return the next {@link EventLoop} to use
*/
@Override
EventLoop next();
/**
* Register a {@link Channel} with this {@link EventLoop}. The returned {@link ChannelFuture}
* will get notified once the registration was complete.
*/
ChannelFuture register(Channel channel);
/**
* Register a {@link Channel} with this {@link EventLoop} using a {@link ChannelFuture}. The passed
* {@link ChannelFuture} will get notified once the registration was complete and also will get returned.
*/
ChannelFuture register(ChannelPromise promise);
/**
* Register a {@link Channel} with this {@link EventLoop}. The passed {@link ChannelFuture}
* will get notified once the registration was complete and also will get returned.
*
* @deprecated Use {@link #register(ChannelPromise)} instead.
*/
@Deprecated
ChannelFuture register(Channel channel, ChannelPromise promise);
}

接下来我们来看看它们的实现类,以NioEventLoopGroup为例(其他的都差不多)
NioEventLoopGroup

用于处理基于Nio的Channel。
AbstractEventExecutorGroup
提供了EventExecutorGroup的基本实现,在此我们不看源码,只要知道它对于EventExecutorGroup的实现是通过调用next()方法获取一个EventLoop实例然后进行处理,比如submit()或schedule()再或者关闭操作以及invokeAll()等。所有的对于EventExecutor的实现都是通过获取EventLoop来实现的。
MultithreadEventExecutorGroup
MultithreadEventExecutorGroup增加了一个EventExecutor数组,一个EventExecutor集合,一个用来记录被终止线程个数的原子整数,一个失败通知器(搭配原子整数进行是否失败检测),一个带有某一种策略的选择器(选择一个EventExecutor)。
public abstract class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup {
private final EventExecutor[] children;
private final Set<EventExecutor> readonlyChildren;
private final AtomicInteger terminatedChildren = new AtomicInteger();
private final Promise<?> terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);
private final EventExecutorChooserFactory.EventExecutorChooser chooser;
// 构造器有好几个,直接看最终那个
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
if (executor == null) {
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
// 对每一个EventExecutor进行实例化
// newChild()方法由其子类实现
children[i] = newChild(executor, args);
success = true;
} catch (Exception e) {
// TODO: Think about if this is a good exception type
throw new IllegalStateException("failed to create a child event loop", e);
} finally { // 为发生异常时进行关闭操作,关闭的是整个线程池
if (!success) {
for (int j = 0; j < i; j ++) {
children[j].shutdownGracefully();
}
for (int j = 0; j < i; j ++) {
EventExecutor e = children[j];
try {
while (!e.isTerminated()) {
e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
}
} catch (InterruptedException interrupted) {
// Let the caller handle the interruption.
Thread.currentThread().interrupt();
break;
}
}
}
}
}
// 设置选择器,此选择器包含一定的选择策略。
chooser = chooserFactory.newChooser(children);
// 设置监听器
final FutureListener<Object> terminationListener = new FutureListener<Object>() {
@Override
public void operationComplete(Future<Object> future) throws Exception {
if (terminatedChildren.incrementAndGet() == children.length) {
terminationFuture.setSuccess(null);
}
}
};
// 为每一个EventExecutor都设置监听器
for (EventExecutor e: children) {
e.terminationFuture().addListener(terminationListener);
}
// 以EventExecutor数组为基础设置一个EventExecutor集合
Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
Collections.addAll(childrenSet, children);
readonlyChildren = Collections.unmodifiableSet(childrenSet);
}
/**
* Create a new EventExecutor which will later then accessible via the {@link #next()} method. This method will be
* called for each thread that will serve this {@link MultithreadEventExecutorGroup}.
*
*/
protected abstract EventExecutor newChild(Executor executor, Object... args) throws Exception;
// 还有一系列关闭线程池的操作,以及判断是否终端的操作,在此略去不表。
}
MultithreadEventLoopGroup
MultithreadEventLoopGroup并没有实现newChild(),此方法有其子类实现,比如NioEventLoopGroup或EpollEventLoopGroup。那这个类干了啥呢?重写了默认线程工程实现;剩下的都是调用父类(MultithreadEventExecutorGroup)的方法了。
NioEventLoopGroup
NioEventLoopGroup的构造方法通过调用父类的构造器实现,这点向上推就行。然后呢,它,实现了newChild()方法,还添加了设置IO频率的方法和重新构建Selector的能力。
public class NioEventLoopGroup extends MultithreadEventLoopGroup {
public NioEventLoopGroup(...) {
super(...);
}
/**
* Sets the percentage of the desired amount of time spent for I/O in the child event loops. The default value is
* {@code 50}, which means the event loop will try to spend the same amount of time for I/O as for non-I/O tasks.
*/
public void setIoRatio(int ioRatio) {
for (EventExecutor e: this) {
((NioEventLoop) e).setIoRatio(ioRatio);
}
}
/**
* Replaces the current {@link Selector}s of the child event loops with newly created {@link Selector}s to work
* around the infamous epoll 100% CPU bug.
*/
public void rebuildSelectors() {
for (EventExecutor e: this) {
((NioEventLoop) e).rebuildSelector();
}
}
@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
EventLoopTaskQueueFactory queueFactory = args.length == 4 ? (EventLoopTaskQueueFactory) args[3] : null;
return new NioEventLoop(this, executor, (SelectorProvider) args[0],
((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2], queueFactory);
}
}
至此,EventLoopGroup暂且搞清楚了,我们来看看如何创建一个新的EventLoop吧!
NioEventLoop

AbstractExecutorService
AbstractExecutorService属于java.util.concurrent包,提供Java的线程池服务。
AbstractEventExecutor
AbstractEventExecutor,虽说不是很有用。主要目的是,扩展了AbstractExecutorService,属于为Netty封装了自己的Abstract线程类。
AbstractScheduledEventExecutor
AbstractScheduledEventExecutor基于AbstractEventExecutor提供了定时任务处理机制。
SingleThreadEventExecutor
SingleThreadEventExecutor以单线程形式,执行OrderedEventExecutor的全部已提交的任务,里面维护了一个任务队列,会把所有的任务使用单个线程进行执行。
SingleThreadEventLoop
SingleThreadEventLoop重写了注册方法,可以把Channel注册到当前执行器,并调用其父类(SingleThreadEventExecutor)的方法进行处理IO事件。
看到这儿,这么设计的目的也就很明显了,由线程接口依次向下到具体的可用的线程池;到带有定时功能的线程池;再到单线程组成的可执行线程;最后到注册Channel。所以,我们可以猜测,NioEventLoop提供轮询机制和具体的IO事件处理,事实确实如此。
NioEventLoop
public final class NioEventLoop extends SingleThreadEventLoop {
// 这两个都是普通的选择器(轮询器)
private Selector selector;
private Selector unwrappedSelector;
// 一个集合,Netty自己封装的,包含了已被选择的键
private SelectedSelectionKeySet selectedKeys;
// 提供基于系统的轮询器
private final SelectorProvider provider;
// 提供Netty自己的轮询策略,比如当某个选择操作卡住时,可以直接跳过此事件去立刻处理其他可用的事件
private final SelectStrategy selectStrategy;
private static Queue<Runnable> newTaskQueue(
EventLoopTaskQueueFactory queueFactory) {
// EventLoopTaskQueueFactory是一个工厂方法,用于创建存放EventLoop任务的队列
if (queueFactory == null) {
return newTaskQueue0(DEFAULT_MAX_PENDING_TASKS);
}
return queueFactory.newTaskQueue(DEFAULT_MAX_PENDING_TASKS);
}
@Override
protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {
return newTaskQueue0(maxPendingTasks);
}
private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) {
// This event loop never calls takeTask()
// PlatformDependent.<Runnable>newMpscQueue()会创建一个线程安全的队列,适用于多生产者和单消费者场景
return maxPendingTasks == Integer.MAX_VALUE ? PlatformDependent.<Runnable>newMpscQueue()
: PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
}
// 轮询器元组,仅用来构建那两个轮询器参数
private static final class SelectorTuple {
final Selector unwrappedSelector;
final Selector selector;
SelectorTuple(Selector unwrappedSelector) {
this.unwrappedSelector = unwrappedSelector;
this.selector = unwrappedSelector;
}
SelectorTuple(Selector unwrappedSelector, Selector selector) {
this.unwrappedSelector = unwrappedSelector;
this.selector = selector;
}
}
private SelectorTuple openSelector() {
// 进行构建SelectorTuple,原方法有三种返回情况:
// 两种仅含unwrappedSelector和一种根据unwrappedSelector创建的selector
}
/**
* 进行注册,前提interestOps不为0,task为当SelectableChannel就绪时,一个任意的可以被NioEventLoop执行的任务
*/
public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task) {
// some check work done here...
if (inEventLoop()) {
register0(ch, interestOps, task);
} else {
try {
// 介于注册是一个比较耗时的工作,所以开辟线程来执行
submit(new Runnable() {
@Override
public void run() {
register0(ch, interestOps, task);
}
}).sync();
} catch (InterruptedException ignore) {
// Even if interrupted we did schedule it so just mark the Thread as interrupted.
Thread.currentThread().interrupt();
}
}
}
private void register0(SelectableChannel ch, int interestOps, NioTask<?> task) {
try {
ch.register(unwrappedSelector, interestOps, task);
} catch (Exception e) {
throw new EventLoopException("failed to register a channel", e);
}
}
/**
* Replaces the current {@link Selector} of this event loop with newly created {@link Selector}s to work
* around the infamous epoll 100% CPU bug.
*/
public void rebuildSelector() {
if (!inEventLoop()) {
execute(new Runnable() {
@Override
public void run() {
rebuildSelector0();
}
});
return;
}
rebuildSelector0();
}
private void rebuildSelector0() {
final Selector oldSelector = selector;
final SelectorTuple newSelectorTuple;
if (oldSelector == null) {
return;
}
try {
newSelectorTuple = openSelector();
} catch (Exception e) {
logger.warn("Failed to create a new Selector.", e);
return;
}
// 把所有的管道注册到新的selector上面
int nChannels = 0;
for (SelectionKey key: oldSelector.keys()) { // 获取所有的选择键
Object a = key.attachment();
try {
if (!key.isValid() || key.channel().keyFor(newSelectorTuple.unwrappedSelector) != null) {
continue;
}
int interestOps = key.interestOps();
key.cancel();
SelectionKey newKey = key.channel().register(newSelectorTuple.unwrappedSelector, interestOps, a);
if (a instanceof AbstractNioChannel) {
// Update SelectionKey
((AbstractNioChannel) a).selectionKey = newKey;
}
nChannels ++;
} catch (Exception e) {
logger.warn("Failed to re-register a Channel to the new Selector.", e);
if (a instanceof AbstractNioChannel) {
AbstractNioChannel ch = (AbstractNioChannel) a;
ch.unsafe().close(ch.unsafe().voidPromise());
} else {
@SuppressWarnings("unchecked")
NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
invokeChannelUnregistered(task, key, e);
}
}
}
// 进行转移
selector = newSelectorTuple.selector;
unwrappedSelector = newSelectorTuple.unwrappedSelector;
try {
// time to close the old selector as everything else is registered to the new one
oldSelector.close();
} catch (Throwable t) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to close the old Selector.", t);
}
}
if (logger.isInfoEnabled()) {
logger.info("Migrated " + nChannels + " channel(s) to the new Selector.");
}
}
@Override
protected void run() {
for (;;) {
// 某个计算策略函数,值有这些:SelectStrategy.CONTINUE;SelectStrategy.BUSY_WAIT;SelectStrategy.SELECT
processSelectedKeys(); // 包含了本次轮询的全部情况
// 或,当设置为不再轮询时
runAllTasks();
}
// 一些关闭线程的操作
}
// 处理轮询结果
private void processSelectedKeys() {
if (selectedKeys != null) {
processSelectedKeysOptimized();
} else {
processSelectedKeysPlain(selector.selectedKeys());
}
}
// 已选择键集合不为空时
private void processSelectedKeysOptimized() {
for (;;) { // 遍历整个selectedKeys
final Object a = k.attachment();
if (a instanceof AbstractNioChannel) { // 已就绪,可以直接处理
processSelectedKey(k, (AbstractNioChannel) a);
} else {
@SuppressWarnings("unchecked")
NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
// 处理未就绪的管道
processSelectedKey(k, task);
}
}
}
// 使管道流绑定,就绪
private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
// 使管道就绪,若失败就抛异常
task.channelReady(k.channel(), k);
}
// 处理已选择集合里面的连接
private void processSelectedKeysPlain(Set<SelectionKey> selectedKeys) {
Iterator<SelectionKey> i = selectedKeys.iterator();
for (;;) { // 遍历整个集合,处理和前面那个一样的,看管道是否就绪
if (a instanceof AbstractNioChannel) { // 已就绪,直接处理
processSelectedKey(k, (AbstractNioChannel) a);
} else {
// 若未就绪,使其就绪
NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
processSelectedKey(k, task);
}
if (needsToSelectAgain) {
// 若之前被取消了的线程数量到了某个值,可能需要再次轮询
}
}
}
// 处理就绪的连接
private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
int readyOps = k.readyOps();
// 处理连接操作
if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
int ops = k.interestOps();
ops &= ~SelectionKey.OP_CONNECT;
k.interestOps(ops);
// 连接完成后,设置"连接已完成",不然会报错
unsafe.finishConnect();
}
// 执行"写"操作,把缓冲区写出去以此来释放内存
if ((readyOps & SelectionKey.OP_WRITE) != 0) {
// forceFlush()会在没有什么可写时进行对于OP_WRITE的清理操作
ch.unsafe().forceFlush();
}
// 除了进行读取,也会处理readOps为0时的空轮询bug,在这里可以看到,除了显式地read会触发"读"操作外
// accept也会隐式地触发"读操作",其实很好理解,服务器接受了客户端的连接后,当然要准备读取来自客户端的数据咯!
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
unsafe.read();
}
}
}
至此,对于NioEventLoop的简短分析可以告一段落了,但是刚刚看到,实际的处理是借助于AbstractNioChannel来实现的,所以,我们还要看看这个类系列:
AbstractNioChannel

public abstract class AbstractNioChannel extends AbstractChannel {
}
AbstractChannel
Each channel has its own pipeline and it is created automatically when a new channel is created.
public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {
private final Channel parent;
private final ChannelId id;
private final Unsafe unsafe;
private final DefaultChannelPipeline pipeline;
private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
private final CloseFuture closeFuture = new CloseFuture(this);
private volatile SocketAddress localAddress;
private volatile SocketAddress remoteAddress;
private volatile EventLoop eventLoop;
private volatile boolean registered;
private boolean closeInitiated;
private Throwable initialCloseCause;
/** Cache for the string representation of this channel */
private boolean strValActive;
private String strVal;
protected AbstractChannel(Channel parent) {
this.parent = parent;
id = newId();
unsafe = newUnsafe();
pipeline = newChannelPipeline();
}
protected ChannelId newId() {
return DefaultChannelId.newInstance();
}
protected DefaultChannelPipeline newChannelPipeline() {
return new DefaultChannelPipeline(this);
}
@Override
public boolean isWritable() {
ChannelOutboundBuffer buf = unsafe.outboundBuffer();
return buf != null && buf.isWritable();
}
@Override
public ChannelFuture writeAndFlush(Object msg) {
return pipeline.writeAndFlush(msg);
}
@Override
public Channel read() {
pipeline.read();
return this;
}
// 那些read(), wirte(), register(), flush(), connect(), bind()...等
// 都是调用channelPipline的同名方法实现的,故略不表
// 创建一个AbstractUnsafe实例用于处理整个Channel生命周期,留给其子类实现
protected abstract AbstractUnsafe newUnsafe();
protected abstract class AbstractUnsafe implements Unsafe {
private volatile ChannelOutboundBuffer outboundBuffer = new ChannelOutboundBuffer(AbstractChannel.this);
private RecvByteBufAllocator.Handle recvHandle;
private boolean inFlush0;
/** true if the channel has never been registered, false otherwise */
private boolean neverRegistered = true;
@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
if (eventLoop.inEventLoop()) { // 如果在当前线程,直接注册
register0(promise);
} else { // 如果不在当前线程,介于注册比较耗时,故显式地注册
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
}
}
private void register0(ChannelPromise promise) {
doRegister(); // 子类会实现这个方法
pipeline.invokeHandlerAddedIfNeeded(); // 确保在通知promise之前调用handlerAdded(...)
pipeline.fireChannelRegistered();
if (isActive()) { // 确保仅在第一次注册时调用fireChannelActive()
if (firstRegistration) {
pipeline.fireChannelActive();
} else if (config().isAutoRead()) { // 此时注册完成,自动读取设置完成,就可以开始读入站数据了
beginRead();
}
}
}
@Override
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
doBind(localAddress); // 子类实现
}
@Override
public final void disconnect(final ChannelPromise promise) {
doDisconnect(); // 子类实现
}
@Override
public final void beginRead() {
doBeginRead(); // 子类实现
}
@Override
public final void write(Object msg, ChannelPromise promise) {
int size;
msg = filterOutboundMessage(msg); // 子类实现
size = pipeline.estimatorHandle().size(msg);
if (size < 0) {
size = 0;
}
outboundBuffer.addMessage(msg, size, promise);
}
@Override
public final void flush() {
outboundBuffer.addFlush();
flush0();
}
protected void flush0() {
doWrite(outboundBuffer); // 子类实现
}
}
}
DefaultAbstractMap
它是AbstractMap的默认实现类,AbstractMap没啥好说的,就保存了一些属性,作为工具类来使用,重点说说Channel
Channel
public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {
ChannelId id();
// 返回当前Channel被注册到的EventLoop
EventLoop eventLoop();
// 返回父类
Channel parent();
//
ChannelConfig config();
//
boolean isOpen();
//
boolean isRegistered();
//
boolean isActive();
//
ChannelMetadata metadata();
//
SocketAddress localAddress();
//
SocketAddress remoteAddress();
//
ChannelFuture closeFuture();
// 只有当当下(这个方法被调用的那一刻),Channel可以处理"写"操作时,才会返回true
// 否则,任何当它返回false时的"写"操作请求都会放到一个队列里面去
// 直到当前线程可以处理写操作时,才会处理队列里面的"写"请求
boolean isWritable();
// 返回当可以"写"时,可以写出的byte数量
long bytesBeforeUnwritable();
// 返回底层缓冲区必须排出的byte数量,这个是在不可写时用的,上面那个是在可写时用的
long bytesBeforeWritable();
// 返回一个仅在内部使用的unsafe对象
Unsafe unsafe();
//
ChannelPipeline pipeline();
// 返回被指定用于分配内存的那个ByteBufAllocator
ByteBufAllocator alloc();
@Override
Channel read();
@Override
Channel flush();
// 一个仅用于内部的接口,它的方法用于实际的传输处理
interface Unsafe {
// 返回它的用于给数据分配内存的内存分配器
RecvByteBufAllocator.Handle recvBufAllocHandle();
//
SocketAddress localAddress();
//
SocketAddress remoteAddress();
//
void register(EventLoop eventLoop, ChannelPromise promise);
//
void bind(SocketAddress localAddress, ChannelPromise promise);
//
void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
//
void disconnect(ChannelPromise promise);
//
void close(ChannelPromise promise);
//
void closeForcibly();
//
void deregister(ChannelPromise promise);
//
void beginRead();
//
void write(Object msg, ChannelPromise promise);
//
void flush();
//
ChannelPromise voidPromise();
// 返回存储待定写请求的ChannelOutboundBuffer
ChannelOutboundBuffer outboundBuffer();
}
}
ChannelOutboundInvoker
public interface ChannelOutboundInvoker {
//
ChannelFuture bind(SocketAddress localAddress);
//
ChannelFuture connect(SocketAddress remoteAddress);
//
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
//
ChannelFuture disconnect();
//
ChannelFuture close();
//
ChannelFuture deregister();
//
ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
//
ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
//
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
//
ChannelFuture disconnect(ChannelPromise promise);
//
ChannelFuture close(ChannelPromise promise);
//
ChannelFuture deregister(ChannelPromise promise);
//
ChannelOutboundInvoker read();
// 通过当前的ChannelHandlerContext把消息刷写并通过ChannelPipline以完成写出
ChannelFuture write(Object msg);
//
ChannelFuture write(Object msg, ChannelPromise promise);
//
ChannelOutboundInvoker flush();
// 相当于同时调用wirte()和flush()
ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
//
ChannelFuture writeAndFlush(Object msg);
//
ChannelPromise newPromise();
//
ChannelProgressivePromise newProgressivePromise();
//
ChannelFuture newSucceededFuture();
//
ChannelFuture newFailedFuture(Throwable cause);
//
ChannelPromise voidPromise();
}
通过源码,可以猜测,这个类作为出站最后一个类,供内部调用。