AbstractChannel 是ChannelOutboundInvoker 的子类。
DefaultPipeLine 是ChannelOutboundInvoker 的子类。
那么哪个类才是真正实现ChannelOutboundInvoker 的功能? 是DefaultPipeLine 。
那AbstractChannel 为什么要实现ChannelOutboundInvoker ?
AbstractChannel 中实现了ChannelOutboundInvoker 的方法:只是简单的委派给DefaultPipeLine 。
AbstractChannel 中实现了ChannelOutboundInvoker 目的:在channel中平滑的调用ChannelOutboundInvoker 方法(委派给DefaultPipeLine ),相当于AbstractChannel 是DefaultPipeLine 的代理。
/**
*
* 持有多个Attribute对象,并通过AttributeKey可以获了
* 实现必须是线程安全的
*/
public interface AttributeMap {
/**
* 通过AttributeKey 获取Attribute,如果没有就创建一个默认的Attribute返回
*/
<T> Attribute<T> attr(AttributeKey<T> key);
/**
* 是否存在AttributeKey对应的Attribute
*/
<T> boolean hasAttr(AttributeKey<T> key);
}
/**
* DefaultAttributeMap 实现了AttributeMap,内部使用
* private volatile AtomicReferenceArray<DefaultAttribute<?>> attributes; 保存DefaultAttribute 。
**/
public class DefaultAttributeMap implements AttributeMap {
}
public interface ChannelOutboundInvoker {
/**
* 请求端口绑定到SocketAddress并通知ChannelFuture 操作成功或失败
* This will result in having the
* {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
* called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.bind(ChannelHandlerContext, SocketAddress, ChannelPromise)-->this
*/
ChannelFuture bind(SocketAddress localAddress);
/**
* 请求连接远端地址(SocketAddress)并通知ChannelFuture 操作成功或失败
*
* 如果连接超时,触发ChannelFuture 失败with ConnectTimeoutException
* 如果连接拒绝,触发ChannelFuture 失败with ConnectException
* This will result in having the
* {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)—>this
*/
ChannelFuture connect(SocketAddress remoteAddress);
/**
* 请求连接远端地址(SocketAddress)并通知ChannelFuture 操作成功或失败
*
* This will result in having the
* {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)—>this
*/
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
/**
* 请求远端断开连接并通知ChannelFuture 操作成功或失败
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)-->this
*/
ChannelFuture disconnect();
/**
* Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
* either because the operation was successful or because of
* an error.
* 请求连接关闭 并通知ChannelFuture 操作成功或失败
* 一旦连接关闭,不能再重复使用它
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)-->this
*/
ChannelFuture close();
/**
* 请求从关联的EventExecutor上取消注册(不再获取此channel上的网络事件,read,write等)并通知ChannelFuture 操作成功或失败
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)-->this
*/
ChannelFuture deregister();
/**
* 请求端口绑定到SocketAddress并通知ChannelFuture 操作成功或失败
* 同时 ChannelPromise被通知操作成功或失败
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
* called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)-->this
*/
ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
/**
* Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
* completes, either because the operation was successful or because of an error.
*
* The given {@link ChannelFuture} will be notified.
* 请求连接远端地址(SocketAddress)并通知ChannelFuture 操作成功或失败
* 同时 ChannelPromise被通知操作成功或失败
* <p>
* If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
* a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
* will be used.
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)-->this
*/
ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
/**
* 请求连接远端地址(SocketAddress)并通知ChannelFuture 操作成功或失败
* 同时 ChannelPromise被通知操作成功或失败
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)-->this
*/
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
/**
* 请求远端断开连接并通知ChannelFuture 操作成功或失败
* 同时 ChannelPromise被通知操作成功或失败
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.disconnect(ChannelHandlerContext, ChannelPromise)-->this
*/
ChannelFuture disconnect(ChannelPromise promise);
/**
* Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
* either because the operation was successful or because of
* an error.
*
* After it is closed it is not possible to reuse it again.
* 请求连接关闭 并通知ChannelFuture 操作成功或失败
* 一旦连接关闭,不能再重复使用它
* 同时 ChannelPromise被通知操作成功或失败
* The given {@link ChannelPromise} will be notified.
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.close(ChannelHandlerContext, ChannelPromise)-->this
*/
ChannelFuture close(ChannelPromise promise);
/**
* 请求从关联的EventExecutor上取消注册(不再获取此channel上的网络事件,read,write等)并通知ChannelFuture 操作成功或失败
* 同时 ChannelPromise被通知操作成功或失败
* <p>
* This will result in having the
* {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.deregister(ChannelHandlerContext, ChannelPromise)-->this
*/
ChannelFuture deregister(ChannelPromise promise);
/**
* 从channel中读取数据-->第1个InBoundBuffer:
* 1.触发ChannelInboundHandler.channelRead(ChannelHandlerContext, Object)事件(读出数据的情况下)
* 2.触发ChannelInboundHandler.channelReadComplete(ChannelHandlerContext) 事件
* 如果已经有挂起的读取操作,则此方法不执行任何操作。
* This will result in having the
* {@link ChannelOutboundHandler#read(ChannelHandlerContext)}
* method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
* 调用源:
* channel-->ChannelPipeline-->ChannelOutboundHandler.read(ChannelHandlerContext)-->this
*/
ChannelOutboundInvoker read();
/**
* Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}.
* This method will not request to actual flush, so be sure to call {@link #flush()}
* once you want to request to flush all pending data to the actual transport.
* 这个方法调用->ChannelHandlerContext.ChannelPipeline 写入缓冲区,但不会立即发送出去,除非调用Flush方法
*
*/
ChannelFuture write(Object msg);
/**
* Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}.
* This method will not request to actual flush, so be sure to call {@link #flush()}
* once you want to request to flush all pending data to the actual transport.
* 这个方法调用->ChannelHandlerContext.ChannelPipeline 写入缓冲区,但不会立即发送出去,除非调用Flush方法
* 方法调用完成,ChannelPromise会得到通知
*/
ChannelFuture write(Object msg, ChannelPromise promise);
/**
* Request to flush all pending messages via this ChannelOutboundInvoker.
* 写入缓冲区数据发送出去
*/
ChannelOutboundInvoker flush();
/**
* 先调用write(Object, ChannelPromise)再调用flush()
*/
ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
/**
* 先调用write(Object)再调用flush()
*/
ChannelFuture writeAndFlush(Object msg);
/**
* 创建一个ChannelPromise
*/
ChannelPromise newPromise();
/**
* 创建一个newProgressivePromise
*/
ChannelProgressivePromise newProgressivePromise();
/**
*
* 创建一个标记为成功的ChannelFuture,ChannelFuture.isSuccess()==true,添加到此ChannelFuture上的FutureListener立即被通知
*/
ChannelFuture newSucceededFuture();
/**
* 创建一个标记为失败的ChannelFuture,ChannelFuture.isSuccess()==false,添加到此ChannelFuture上的FutureListener立即被通知
*/
ChannelFuture newFailedFuture(Throwable cause);
/**
* Return a special ChannelPromise which can be reused for different operations.
* <p>
* It's only supported to use
* it for {@link ChannelOutboundInvoker#write(Object, ChannelPromise)}.
* </p>
* <p>
* Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used
* if you want to save an object allocation for every write operation. You will not be able to detect if the
* operation was complete, only if it failed as the implementation will call
* {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case.
* </p>
* <strong>Be aware this is an expert feature and should be used with care!</strong>
*/
ChannelPromise voidPromise();
}
/**
* 一个channel(socket)通道,支持 read,write,connect,bind
* 提供:
* 1.查询channel状态 ,如 open? connected?
* 2.通过ChannelConfig 配置channel参数 ,如接收发送缓冲区大小等
* 3.IO操作read, write, connect, and bind
* 4.通过此channel关联的ChannelPipeline 触发IO事件
* 所有的IO操作都是异步的,所有操作立即返回ChannelFuture,通过ChannelFuture来获取操作结果
* SocketChannel 的parent()方法返回accept它的ServerSocketChannel
*
*/
public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {
/**
* 返回channel 唯一的ID
*/
ChannelId id();
/**
* 每一个Channel都注册到EventLoop,返回Channel关联的EventLoop
*/
EventLoop eventLoop();
/**
* 返回此channel的parent
*/
Channel parent();
/**
* 返回channel对应的配置类ChannelConfig
*/
ChannelConfig config();
/**
* channel 是否open?
*/
boolean isOpen();
/**
* Returns {@code true} if the {@link Channel} is registered with an {@link EventLoop}.
* channel 是否被注册到EventLoop(EventExecutor的实现)
*/
boolean isRegistered();
/**
* Return {@code true} if the {@link Channel} is active and so connected.
* 返回Channel是否是active?(已经连接Connected)
*/
boolean isActive();
/**
* Return the {@link ChannelMetadata} of the {@link Channel} which describe the nature of the {@link Channel}.
*/
ChannelMetadata metadata();
/**
*
* 返回channel 的本地地址(可转换为InetSocketAddress类型获取详细信息)
*/
SocketAddress localAddress();
/**
* 返回channel 的连接的远程地址(可转换为InetSocketAddress类型获取详细信息)
*/
SocketAddress remoteAddress();
/**
* 返回ChannelFuture,当channel被关闭时,ChannelFuture被触发,多次调用返回同一实列
*/
ChannelFuture closeFuture();
/**
* Returns {@code true} if and only if the I/O thread will perform the
* requested write operation immediately. Any write requests made when
* this method returns {@code false} are queued until the I/O thread is
* ready to process the queued write requests.
*/
boolean isWritable();
/**
* Get how many bytes can be written until {@link #isWritable()} returns {@code false}.
* This quantity will always be non-negative. If {@link #isWritable()} is {@code false} then 0.
* 获取当前channel能够写入多少字节
* 当isWritable()==false,返回0
* 理解:写入缓冲区能写多少数据
*/
long bytesBeforeUnwritable();
/**
* Get how many bytes must be drained from underlying buffers until {@link #isWritable()} returns {@code true}.
* This quantity will always be non-negative. If {@link #isWritable()} is {@code true} then 0.
*/
long bytesBeforeWritable();
/**
* Returns an <em>internal-use-only</em> object that provides unsafe operations.
*/
Unsafe unsafe();
/**
* 返回关联的ChannelPipeline
*/
ChannelPipeline pipeline();
/**
* 返回ByteBufAllocator,用于创建ByteBuf对象
*/
ByteBufAllocator alloc();
@Override
Channel read();
@Override
Channel flush();
/**
* Unsafe不应该由用户代码调用。
* Unsafe提供了IO调用方法(从IO线程调用)
* invoker()、localAddress()、remoteAddress()、closeForcibly()、register(EventLoop, ChannelPromise)、
* deregister(ChannelPromise)、voidPromise() 可由其它线程调用。
*/
interface Unsafe {
/**
* 返回 RecvByteBufAllocator.Handle,
* RecvByteBufAllocator.Handle 用来给接收的数据分配ByteBuf
*/
RecvByteBufAllocator.Handle recvBufAllocHandle();
/**
* 返回本地网络地址
*/
SocketAddress localAddress();
/**
* 返回远程网络地址
*/
SocketAddress remoteAddress();
/**
* 注册ChannelPromise里的channel,当注册完成后通知ChannelFuture
*/
void register(EventLoop eventLoop, ChannelPromise promise);
/**
* Bind the SocketAddress ,完成后通知ChannelPromise
*/
void bind(SocketAddress localAddress, ChannelPromise promise);
/**
* 本地channel(ChannelPromise内部)连接远程地址,完成后通知ChannelPromise
* localAddress可空
*/
void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
/**
* 断开连接(Channel在ChannelPromise内部),完成后通知ChannelPromise
*/
void disconnect(ChannelPromise promise);
/**
* 关闭Channel(Channel在ChannelPromise内部),完成后并通知ChannelPromise
*/
void close(ChannelPromise promise);
/**
* 立即关闭channel 并不触发任务事件,但当注册失败情况下触发。
*/
void closeForcibly();
/**
* Deregister the {@link Channel} of the {@link ChannelPromise} from {@link EventLoop} and notify the
* {@link ChannelPromise} once the operation was complete.
* 通过EventLoop注销(Deregister)channel(Channel在ChannelPromise内部),完成后通知ChannelPromise
*/
void deregister(ChannelPromise promise);
/**
* Schedules a read operation that fills the inbound buffer of the first {@link ChannelInboundHandler} in the
* {@link ChannelPipeline}. If there's already a pending read operation, this method does nothing.
* 调用读操作添充缓冲区(ChannelInboundHandler 在ChannelPipeline 内部)
*/
void beginRead();
/**
* Schedules a write operation.
*/
void write(Object msg, ChannelPromise promise);
/**
* Flush out all write operations scheduled via {@link #write(Object, ChannelPromise)}.
*/
void flush();
/**
* Return a special ChannelPromise which can be reused and passed to the operations in {@link Unsafe}.
* It will never be notified of a success or error and so is only a placeholder for operations
* that take a {@link ChannelPromise} as argument but for which you not want to get notified.
*/
ChannelPromise voidPromise();
/**
* Returns the {@link ChannelOutboundBuffer} of the {@link Channel} where the pending write requests are stored.
* 返回一个ChannelOutboundBuffer(缓冲区对象)
*/
ChannelOutboundBuffer outboundBuffer();
}
}
public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {
private final Channel parent;//构建器参数赋值
private final ChannelId id;//构建器创建一个DefaultChannelId
private final Unsafe unsafe;//构建器 创建一个 newUnsafe
private final DefaultChannelPipeline pipeline;//构建器 创建 new DefaultChannelPipeline(this);
private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
private final CloseFuture closeFuture = new CloseFuture(this);//一个实例
private volatile SocketAddress localAddress;//localAddress()调用时通过 unsafe().remoteAddress()获取;
private volatile SocketAddress remoteAddress;//remoteAddress()调用时通过 unsafe().remoteAddress()获取;
private volatile EventLoop eventLoop; //在unsafe.register方法被调时,赋值,值来源于参数
private volatile boolean registered;//在unsafe.register方法被调时,赋值,值来源于注册结果
protected AbstractChannel(Channel parent) {
this.parent = parent;//父channel
id = newId();//创建一个DefaultChannelId
unsafe = newUnsafe();//创建Unsafe
pipeline = newChannelPipeline();//创建 new DefaultChannelPipeline(this);
}
public ChannelFuture bind(SocketAddress localAddress) { return pipeline.bind(localAddress); }
public ChannelFuture connect(SocketAddress remoteAddress) { return pipeline.connect(remoteAddress); }
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { return pipeline.connect(remoteAddress, localAddress);}
/**
* 以下网络IO方法都与上面三个类都,功能都委派给pipeline的同名方法执行。
**/
public ChannelFuture disconnect() ;
public ChannelFuture close() ;
public ChannelFuture deregister();
public Channel flush() ;
public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) ;
public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) ;
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) ;
public ChannelFuture disconnect(ChannelPromise promise);
public ChannelFuture close(ChannelPromise promise);
public ChannelFuture deregister(ChannelPromise promise);
public Channel read() ;
public ChannelFuture write(Object msg) ;
public ChannelFuture write(Object msg, ChannelPromise promise);
public ChannelFuture writeAndFlush(Object msg) ;
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) ;
public ChannelPromise newPromise();
public ChannelProgressivePromise newProgressivePromise() ;
public ChannelFuture newSucceededFuture();
public ChannelFuture newFailedFuture(Throwable cause) ;
/**
*
* AbstractUnsafe 功能:
* 1.触发网络IO事件调用(方法是AbstractChannel子类实现)doBind、doDisconnect、doClose、doBeginRead、doWrite
* 2.对ChannelPromise 设置结果:成功或失败
* 3.触发pipeline.fireXXXX();方法
*/
protected abstract class AbstractUnsafe implements Unsafe {
//io缓存
private volatile ChannelOutboundBuffer outboundBuffer = new ChannelOutboundBuffer(AbstractChannel.this);
//用来给接收的数据分配ByteBuf
private RecvByteBufAllocator.Handle recvHandle;
//是否Flush
private boolean inFlush0;
//默认未注册
private boolean neverRegistered = true;
@Override
public RecvByteBufAllocator.Handle recvBufAllocHandle() {
if (recvHandle == null) {//从config中获取RecvByteBufAllocator.Handle
recvHandle = config().getRecvByteBufAllocator().newHandle();
}
return recvHandle;
}
@Override
public final SocketAddress localAddress() {
return localAddress0();
}
@Override
public final SocketAddress remoteAddress() {
return remoteAddress0();
}
@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
AbstractChannel.this.eventLoop = eventLoop;//给AbstractChannel.eventLoop赋值
if (eventLoop.inEventLoop()) {//如果是内部线程(NioEventLoop启动的线程),直接调用register0注册
register0(promise);
} else {
try {
eventLoop.execute(new Runnable() {//添加到NioEventLoop的任务队列,由内部线程从队列中取出再执行任务->调用register0
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
}
}
}
private void register0(ChannelPromise promise) {
try {
// check if the channel is still open as it could be closed in the mean time when the register
// call was outside of the eventLoop
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
doRegister();//执行注册操作
neverRegistered = false;//改为状态
registered = true;//channel 改变状态
// 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();
safeSetSuccess(promise);//设置ChannelPromise 为成功
pipeline.fireChannelRegistered();//触发注册事件
// Only fire a channelActive if the channel has never been registered. This prevents firing
// multiple channel actives if the channel is deregistered and re-registered.
if (isActive()) {
if (firstRegistration) {
pipeline.fireChannelActive();//只触发一次ChannelActive事件
} else if (config().isAutoRead()) {//config 自动读取为true,则自动调用读取IO读取
// This channel was registered before and autoRead() is set. This means we need to begin read
// again so that we process inbound data.
//
// See https://github.com/netty/netty/issues/4805
beginRead();
}
}
} catch (Throwable t) {
}
}
@Override
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
boolean wasActive = isActive();
try {
doBind(localAddress);
} catch (Throwable t) {}
if (!wasActive && isActive()) {//
invokeLater(new Runnable() {
@Override
public void run() {//只触发一次ChannelActive事件
pipeline.fireChannelActive();
}
});
}
safeSetSuccess(promise);//设置ChannelPromise 为成功
}
@Override
public final void disconnect(final ChannelPromise promise) {
boolean wasActive = isActive();
try {
doDisconnect();//执行网络断开
} catch (Throwable t) {
safeSetFailure(promise, t);
closeIfClosed();
return;
}
if (wasActive && !isActive()) {
invokeLater(new Runnable() {
@Override
public void run() {//只触发一次ChannelInactive事件
pipeline.fireChannelInactive();
}
});
}
safeSetSuccess(promise);
closeIfClosed(); // doDisconnect() might have closed the channel
}
@Override
public final void close(final ChannelPromise promise) {
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) {
final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (closeFuture.isDone()) {//closeFuture 只有一个实例,如果已经close了,直接返回
// Closed already.
safeSetSuccess(promise);//设置ChannelPromise 为成功
return;
}
final boolean wasActive = isActive();
this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer.
try {
// Close the channel and fail the queued messages in all cases.
doClose0(promise);//关闭
} finally { }
if (inFlush0) {
invokeLater(new Runnable() {
@Override
public void run() {
fireChannelInactiveAndDeregister(wasActive);//触发deregister、fireChannelInactive
}
});
} else {
fireChannelInactiveAndDeregister(wasActive);//触发deregister、fireChannelInactive
}
}
private void doClose0(ChannelPromise promise) {
try {
doClose();//执行关闭
closeFuture.setClosed();//设置closeFuture 状态
safeSetSuccess(promise);//设置ChannelPromise 为成功
} catch (Throwable t) {
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
private void fireChannelInactiveAndDeregister(final boolean wasActive) {
deregister(voidPromise(), wasActive && !isActive());
}
@Override
public final void deregister(final ChannelPromise promise) {
assertEventLoop();
deregister(promise, false);
}
private void deregister(final ChannelPromise promise, final boolean fireChannelInactive) {
if (!registered) {//没有注册过,直接设置ChannelPromise成功并返回
safeSetSuccess(promise);
return;
}
doDeregister();//调用doDeregister方法
}
@Override
public final void beginRead() {
try {
doBeginRead();
} catch (final Exception e) {
invokeLater(new Runnable() {
@Override
public void run() {
pipeline.fireExceptionCaught(e);//读取时有异常,触发ExceptionCaught事件
}
});
close(voidPromise());
}
}
@Override
public final void write(Object msg, ChannelPromise promise) {
ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
msg = filterOutboundMessage(msg);
size = pipeline.estimatorHandle().size(msg);
outboundBuffer.addMessage(msg, size, promise);//写入的数据存入ChannelOutboundBuffer
}
@Override
public final void flush() {
ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
outboundBuffer.addFlush();//将未flush过的数据打上状态,以便flush时取出发送
flush0();
}
@SuppressWarnings("deprecation")
protected void flush0() {
if (inFlush0) {
// Avoid re-entrance
return;
}
final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
inFlush0 = true;
try {
doWrite(outboundBuffer);
} catch (Throwable t) {
//异常处理
} finally {
inFlush0 = false;
}
}
private void invokeLater(Runnable task) {
try {
eventLoop().execute(task);//添加到NioEventLoop 执行队列,由内部线程执行
} catch (RejectedExecutionException e) {
logger.warn("Can't invoke task later as EventLoop rejected it", e);
}
}
}
/**
* 以下方法为真正调用IO的代码,由子类实现
*/
protected abstract SocketAddress localAddress0();
protected abstract SocketAddress remoteAddress0();
protected void doRegister() throws Exception {
// NOOP
}
protected abstract void doBind(SocketAddress localAddress) throws Exception;
protected abstract void doDisconnect() throws Exception;
protected abstract void doClose() throws Exception;
protected void doDeregister() throws Exception {
// NOOP
}
protected abstract void doBeginRead() throws Exception;
protected abstract void doWrite(ChannelOutboundBuffer in) throws Exception;
protected Object filterOutboundMessage(Object msg) throws Exception {
return msg;
}
/**
* 实现部分selector及selectkey相关操作:注册,取消注册,监听channel的读取
* 以及AbstractNioUnsafe 实现了connect方法
*/
public abstract class AbstractNioChannel extends AbstractChannel {
@Override
protected void doRegister() throws Exception {//在selector上注册channel
boolean selected = false;
for (;;) {
try {
selectionKey = javaChannel().register(eventLoop().selector, 0, this);//attachment==AbstractNioChannel
return;
} catch (CancelledKeyException e) {
}
}
}
@Override
protected void doDeregister() throws Exception {
eventLoop().cancel(selectionKey());//取消channel所有事件监听
}
@Override
protected void doBeginRead() throws Exception {
final int interestOps = selectionKey.interestOps();
if ((interestOps & readInterestOp) == 0) {
selectionKey.interestOps(interestOps | readInterestOp);//让selector 监听channel的读取
}
}
protected abstract class AbstractNioUnsafe extends AbstractUnsafe implements NioUnsafe {
@Override
public final void connect(
final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {
try {
if (doConnect(remoteAddress, localAddress)) {//由子类实现
if (!wasActive && active) {
pipeline().fireChannelActive();//只触发一次fireChannelActive事件
}
} else {
//
}
} catch (Throwable t) {
promise.tryFailure(annotateConnectException(t, remoteAddress));
closeIfClosed();
}
}
}
}
/**
* 实现io read,write
*/
public abstract class AbstractNioByteChannel extends AbstractNioChannel {
protected class NioByteUnsafe extends AbstractNioUnsafe {
@Override
public final void read() {
final ChannelConfig config = config();
final ChannelPipeline pipeline = pipeline();
final ByteBufAllocator allocator = config.getAllocator();
final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
allocHandle.reset(config);
ByteBuf byteBuf = null;
boolean close = false;
try {
do {
byteBuf = allocHandle.allocate(allocator);
allocHandle.lastBytesRead(doReadBytes(byteBuf)); doReadBytes//由子类实现
allocHandle.incMessagesRead(1);
readPending = false;
pipeline.fireChannelRead(byteBuf);触发pipeline.fireChannelRead事件(对象类型为ByteBuf)
byteBuf = null;
} while (allocHandle.continueReading());
allocHandle.readComplete();
pipeline.fireChannelReadComplete();触发pipeline.fireChannelReadComplete事件
} catch (Throwable t) {
//ignore
} finally {
//ignore
}
}
}
}
/**
* 执行写入操作
* 在写入缓中区中ChannelOutboundBuffer 获取需要发送的数据进入网络发送(Write)直到没有发送的事件---》在selector上取消write监听
* 如果由于网络写入缓冲区没有空间,在selector上注册write监听,并写添加任务队列任务,由线程调用flush方法继续发送
*/
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
int writeSpinCount = -1;
boolean setOpWrite = false;
for (;;) {
Object msg = in.current();//flush方法标记过的需要发送的数据
if (msg == null) {
// Wrote all messages.
clearOpWrite();//如果没有需要写入的数据,则在select 取消write监听
// Directly return here so incompleteWrite(...) is not called.
return;//退出
}
if (msg instanceof ByteBuf) {
ByteBuf buf = (ByteBuf) msg;
int readableBytes = buf.readableBytes();//
boolean done = false;
long flushedAmount = 0;
if (writeSpinCount == -1) {
writeSpinCount = config().getWriteSpinCount();
}
for (int i = writeSpinCount - 1; i >= 0; i --) {
int localFlushedAmount = doWriteBytes(buf); //doWriteBytes由子类实现数据写入
if (localFlushedAmount == 0) {//网络写入缓冲区不可以写入了,停止写入,退出
setOpWrite = true;//标记为未完成写入
break;
}
flushedAmount += localFlushedAmount;
if (!buf.isReadable()) {//没有数据需要发送了
done = true;
break;
}
}
in.progress(flushedAmount);//标记已发送的数据量,以便下次发送时接着发送
if (done) {//没有数据需要发送了
in.remove();//ChannelOutboundBuffer 移除已发送的数据
} else {
// Break the loop and so incompleteWrite(...) is called.
break;
}
} else if (msg instanceof FileRegion) {
//ignore
} else {
// Should not reach here.
throw new Error();
}
}
incompleteWrite(setOpWrite);
}
/**
* 未完成写入,在selector上注册写入事件,添加到任务队列执行:flush-->this.doWrite() 继续发送
**/
protected final void incompleteWrite(boolean setOpWrite) {
// Did not write completely.
if (setOpWrite) {
setOpWrite();//在selector上注册写入事件
} else {
// Schedule flush again later so other tasks can be picked up in the meantime
Runnable flushTask = this.flushTask;
if (flushTask == null) {
flushTask = this.flushTask = new Runnable() {
@Override
public void run() {
flush();
}
};
}
eventLoop().execute(flushTask);//线程中调用继续写入
}
}
}
/**
*
* 调用jdk SocketChannel 实现网络操作,read,write ,
*/
public class NioSocketChannel extends AbstractNioByteChannel implements io.netty.channel.socket.SocketChannel {
@Override
public boolean isActive() {
SocketChannel ch = javaChannel();
return ch.isOpen() && ch.isConnected();
}
@Override
protected SocketAddress localAddress0() {
return javaChannel().socket().getLocalSocketAddress();
}
@Override
protected SocketAddress remoteAddress0() {
return javaChannel().socket().getRemoteSocketAddress();
}
@Override
protected void doBind(SocketAddress localAddress) throws Exception {
doBind0(localAddress);
}
private void doBind0(SocketAddress localAddress) throws Exception {
if (PlatformDependent.javaVersion() >= 7) {
javaChannel().bind(localAddress);
} else {
javaChannel().socket().bind(localAddress);
}
}
@Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
if (localAddress != null) {
doBind0(localAddress);
}
boolean success = false;
try {
boolean connected = javaChannel().connect(remoteAddress);
if (!connected) {
selectionKey().interestOps(SelectionKey.OP_CONNECT);
}
success = true;
return connected;
} finally {
if (!success) {
doClose();
}
}
}
@Override
protected void doFinishConnect() throws Exception {
if (!javaChannel().finishConnect()) {
throw new Error();
}
}
@Override
protected void doDisconnect() throws Exception {
doClose();
}
@Override
protected void doClose() throws Exception {
super.doClose();
javaChannel().close();
}
@Override
protected int doReadBytes(ByteBuf byteBuf) throws Exception {
final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
allocHandle.attemptedBytesRead(byteBuf.writableBytes());
return byteBuf.writeBytes(javaChannel(), allocHandle.attemptedBytesRead());
}
@Override
protected int doWriteBytes(ByteBuf buf) throws Exception {
final int expectedWrittenBytes = buf.readableBytes();
return buf.readBytes(javaChannel(), expectedWrittenBytes);
}
}