服务端Selector监听到NioSochetChannel的连接事件后,需要通过boss线程启动一个worker线程驱动的事件循环组,并且将当前NioSochetChannel注册至worker线程的Selector上并且监听相关NioSochetChannel存在的IO事件。
在服务端NioSochetChannel在worker线程的Selector上注册register0
过程中,会为当前的NioSochetChannel填充自定义的ChannelHandler时涉及相关心跳的ChannelHandler之IdleStateHandler
。
IdleStateHandler提供了三种类型的IdleStateEvent
:read, write, or both operation for a while。每种类型的定时事件都对应一个AbstractIdleTask
类型的定时任务ReaderIdleTimeoutTask
、WriterIdleTimeoutTask
、AllIdleTimeoutTask
。
public class IdleStateHandler extends ChannelDuplexHandler {
public IdleStateHandler(boolean observeOutput,long readerIdleTime,
long writerIdleTime, long allIdleTime,TimeUnit unit) {
readerIdleTimeNanos = Math.max(unit.toNanos(readerIdleTime), MIN_TIMEOUT_NANOS);
writerIdleTimeNanos = Math.max(unit.toNanos(writerIdleTime), MIN_TIMEOUT_NANOS);
allIdleTimeNanos = Math.max(unit.toNanos(allIdleTime), MIN_TIMEOUT_NANOS);
}
private void initialize(ChannelHandlerContext ctx) {
...
state = 1;
initOutputChanged(ctx);
lastReadTime = lastWriteTime = ticksInNanos();
if (readerIdleTimeNanos > 0) {
readerIdleTimeout = schedule(ctx, new ReaderIdleTimeoutTask(ctx),
readerIdleTimeNanos, TimeUnit.NANOSECONDS);
}
if (writerIdleTimeNanos > 0) {
writerIdleTimeout = schedule(ctx, new WriterIdleTimeoutTask(ctx),
writerIdleTimeNanos, TimeUnit.NANOSECONDS);
}
if (allIdleTimeNanos > 0) {
allIdleTimeout = schedule(ctx, new AllIdleTimeoutTask(ctx),
allIdleTimeNanos, TimeUnit.NANOSECONDS);
}
}
}
public abstract class AbstractScheduledEventExecutor{
PriorityQueue<ScheduledFutureTask<?>> scheduledTaskQueue;
@Override
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
...
return schedule(new ScheduledFutureTask<Void>(this,command,
deadlineNanos(getCurrentTimeNanos(), unit.toNanos(delay))));
}
public static long deadlineNanos(long nanoTime, long delay) {
//当前时间 + 延迟纳秒数
long deadlineNanos = nanoTime + delay;
return deadlineNanos < 0 ? Long.MAX_VALUE : deadlineNanos;
}
private <V> ScheduledFuture<V> schedule(final ScheduledFutureTask<V> task) {
if (inEventLoop()) {
scheduledTaskQueue.add(task.setId(++nextTaskId));
} else {
...
}
return task;
}
}
最后将三种类型的任务task均抽象为ScheduledFutureTask
类型的任务,并添加至优先队列scheduledTaskQueue中。
1.AbstractIdleTask任务初始化时机
IdleStateHandler 被添加至 NioSochetChannel对应的pipeline过程中。意味着服务端监听到每个客户端NioSochetChannel连接事件后,会为每个NioSochetChannel的pipeline中添加一个IdleStateHandler类型的channelHandler。
public class DefaultChannelPipeline implements ChannelPipeline {
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
AbstractChannelHandlerContext newCtx;
synchronized (this) {
newCtx = newContext(group, filterName(name, handler), handler);
addLast0(newCtx);
...
}
callHandlerAdded0(newCtx);//真正调用IdleStateHandler的initialize方法
return this;
}
}
2.优先队列PriorityQueue添加至普通队列
优先队列PriorityQueue中元素类型为ScheduledFutureTask:
- 将 PriorityQueue中元素ScheduledFutureTask 添加至循环事件组监听的普通队列中。
- 由 worker线程负责触发 ScheduledFutureTask类型的任务。
public abstract class SingleThreadEventExecutor extends AbstractScheduledEventExecutor{
private final Queue<Runnable> taskQueue;
protected boolean runAllTasks(long timeoutNanos) {
fetchFromScheduledTaskQueue();
Runnable task = pollTask();
...
final long deadline = timeoutNanos > 0 ? getCurrentTimeNanos() + timeoutNanos : 0;
long runTasks = 0;
long lastExecutionTime;
for (;;) {//worker线程循环处理taskQueue中全部任务
safeExecute(task);
runTasks ++;
...
}
return true;
}
private boolean fetchFromScheduledTaskQueue() {
if (scheduledTaskQueue == null || scheduledTaskQueue.isEmpty()) {
return true;
}
long nanoTime = getCurrentTimeNanos();
for (;;) {//循环将PriorityQueue队列中ScheduledFutureTask类型任务添加至taskQueue终
Runnable scheduledTask = pollScheduledTask(nanoTime);
if (scheduledTask == null) {
return true;
}
if (!taskQueue.offer(scheduledTask)) {
scheduledTaskQueue.add((ScheduledFutureTask<?>) scheduledTask);
return false;
}
}
}
}
3.ScheduledFutureTask
ScheduledFutureTask任务是被当做普通队列中任务后被worker线程触发执行。
final class ScheduledFutureTask<V> extends PromiseTask<V> implements ScheduledFuture<V>, PriorityQueueNode {
// AbstractIdleTask类型的任务触发的截止时间
private long deadlineNanos;
/* 0 - no repeat, >0 - repeat at fixed rate, <0 - repeat with fixed delay */
private final long periodNanos;//默认值0
@Override
public void run() {
//当前时间与AbstractIdleTask截止时间比较,是否过期
if (delayNanos() > 0L) {// 条件成立,意味着 AbstractIdleTask 任务执行时已经超过截止时间了
if (isCancelled()) {
scheduledExecutor().scheduledTaskQueue().removeTyped(this);
} else {
scheduledExecutor().scheduleFromEventLoop(this);
}
return;
}
if (periodNanos == 0) {
if (setUncancellableInternal()) {
V result = runTask();// 直接触发AbstractIdleTask任务的执行
setSuccessInternal(result);
}
} else {
// check if is done as it may was cancelled
if (!isCancelled()) {
runTask();
...
}
}
}
}
4.AbstractIdleTask
以 AllIdleTimeoutTask 类型为例。
public class IdleStateHandler extends ChannelDuplexHandler {
// channelRead设置为true,channelReadComplete设置为false
private boolean reading;// 默认值为false
private long lastReadTime;
private long lastWriteTime;
private final class AllIdleTimeoutTask extends AbstractIdleTask {
@Override
protected void run(ChannelHandlerContext ctx) {
long nextDelay = allIdleTimeNanos;
if (!reading) {
// channelReadComplete 设置 lastReadTime 为当前时间
nextDelay -= ticksInNanos() - Math.max(lastReadTime, lastWriteTime);
}
if (nextDelay <= 0) {// 说明已经达到定时任务触发时间
allIdleTimeout = schedule(ctx, this, allIdleTimeNanos, TimeUnit.NANOSECONDS);
boolean first = firstAllIdleEvent;
firstAllIdleEvent = false;
if (hasOutputChanged(ctx, first)) {
return;
}
IdleStateEvent event = newIdleStateEvent(IdleState.ALL_IDLE, first);
channelIdle(ctx, event);//触发入栈ChannelHandler#fireUserEventTriggered
} else {
allIdleTimeout = schedule(ctx, this, nextDelay, TimeUnit.NANOSECONDS);
}
}
}
}