1 类继承关系
2 代码详情
AbstractChannel
字段
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;
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 abstract AbstractUnsafe newUnsafe();
- 是一个抽象方法,但是限定了返回值一定要是AbstractUnsafe
protected DefaultChannelPipeline newChannelPipeline()
- return new DefaultChannelPipeline(this);
@Override
public boolean isWritable()
- //通道是否可写,实现了父类Channel的方法,是否判断的是unsafe //的输出buffer是否可写 ChannelOutboundBuffer buf = unsafe.outboundBuffer(); return buf != null && buf.isWritable();
@Override
public long bytesBeforeUnwritable()
- //实现的父类Channel中的方法 //可以写入多少字节,也是拿的unsafe的输出buffer的做的判断 ChannelOutboundBuffer buf = unsafe.outboundBuffer(); return buf != null ? buf.bytesBeforeUnwritable() : 0;
@Override
public long bytesBeforeWritable()
- //实现的父类Channel中的方法 //还需要发送出去多少字节的数据输出缓冲区才可以写,也是拿的unsafe的输出buffer的做的判断 ChannelOutboundBuffer buf = unsafe.outboundBuffer(); return buf != null ? buf.bytesBeforeUnwritable() : 0;
@Override
public Channel parent() {
return parent;
}
@Override
public ChannelPipeline pipeline() {
return pipeline;
}
//父类Channel中的方法,获取ByteBufAllocator
@Override public ByteBufAllocator alloc() { return config().getAllocator(); }
//父类Channel中的方法,说明一个Channel必定在一个EventLoop中
@Override public EventLoop eventLoop() { EventLoop eventLoop = this.eventLoop; if (eventLoop == null) { throw new IllegalStateException("channel not registered to an event loop"); } return eventLoop; }
@Override
public SocketAddress localAddress()
- //数据来源是Unsafe SocketAddress localAddress = this.localAddress; if (localAddress == null) { try { this.localAddress = localAddress = unsafe().localAddress(); } catch (Error e) { throw e; } catch (Throwable t) { // Sometimes fails on a closed socket in Windows. return null; } } return localAddress;
//父类Channel中的方法
@Override public SocketAddress remoteAddress()
- //数据来源是Unsafe SocketAddress remoteAddress = this.remoteAddress; if (remoteAddress == null) { try { this.remoteAddress = remoteAddress = unsafe().remoteAddress(); } catch (Error e) { throw e; } catch (Throwable t) { // Sometimes fails on a closed socket in Windows. return null; } } return remoteAddress;
//Channel中的方法,是否被注册到eventloop中
@Override public boolean isRegistered() { return registered; }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture bind(SocketAddress localAddress) { return pipeline.bind(localAddress); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture connect(SocketAddress remoteAddress) { return pipeline.connect(remoteAddress); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { return pipeline.connect(remoteAddress, localAddress); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture disconnect() { return pipeline.disconnect(); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture close() { return pipeline.close(); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture deregister() { return pipeline.deregister(); }
//实现父类Channel中的方法,调用的pipeline
@Override public Channel flush() { pipeline.flush(); return this; }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { return pipeline.bind(localAddress, promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { return pipeline.connect(remoteAddress, promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { return pipeline.connect(remoteAddress, localAddress, promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture disconnect(ChannelPromise promise) { return pipeline.disconnect(promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture close(ChannelPromise promise) { return pipeline.close(promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture deregister(ChannelPromise promise) { return pipeline.deregister(promise); }
//实现父类channel中的方法,调用的pipeline
@Override public Channel read() { pipeline.read(); return this; }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture write(Object msg) { return pipeline.write(msg); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture write(Object msg, ChannelPromise promise) { return pipeline.write(msg, promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture writeAndFlush(Object msg) { return pipeline.writeAndFlush(msg); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { return pipeline.writeAndFlush(msg, promise); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelPromise newPromise() { return pipeline.newPromise(); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelProgressivePromise newProgressivePromise() { return pipeline.newProgressivePromise(); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture newSucceededFuture() { return pipeline.newSucceededFuture(); }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public ChannelFuture newFailedFuture(Throwable cause) { return pipeline.newFailedFuture(cause); }
//实现父类Channel中的方法,调用的pipeline
@Override public ChannelFuture closeFuture() { return closeFuture; }
//实现父类Channel中的方法,调用的pipeline
@Override public Unsafe unsafe() { return unsafe; }
//实现父类ChannelOutboundInvoker中的方法,调用的pipeline
@Override public final ChannelPromise voidPromise() { return pipeline.voidPromise(); }
protected abstract SocketAddress localAddress0();
protected abstract SocketAddress remoteAddress0();
//语义:该channel和这个Eventloop是否相匹配
protected abstract boolean isCompatible(EventLoop loop);
protected abstract void doDisconnect() throws Exception;
protected abstract void doClose() throws Exception;
非static的内部类AbstractUnsafe
类签名protected abstract class AbstractUnsafe implements Unsafe,一个抽象类实现了Unsafe接口
字段
- private volatile ChannelOutboundBuffer outboundBuffer = new ChannelOutboundBuffer(AbstractChannel.this);
- private RecvByteBufAllocator.Handle recvHandle;
- private boolean inFlush0;
- private boolean neverRegistered = true;
方法
-
@Override public RecvByteBufAllocator.Handle recvBufAllocHandle() { if (recvHandle == null) { recvHandle = config().getRecvByteBufAllocator().newHandle(); } return recvHandle; }
-
@Override public final ChannelOutboundBuffer outboundBuffer() { return outboundBuffer; } -
//调用的AbstractChannel中的方法localAddress0(); @Override public final SocketAddress localAddress() { return localAddress0(); }
-
//调用的AbstractChannel中的方法remoteAddress0(); @Override public final SocketAddress remoteAddress() { return remoteAddress0(); }
-
//实现的父类Unsafe中的方法 @Override public final void register(EventLoop eventLoop, final ChannelPromise promise)
- //校验 ObjectUtil.checkNotNull(eventLoop, "eventLoop"); if (isRegistered()) { promise.setFailure(new IllegalStateException("registered to an event loop already")); return; } if (!isCompatible(eventLoop)) { promise.setFailure( new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName())); return; }
- //当前线程如果在eventloop中则直接调用register0,否则就提交一个runnable到eventloop中 if (eventLoop.inEventLoop()) { register0(promise); } else { try { eventLoop.execute(new Runnable() { @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); } }
-
private void register0(ChannelPromise promise)
-
try{}
- //ChannelPromise设置成不可取消,并且确认Channel是打开的 if (!promise.setUncancellable() || !ensureOpen(promise)) { return; }
- //doRegister();是AbstractChannel中的方法,是一个空的实现 boolean firstRegistration = neverRegistered; doRegister();
- //相关标志位置位 neverRegistered = false; registered = true;
- // Ensure we call handlerAdded(...) before we actually notify the promise. This is needed as the // user may already fire events through the pipeline in the ChannelFutureListener. pipeline.invokeHandlerAddedIfNeeded();
- //promise 设置为成功 safeSetSuccess(promise);
- //发送注册事件 pipeline.fireChannelRegistered();
- //如果通道是Active的,则如果是第一次注册,则发送ChannelActive事件 //这个是未了防止因为同一个Channel多次的注册和注销注册而发送出多个ChannelActive事件 //如果不是初次注册且配置的自动读,那么就要去读数据 if (isActive()) { if (firstRegistration) { pipeline.fireChannelActive(); } else if (config().isAutoRead()) { // This channel was registered before and autoRead() is set. This means we need to begin read // again so that we process inbound data. // // See github.com/netty/netty… beginRead(); } }
-
catch (Throwable t) { // Close the channel directly to avoid FD leak. closeForcibly(); closeFuture.setClosed(); safeSetFailure(promise, t); }
-
-
//实现父类Unsafe中的方法 @Override public final void beginRead()
- assertEventLoop();
- // doBeginRead()是AbstractChannel的一个抽象方法 try { doBeginRead(); } catch (final Exception e) { invokeLater(new Runnable() { @Override public void run() { pipeline.fireExceptionCaught(e); } }); close(voidPromise()); }
-
@Override public final void bind(final SocketAddress localAddress, final ChannelPromise promise)
- assertEventLoop();
- //promise设置为不可以取消,确定Channel是打开的 if (!promise.setUncancellable() || !ensureOpen(promise)) { return; }
- 如果是类unix系统且不是root用的话且不是绑定到*地址的话,不能接受多播消息 // See: github.com/netty/netty… if (Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) && localAddress instanceof InetSocketAddress && !((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress() && !PlatformDependent.isWindows() && !PlatformDependent.maybeSuperUser()) { // Warn a user about the fact that a non-root user can't receive a // broadcast packet on *nix if the socket is bound on non-wildcard address. logger.warn( "A non-root user can't receive a broadcast packet if the socket " + "is not bound to a wildcard address; binding to a non-wildcard " + "address (" + localAddress + ") anyway as requested."); }
- boolean wasActive = isActive();
- //做绑定,doBind是AbstractChannel //的一个抽象类 try { doBind(localAddress); } catch (Throwable t) { safeSetFailure(promise, t); closeIfClosed(); return; }
- //如果之前Channel不是active的,现在是了 //则异步发送一个ChannelActive事件 if (!wasActive && isActive()) { invokeLater(new Runnable() { @Override public void run() { pipeline.fireChannelActive(); } }); }
- safeSetSuccess(promise);
-
@Override public final void disconnect(final ChannelPromise promise)
- assertEventLoop();
- if (!promise.setUncancellable()) { return; }
- boolean wasActive = isActive();
- //doDisconnect()是AbstractChannel中一个抽象方法 try { doDisconnect(); // Reset remoteAddress and localAddress remoteAddress = null; localAddress = null; } catch (Throwable t) { safeSetFailure(promise, t); closeIfClosed(); return; }
- //之前是active的现在不active,那么则 //提交一个发送ChannelInactive事件的任务给 //eventloop if (wasActive && !isActive()) { invokeLater(new Runnable() { @Override public void run() { pipeline.fireChannelInactive(); } }); }
- safeSetSuccess(promise);
- closeIfClosed(); // doDisconnect() might have closed the channel
-
@Override public void close(final ChannelPromise promise) { assertEventLoop();
ClosedChannelException closedChannelException = StacklessClosedChannelException.newInstance(AbstractChannel.class, "close(ChannelPromise)"); close(promise, closedChannelException, closedChannelException, false); }
-
private void close(final ChannelPromise promise, final Throwable cause, final ClosedChannelException closeCause, final boolean notify)- if (!promise.setUncancellable()) { return; }
- //如果已经启动close,则看下如果已经完成close则直接对promise设置为成功,否则的话,加监听器当完成的时候做回调, //将promise设置为成功 if (closeInitiated) { if (closeFuture.isDone()) { // Closed already. safeSetSuccess(promise); } else if (!(promise instanceof VoidChannelPromise)) { // Only needed if no VoidChannelPromise. // This means close() was called before so we just register a listener and return closeFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { promise.setSuccess(); } }); } return; }
- closeInitiated = true;
- final boolean wasActive = isActive(); final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
- this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer.
- Executor closeExecutor = prepareToClose();//这个方法是AbstractUnsafe中的一个protect方法,目前是return null
- if (closeExecutor != null) { closeExecutor.execute(new Runnable() { @Override public void run() { try { // Execute the close. doClose0(promise); } finally { // Call invokeLater so closeAndDeregister is executed in the EventLoop again! invokeLater(new Runnable() { @Override public void run() { if (outboundBuffer != null) { // Fail all the queued messages outboundBuffer.failFlushed(cause, notify); outboundBuffer.close(closeCause); } fireChannelInactiveAndDeregister(wasActive); } }); } } }); }
- else { try { // Close the channel and fail the queued messages in all cases. doClose0(promise); } finally { if (outboundBuffer != null) { // Fail all the queued messages. outboundBuffer.failFlushed(cause, notify); outboundBuffer.close(closeCause); } } if (inFlush0) { invokeLater(new Runnable() { @Override public void run() { fireChannelInactiveAndDeregister(wasActive); } }); } else { fireChannelInactiveAndDeregister(wasActive); } }
-
private void fireChannelInactiveAndDeregister(final boolean wasActive) { deregister(voidPromise(), wasActive && !isActive()); }
-
//doClose();是AbstractChannel中的一个抽象方法 private void doClose0(ChannelPromise promise) { try { doClose(); closeFuture.setClosed(); safeSetSuccess(promise); } catch (Throwable t) { closeFuture.setClosed(); safeSetFailure(promise, t); } }
-
@Override public final void closeForcibly() { assertEventLoop(); try { doClose(); } catch (Exception e) { logger.warn("Failed to close a channel.", e); } }
-
@Override public final void deregister(final ChannelPromise promise) { assertEventLoop(); deregister(promise, false); }
-
private void deregister(final ChannelPromise promise, final boolean fireChannelInactive)
- if (!promise.setUncancellable()) { return; }
- if (!registered) { safeSetSuccess(promise); return; }
- // As a user may call deregister() from within any method while doing processing in the ChannelPipeline, // we need to ensure we do the actual deregister operation later. This is needed as for example, // we may be in the ByteToMessageDecoder.callDecode(...) method and so still try to do processing in // the old EventLoop while the user already registered the Channel to a new EventLoop. Without delay, // the deregister operation this could lead to have a handler invoked by different EventLoop and so // threads. // // See: // github.com/netty/netty… invokeLater(new Runnable() { @Override public void run() { try { doDeregister(); } catch (Throwable t) { logger.warn("Unexpected exception occurred while deregistering a channel.", t); } finally { if (fireChannelInactive) { pipeline.fireChannelInactive(); } // Some transports like local and AIO does not allow the deregistration of // an open channel. Their doDeregister() calls close(). Consequently, // close() calls deregister() again - no need to fire channelUnregistered, so check // if it was registered. if (registered) { registered = false; pipeline.fireChannelUnregistered(); } safeSetSuccess(promise); } } });
-
@Override public final void write(Object msg, ChannelPromise promise)
- assertEventLoop();
- ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
- if (outboundBuffer == null) { try { // release message now to prevent resource-leak ReferenceCountUtil.release(msg); } finally { // If the outboundBuffer is null we know the channel was closed and so // need to fail the future right away. If it is not null the handling of the rest // will be done in flush0() // See github.com/netty/netty… safeSetFailure(promise, newClosedChannelException(initialCloseCause, "write(Object, ChannelPromise)")); } return; }
- //写到输出buffer中 int size; try { msg = filterOutboundMessage(msg); size = pipeline.estimatorHandle().size(msg); if (size < 0) { size = 0; } } catch (Throwable t) { try { ReferenceCountUtil.release(msg); } finally { safeSetFailure(promise, t); } return; } outboundBuffer.addMessage(msg, size, promise);
-
//真正的操作在flush0 @Override public final void flush() { assertEventLoop(); ChannelOutboundBuffer outboundBuffer = this.outboundBuffer if (outboundBuffer == null) { return; } outboundBuffer.addFlush(); flush0(); }
-
protected void flush0()
- if (inFlush0) { // Avoid re-entrance return; }
- final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; if (outboundBuffer == null || outboundBuffer.isEmpty()) { return; }
- inFlush0 = true;
- // Mark all pending write requests as failure if the channel is inactive. if (!isActive()) { try { // Check if we need to generate the exception at all. if (!outboundBuffer.isEmpty()) { if (isOpen()) { outboundBuffer.failFlushed(new NotYetConnectedException(), true); } else { // Do not trigger channelWritabilityChanged because the channel is closed already. outboundBuffer.failFlushed(newClosedChannelException(initialCloseCause, "flush0()"), false); } } } finally { inFlush0 = false; } return; }
- //doWrite是AbstractChannel中的 //抽象方法 try { doWrite(outboundBuffer); } catch (Throwable t) { handleWriteError(t); } finally { inFlush0 = false; }
static的内部类CloseFuture
static final class CloseFuture extends DefaultChannelPromise {
CloseFuture(AbstractChannel ch) {
super(ch);
}
@Override
public ChannelPromise setSuccess() {
throw new IllegalStateException();
}
@Override
public ChannelPromise setFailure(Throwable cause) {
throw new IllegalStateException();
}
@Override
public boolean trySuccess() {
throw new IllegalStateException();
}
@Override
public boolean tryFailure(Throwable cause) {
throw new IllegalStateException();
}
boolean setClosed() {
return super.trySuccess();
}
}
static的内部类AnnotatedConnectException
private static final class AnnotatedConnectException extends ConnectException {
private static final long serialVersionUID = 3901958112696433556L;
AnnotatedConnectException(ConnectException exception, SocketAddress remoteAddress) {
super(exception.getMessage() + ": " + remoteAddress);
initCause(exception);
}
// Suppress a warning since this method doesn't need synchronization
@Override
public Throwable fillInStackTrace() { // lgtm[java/non-sync-override]
return this;
}
}
static的内部类AnnotatedNoRouteToHostException
private static final class AnnotatedNoRouteToHostException extends NoRouteToHostException {
private static final long serialVersionUID = -6801433937592080623L;
AnnotatedNoRouteToHostException(NoRouteToHostException exception, SocketAddress remoteAddress) {
super(exception.getMessage() + ": " + remoteAddress);
initCause(exception);
}
// Suppress a warning since this method doesn't need synchronization
@Override
public Throwable fillInStackTrace() { // lgtm[java/non-sync-override]
return this;
}
}
static的内部类AnnotatedSocketException
private static final class AnnotatedSocketException extends SocketException {
private static final long serialVersionUID = 3896743275010454039L;
AnnotatedSocketException(SocketException exception, SocketAddress remoteA
super(exception.getMessage() + ": " + remoteAddress);
initCause(exception);
}
// Suppress a warning since this method doesn't need synchronization
@Override
public Throwable fillInStackTrace() { // lgtm[java/non-sync-override]
return this;
}
}
3 总结
AbstractChannel中的方法实现都委托给了pipeline了。AbstractUnsafe的接口的实现都是写了模板方法,核心的实现会调用AbstractChannel的抽象方法。