归档
处理器链
- 每个信道都有一个流水线
ChannelPipeline
- 默认实现类为
DefaultChannelPipeline
- 默认实现类为
- 默认流水线内部封装上下文
ChannelHandlerContext
- 上下文默认实现类为
DefaultChannelHandlerContext
- 相当于是双向链表(节点数据为处理器
ChannelHandler
)
- 上下文默认实现类为
DefaultChannelPipeline
io.netty.channel.DefaultChannelPipeline
- 添加节点
/*** 默认信道流水线 */
public class DefaultChannelPipeline implements ChannelPipeline {
final HeadContext head; // 头节点
final TailContext tail; // 尾节点
private final Channel channel; // 信道
// 构造器(在创建信道时调用)
protected DefaultChannelPipeline(Channel channel) {
this.channel = ObjectUtil.checkNotNull(channel, "channel");
...
tail = new TailContext(this);
head = new HeadContext(this);
head.next = tail;
tail.prev = head;
}
// sign_demo_010 添加到尾部
@Override
public final ChannelPipeline addLast(String name, ChannelHandler handler) {
return addLast(null, name, handler); // sign_m_001 添加到尾部并设置线程
}
/**
* sign_m_001 添加到尾部并设置线程
*
* group 为空则不设置线程,不为空则提取一个线程设置给节点
*/
@Override
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized (this) {
/**
* 校验 handler 是否重复添加。
* 如果 handler 需要被重复添加到流水线,则需要加 @Sharable 注解
*/
checkMultiplicity(handler);
newCtx = newContext(group, filterName(name, handler), handler); // sign_m_002 创建上下文节点
addLast0(newCtx); // sign_m_003 添加到尾部
... // 未注册挂起与异步调用钩子函数处理
}
callHandlerAdded0(newCtx); // sign_m_004 回调 handler 钩子函数 handlerAdded(ctx)
return this;
}
// sign_m_002 创建上下文节点
private AbstractChannelHandlerContext newContext(EventExecutorGroup group, String name, ChannelHandler handler) {
return new DefaultChannelHandlerContext(this, childExecutor(group), name, handler); // sign_m_010 将 handler 封装到节点里
}
// sign_m_003 添加到尾部(但在尾节点之前)
private void addLast0(AbstractChannelHandlerContext newCtx) {
/**
* 相当于链结构由:
* ... <-> prev <-> tail
* 变成:
* ... <-> prev <-> newCtx <-> tail
*/
AbstractChannelHandlerContext prev = tail.prev;
newCtx.prev = prev;
newCtx.next = tail;
prev.next = newCtx;
tail.prev = newCtx;
}
// sign_m_004 回调 handler 钩子函数 handlerAdded(ctx)
private void callHandlerAdded0(final AbstractChannelHandlerContext ctx) {
try {
ctx.callHandlerAdded();
} ... // catch
}
}
DefaultChannelHandlerContext
io.netty.channel.DefaultChannelHandlerContext
/*** 默认处理器上下文(相当于双链表节点) */
final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext {
private final ChannelHandler handler; // 封装的处理器
// sign_m_010 将 handler 封装到节点里
DefaultChannelHandlerContext(
DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler
) {
// executor 相当于线程
super(pipeline, executor, name, handler.getClass()); // sign_m_020
this.handler = handler;
}
@Override
public ChannelHandler handler() {
return handler;
}
}
io.netty.channel.AbstractChannelHandlerContext
// 上下文节点父类
abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {
volatile AbstractChannelHandlerContext next; // 下一个节点
volatile AbstractChannelHandlerContext prev; // 上一个节点
private final DefaultChannelPipeline pipeline; // 用于反查流水线
private final String name; // 如果未指定,则默认用处理器类简名 + "#0" 进行赋值
final EventExecutor executor;
// sign_m_020
AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor,
String name, Class<? extends ChannelHandler> handlerClass
) {
this.name = ObjectUtil.checkNotNull(name, "name");
this.pipeline = pipeline;
this.executor = executor;
... // 其他设置
}
/**
* sign_f_001 执行线程
*
* 用于执行当前处理器的相关方法,
* 如果为空(未指定),则用信道的线程执行。
*/
@Override
public EventExecutor executor() {
if (executor == null) {
return channel().eventLoop();
} else {
return executor;
}
}
}
读流程
io.netty.channel.DefaultChannelPipeline
- 调用点-参考:读写原理-读原理 sign_o_010
/*** 默认信道流水线 */
public class DefaultChannelPipeline implements ChannelPipeline {
// sign_o_010 发送读取的字节
@Override
public final ChannelPipeline fireChannelRead(Object msg) {
AbstractChannelHandlerContext.invokeChannelRead(head, msg); // sign_m_101 使用头节点读
return this;
}
// sign_o_020 发送读取完成事件
@Override
public final ChannelPipeline fireChannelReadComplete() {
AbstractChannelHandlerContext.invokeChannelReadComplete(head); // sign_m_110 从头节点开始
return this;
}
/*** 头节点 */
final class HeadContext extends AbstractChannelHandlerContext
implements ChannelOutboundHandler, ChannelInboundHandler
{
// sign_m_130 读
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ctx.fireChannelRead(msg); // sign_m_131 上下文读
}
}
}
io.netty.channel.AbstractChannelHandlerContext
abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {
// sign_m_101 开启读调用
static void invokeChannelRead(final AbstractChannelHandlerContext next, Object msg) {
final Object m = next.pipeline.touch(ObjectUtil.checkNotNull(msg, "msg"), next);
EventExecutor executor = next.executor(); // sign_f_001
if (executor.inEventLoop()) {
next.invokeChannelRead(m); // sign_i_102 使用(当前类的)实例方法进行读
} else {
... // 用给定的线程执行 invokeChannelRead(m) 方法
}
}
// sign_i_102 读处理
private void invokeChannelRead(Object msg) {
if (invokeHandler()) {
try {
// see https://bugs.openjdk.org/browse/JDK-8180450
final ChannelHandler handler = handler();
final DefaultChannelPipeline.HeadContext headContext = pipeline.head;
if (handler == headContext) {
headContext.channelRead(this, msg); // sign_m_130 头节点处理读
} else if (handler instanceof ChannelDuplexHandler) {
((ChannelDuplexHandler) handler).channelRead(this, msg);
} else {
/**
* 调用对应的入站处理器进行读取
* handler 实现的方法一般会调用 ctx.fireChannelRead(msg) - sign_m_131 进入链式传递
*/
((ChannelInboundHandler) handler).channelRead(this, msg);
}
} ... // catch
} ... // else
}
// sign_m_110 开启调用
static void invokeChannelReadComplete(final AbstractChannelHandlerContext next) {
EventExecutor executor = next.executor(); // sign_f_001
if (executor.inEventLoop()) {
next.invokeChannelReadComplete(); // 当前类的实例方法。具体实现略...
} else {
... // 相当于用给定的线程执行 invokeChannelReadComplete() 方法
}
}
// sign_m_131 读处理(链式调用处理)
@Override
public ChannelHandlerContext fireChannelRead(final Object msg) {
/**
* sign_m_132 findContextInbound 查找下一个节点
* sign_m_101 invokeChannelRead 开启读调用
*/
invokeChannelRead(findContextInbound(MASK_CHANNEL_READ), msg);
return this;
}
// sign_m_132 查找链表上的入站处理器节点
private AbstractChannelHandlerContext findContextInbound(int mask) {
AbstractChannelHandlerContext ctx = this;
EventExecutor currentExecutor = executor();
do {
ctx = ctx.next;
} while (skipContext(ctx, currentExecutor, mask, MASK_ONLY_INBOUND)); // sign_m_301 判断是否跳过此 ctx
return ctx;
}
}
写流程
-
调用参考:简单示例-客户端 sign_u_001
- 调用点:
channel.write(msg); // sign_u_001 写入消息
- 调用点:
-
写底层参考:读写原理-写入
-
io.netty.channel.AbstractChannel
// sign_u_001 信道写入消息
@Override
public ChannelFuture write(Object msg) {
return pipeline.write(msg); // sign_m_201 流水线写入消息
}
io.netty.channel.DefaultChannelPipeline
/*** 默认信道流水线 */
public class DefaultChannelPipeline implements ChannelPipeline {
// sign_m_201 写入消息
@Override
public final ChannelFuture write(Object msg) {
return tail.write(msg); // sign_m_210 从尾节点开始写入
}
}
io.netty.channel.AbstractChannelHandlerContext
abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {
// sign_m_210 写入消息
@Override
public ChannelFuture write(Object msg) {
return write(msg, newPromise()); // sign_m_211 写入消息
}
// sign_m_211 写入消息
@Override
public ChannelFuture write(final Object msg, final ChannelPromise promise) {
write(msg, false, promise); // sign_m_212 写入消息
return promise;
}
// sign_m_212 写入消息
private void write(Object msg, boolean flush, ChannelPromise promise) {
... // 省略校验处理
final AbstractChannelHandlerContext next = findContextOutbound( // 查找下一个出站处理器
flush ? (MASK_WRITE | MASK_FLUSH) : MASK_WRITE
);
final Object m = pipeline.touch(msg, next);
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
if (flush) {
next.invokeWriteAndFlush(m, promise); // 写入并推送
} else {
next.invokeWrite(m, promise); // sign_m_213 仅写入
}
} else {
... // 异步执行
}
}
// sign_m_213 调用写入
void invokeWrite(Object msg, ChannelPromise promise) {
if (invokeHandler()) {
invokeWrite0(msg, promise); // sign_m_214 调用写入
} ... // else
}
// sign_m_214 调用写入
private void invokeWrite0(Object msg, ChannelPromise promise) {
try {
// see https://bugs.openjdk.org/browse/JDK-8180450
final ChannelHandler handler = handler();
final DefaultChannelPipeline.HeadContext headContext = pipeline.head;
if (handler == headContext) {
headContext.write(this, msg, promise); // sign_o_030 头节点写入消息
} else if (handler instanceof ChannelDuplexHandler) {
((ChannelDuplexHandler) handler).write(this, msg, promise);
} else {
/**
* 调用对应的出站处理器进行写入
* handler 实现的方法一般会调用 ctx.write(msg, promise); - sign_m_211 进入链式传递
*/
((ChannelOutboundHandler) handler).write(this, msg, promise);
}
} ... // catch
}
}
处理器回调函数逻辑
- 方法有:
ChannelHandler #handlerAdded(ctx)
ChannelInboundHandler #channelRegistered(ctx)
- 参考:简单示例-服务端(sign_demo_020、sign_demo_021)
- 调用点:
io.netty.channel.AbstractChannel.AbstractUnsafe
- 参考:ServerBootstrap-监听-注册调用点 sign_m_201
// sign_m_201
private void register0(ChannelPromise promise) {
try {
... // 略
pipeline.invokeHandlerAddedIfNeeded(); // 回调被添加到流水线的方法
safeSetSuccess(promise);
pipeline.fireChannelRegistered(); // 回调信道被添加到事件轮循的方法
... // 略
} ... // catch
}
@Skip-原理
io.netty.channel.AbstractChannelHandlerContext
abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {
private final int executionMask; // 执行的掩码
AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor,
String name, Class<? extends ChannelHandler> handlerClass
) {
this.executionMask = mask(handlerClass); // sign_m_150 根据类计算掩码
}
// sign_m_301 判断是否跳过此 ctx
private static boolean skipContext(
AbstractChannelHandlerContext ctx, EventExecutor currentExecutor, int mask, int onlyMask
) {
// 与当前上下文设置的掩码不一致,则跳过
return (ctx.executionMask & (onlyMask | mask)) == 0 ||
(ctx.executor() == currentExecutor && (ctx.executionMask & mask) == 0);
}
}
io.netty.channel.ChannelHandlerMask
// 掩码帮助类
public final class ChannelHandlerMask {
// sign_m_150 根据类计算掩码
static int mask(Class<? extends ChannelHandler> clazz) {
Map<Class<? extends ChannelHandler>, Integer> cache = MASKS.get();
Integer mask = cache.get(clazz);
if (mask == null) {
mask = mask0(clazz); // sign_i_151 计算掩码
cache.put(clazz, mask);
}
return mask;
}
// sign_i_151 计算掩码
private static int mask0(Class<? extends ChannelHandler> handlerType) {
int mask = MASK_EXCEPTION_CAUGHT;
try {
if (ChannelInboundHandler.class.isAssignableFrom(handlerType)) {
mask |= MASK_ALL_INBOUND;
/**
* sign_i_152 判断方法是否应跳过。
* 如果 isSkippable() 返回 true,则表示跳过,
* 掩码则取反 (~)
*/
if (isSkippable(handlerType, "channelRegistered", ChannelHandlerContext.class)) {
mask &= ~MASK_CHANNEL_REGISTERED;
}
... // 省略 channelUnregistered channelActive channelInactive
... // 省略 channelRead channelReadComplete channelWritabilityChanged userEventTriggered
}
if (ChannelOutboundHandler.class.isAssignableFrom(handlerType)) {
mask |= MASK_ALL_OUTBOUND;
... // 省略 bind connect disconnect close deregister
... // 省略 read write flush
}
... // 省略 exceptionCaught
} ... // catch
return mask;
}
// sign_i_152 判断方法是否应跳过
private static boolean isSkippable(
final Class<?> handlerType, final String methodName, final Class<?>... paramTypes
) throws Exception {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
@Override
public Boolean run() throws Exception {
Method m;
try {
m = handlerType.getMethod(methodName, paramTypes); // 查找要判断的方法
} catch (NoSuchMethodException e) {
... // 省略日志输出
return false; // 没有此方法,则不跳过
}
return m.isAnnotationPresent(Skip.class); // 判断此方法是否有 @Skip 注解:有的话,则跳过
}
});
}
}