类的字段
private final Channel parent; //父channel
private final ChannelId id; //唯一id
private final Unsafe unsafe; //实际处理I/O操作的类
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; //eventloop线程
private volatile boolean registered;
类的构造方法
protected AbstractChannel(Channel parent) {
this.parent = parent;
id = newId();
unsafe = newUnsafe();
pipeline = newChannelPipeline();
}
protected AbstractChannel(Channel parent, ChannelId id) {
this.parent = parent;
this.id = id;
unsafe = newUnsafe();
pipeline = newChannelPipeline();
}
其中 newUnsafe()方法是抽象方法,由子类实现
protected abstract AbstractUnsafe newUnsafe();
每一个channel内部都有一个对应的Unsafe内部类。
而
newChannelPipeline()方法在这里就实现了
protected DefaultChannelPipeline newChannelPipeline() {
return new DefaultChannelPipeline(this);
}
其中ChannelPipeline这里不做引申,用途:做为Handler的容器,为用户提供逻辑处理。AbstractChannel中对I/O事件的都由pipeline 来完成。
public ChannelFuture bind(SocketAddress localAddress) {
return pipeline.bind(localAddress);
}
public ChannelFuture connect(SocketAddress remoteAddress) {
return pipeline.connect(remoteAddress);
}
public ChannelFuture disconnect() {
return pipeline.disconnect();
}
public ChannelFuture close() {
return pipeline.close();
}
public Channel flush() {
pipeline.flush();
return this;
}
public Channel read() {
pipeline.read();
return this;
}
public ChannelFuture write(Object msg) {
return pipeline.write(msg);
}
.....
pipeline只是一个Handler的容器,也可以理解为一个Handler链,具体的逻辑由Handler处理,而每个Handler都会分配一个EventLoop,最终的请求还是要EventLoop来执行,而EventLoop中又调用Channel中的内部类Unsafe对应的方法。
新建一个channel会自动创建一个ChannelPipeline。
@Override
public ChannelFuture register(final Channel channel, final ChannelPromise promise) {
if (channel == null) {
throw new NullPointerException("channel");
}
if (promise == null) {
throw new NullPointerException("promise");
}
channel.unsafe().register(this, promise);//真正的执行者
return promise;
}
参考前面文章 "Channel简介" 中Unsafe接口的方法来看 I/O操作的具体实现。
register()方法:
将Channel中注册给EventLoop
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
if (eventLoop == null) {
throw new NullPointerException("eventLoop");
}
if (isRegistered()) {//已经注册过了,则失败
promise.setFailure(new IllegalStateException("registered to an event loop already"));
return;
}
if (!isCompatible(eventLoop)) {//不兼容当前channel,子类实现
promise.setFailure(
new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
return;
}
AbstractChannel.this.eventLoop = eventLoop;
//每个EventLoop由固定的Thread执行
//每个Cnel会分配一个EventLoop
//一个EventLoop可以分配给多个Channnel
if (eventLoop.inEventLoop()) {//见注释1
register0(promise);
} else {
try {
eventLoop.execute(new Runnable() {//放入eventloop的任务队列,这样做是为保证一个channel的所有处理都是走同一个线程
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
logger.warn(
"Force-closing a channel whose registration task was not accepted by an event loop: {}",
AbstractChannel.this, t);
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
}
注释1:
/**
* 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);
如果给的线程是EventLoop线程池的线程,那就执行 register0()
register0()方法
private void register0(ChannelPromise promise) {
try {
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
doRegister();//由子类实现,将当前Channel注册到EventLoop的多路复用器上
neverRegistered = false;//从来没有注册过
registered = true;//标记已经注册
pipeline.invokeHandlerAddedIfNeeded();//加载Handler到pipeline
safeSetSuccess(promise);//设置为成功
pipeline.fireChannelRegistered();//触发channel的“注册”事件,将ChannelHandlerContext注册到pipeline
if (isActive()) { //channel已经被激活
if (firstRegistration) {//首次激活,则触发channel的“激活”事件
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {//设置为AutoRead,则开始读取数据
beginRead();//见下文
}
}
} catch (Throwable t) {
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
beginRead()方法
public final void beginRead() {
assertEventLoop();//assert !registered || eventLoop.inEventLoop(); channel没有注册或当前线程是eventLoop
if (!isActive()) {
return;
}
try {
doBeginRead();//模板方法,子类实现
} catch (final Exception e) {
invokeLater(new Runnable() {
@Override
public void run() {
pipeline.fireExceptionCaught(e);
}
});
close(voidPromise());
}
}
deregister()方法:
解除注册
@Override
public final void deregister(final ChannelPromise promise) {
assertEventLoop();//assert !registered || eventLoop.inEventLoop();
deregister(promise, false);
}
private void deregister(final ChannelPromise promise, final boolean fireChannelInactive) {
if (!promise.setUncancellable()) {
return;
}
if (!registered) {//已经解除注册
safeSetSuccess(promise);
return;
}
invokeLater(new Runnable() {//invokeLater()方法的具体含义可见下文
@Override
public void run() {
try {
doDeregister();//模版方法,由子类实现,将Channel从EventLoop的多路复用器上删除
} catch (Throwable t) {
logger.warn("Unexpected exception occurred while deregistering a channel.", t);
} finally {
if (fireChannelInactive) {
pipeline.fireChannelInactive();//触发ChannelInavtive事件
}
if (registered) {
registered = false;
pipeline.fireChannelUnregistered();//触发ChannelUnregistered事件
}
safeSetSuccess(promise);
}
}
});
}
bind()方法:
绑定channel到本地地址,然后触发激活事件
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
assertEventLoop();
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
if (Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) &&
localAddress instanceof InetSocketAddress &&
!((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress() &&
!PlatformDependent.isWindows() && !PlatformDependent.maybeSuperUser()) {
logger.warn(.......);
}
boolean wasActive = isActive();//绑定前的激活状态
try {
doBind(localAddress);//模板方法,由子类实现
} catch (Throwable t) {
safeSetFailure(promise, t);
closeIfClosed();
return;
}
if (!wasActive && isActive()) {//没有进行激活操作
invokeLater(new Runnable() {//见下文
@Override
public void run() {
pipeline.fireChannelActive();//触发“激活”事件
}
});
}
safeSetSuccess(promise);//设置成功
}
invokeLater()
其实就是想eventLoop提交一个任务
private void invokeLater(Runnable task) {
try {
eventLoop().execute(task);
} catch (RejectedExecutionException e) {
logger.warn("Can't invoke task later as EventLoop rejected it", e);
}
}
connect()方法:
由子类 AbstractNioChannel 实现
disconnect()方法:
解除连接
public final void disconnect(final ChannelPromise promise) {
assertEventLoop();
if (!promise.setUncancellable()) {
return;
}
boolean wasActive = isActive();//解除连接前的激活状态
try {
doDisconnect();//子类实现
} catch (Throwable t) {
safeSetFailure(promise, t);
closeIfClosed();
return;
}
if (wasActive && !isActive()) {//非激活状态
invokeLater(new Runnable() {
@Override
public void run() {
pipeline.fireChannelInactive();//触发ChannelInavtive事件
}
});
}
safeSetSuccess(promise);
closeIfClosed(); // doDisconnect() 可能关闭Channel
}
write()方法:
将msg写到队列中等待flush
public final void write(Object msg, ChannelPromise promise) {
assertEventLoop();
ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (outboundBuffer == null) {//表示Channel正在关闭,禁止写数据
safeSetFailure(promise, WRITE_CLOSED_CHANNEL_EXCEPTION);
ReferenceCountUtil.release(msg);//释放msg,防止泄漏
return;
}
int size;
try {
msg = filterOutboundMessage(msg);//由子类AbstractNioByteChannel实现,过滤msg,如果不是ByteBuf或者FileRegion就抛错
size = pipeline.estimatorHandle().size(msg);//计算msg的大小
if (size < 0) {
size = 0;
}
} catch (Throwable t) {
safeSetFailure(promise, t);
ReferenceCountUtil.release(msg);
return;
}
outboundBuffer.addMessage(msg, size, promise);//添加到发送队列,等待flush
}
ChannelOutboundBuffer 的addMessage()
public void addMessage(Object msg, int size, ChannelPromise promise) {
Entry entry = Entry.newInstance(msg, size, total(msg), promise);
if (tailEntry == null) {
flushedEntry = null;
tailEntry = entry;
} else {
Entry tail = tailEntry;
tail.next = entry;
tailEntry = entry;
}
if (unflushedEntry == null) {
unflushedEntry = entry;
}
incrementPendingOutboundBytes(entry.pendingSize, false);
}
flush()方法:
将队列中的msg冲刷到channel中
public final void flush() {
assertEventLoop();
ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (outboundBuffer == null) {
return;
}
outboundBuffer.addFlush();//添加一个标记,意味着所有以前添加的消息都被标记为刷新,并且能够处理它们。
flush0();
}
flush0() 方法
protected void flush0() {
if (inFlush0) {//已经冲刷
return;
}
final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (outboundBuffer == null || outboundBuffer.isEmpty()) {// Channel已经关闭或者已没有需要写的数据
return;
}
inFlush0 = true;
// Mark all pending write requests as failure if the channel is inactive.
if (!isActive()) {//非激活
try {
if (isOpen()) {//channel还是打开的
outboundBuffer.failFlushed(FLUSH0_NOT_YET_CONNECTED_EXCEPTION, true);//failFlushed()内部将队列的中的写请求标记为失败
} else {
outboundBuffer.failFlushed(FLUSH0_CLOSED_CHANNEL_EXCEPTION, false);
}
} finally {
inFlush0 = false;
}
return;
}
try {
doWrite(outboundBuffer);//由子类实现,将所有msg写入Channel
} catch (Throwable t) {
if (t instanceof IOException && config().isAutoClose()) {
close(voidPromise(), t, FLUSH0_CLOSED_CHANNEL_EXCEPTION, false);
} else {
outboundBuffer.failFlushed(t, true);
}
} finally {
inFlush0 = false;
}
}
close()方法:
关闭Channel
public final void close(final ChannelPromise promise) {
assertEventLoop();
close(promise, CLOSE_CLOSED_CHANNEL_EXCEPTION, CLOSE_CLOSED_CHANNEL_EXCEPTION, false);
}
private void close(final ChannelPromise promise, final Throwable cause,
final ClosedChannelException closeCause, final boolean notify) {
if (!promise.setUncancellable()) {
return;
}
final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (outboundBuffer == null) {//Channel已经关闭
if (!(promise instanceof VoidChannelPromise)) {
closeFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
promise.setSuccess();// 当Channel关闭时,将此次close异步请求结果也设置为成功
}
});
}
return;
}
if (closeFuture.isDone()) {//已经成功关闭,保证底层close只执行一次
safeSetSuccess(promise);
return;
}
final boolean wasActive = isActive();
this.outboundBuffer = null; // 这里可以做一个标识,前面关于 == null的判读的基础就是这里。
//准备去关闭Channel。
//如果返回一个Executor,调用者必须 将doClose0()包装成一个任务加入Executor。
//如果返回null,必须执行 doClose0()
Executor closeExecutor = prepareToClose();
if (closeExecutor != null) {
closeExecutor.execute(new Runnable() {
@Override
public void run() {
try {
doClose0(promise);
} finally {
invokeLater(new Runnable() {//invokeLater见上文
@Override
public void run() {
outboundBuffer.failFlushed(cause, notify);
outboundBuffer.close(closeCause);
fireChannelInactiveAndDeregister(wasActive);
}
});
}
}
});
} else {
try {
doClose0(promise);
} finally {
outboundBuffer.failFlushed(cause, notify);
outboundBuffer.close(closeCause);
}
if (inFlush0) {
invokeLater(new Runnable() {
@Override
public void run() {
fireChannelInactiveAndDeregister(wasActive);//触发ChannelInavtive事件 和 触发ChannelUnregistered事件
}
});
} else {
fireChannelInactiveAndDeregister(wasActive);
}
}
}
doClose0() 方法
private void doClose0(ChannelPromise promise) {
try {
doClose();
closeFuture.setClosed();
safeSetSuccess(promise);
} catch (Throwable t) {
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
doClose() 方法
由子类 AbstractNioChannel 实现
回顾上文:
回顾上文:
- 每个Channel都有个一个Unsafe内部类,具体的逻辑都是Unsafe类实现
- 每个Channel都有一个EventLoop,EventLoop的Thread是固定的,所有的事件都是由同一条Thread执行,避免并发。
- 消息不是直接写到Channel中,而是先写入队列,然后在flush时一次写入Channel
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">