write 事件:
ChannelHandlerContext ctx.write(object)
|
|
\|/
channel.pipeline()中ChannelHandler链,触发ctx.write(object)的ChannelHandler所在链的位置--》head方向上的第一个的ChannelHander开始,
依次调用((ChannelOutboundHandler) handler()).write(this, msg, promise); 直到head.
|
|
\|/
head类:将数据写入缓冲区
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
unsafe.write(msg, promise);//写入缓冲区
}
|
|
\|/
当flush触发,write方法返回的DefaultPromes.trySuccess被调用
flush 事件:
ChannelHandlerContext ctx.flush(object)
|
|
\|/
channel.pipeline()中ChannelHandler链,触发ctx.flush()的ChannelHandler所在链的位置--》head方向上的第一个的ChannelHander开始,
依次调用 ((ChannelOutboundHandler) handler()).flush(this);; 直到head.
|
|
|
\|/
head类的flush被调用:
@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
unsafe.flush();//触发缓冲区数据写入对端网络
}
|
|
|
\|/
触发write方法返回的DefaultPromes.trySuccess
protected abstract class AbstractUnsafe implements Unsafe {
public final void write(Object msg, ChannelPromise promise) {
assertEventLoop();
ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (outboundBuffer == null) {
// 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 https://github.com/netty/netty/issues/2362
safeSetFailure(promise, WRITE_CLOSED_CHANNEL_EXCEPTION);
// release message now to prevent resource-leak
ReferenceCountUtil.release(msg);
return;
}
int size;
try {
msg = filterOutboundMessage(msg);
size = pipeline.estimatorHandle().size(msg);
if (size < 0) {
size = 0;
}
} catch (Throwable t) {
safeSetFailure(promise, t);
ReferenceCountUtil.release(msg);
return;
}
outboundBuffer.addMessage(msg, size, promise);//添加到缓冲区
}
}
protected abstract class AbstractUnsafe implements Unsafe {
@Override
public final void flush() {
assertEventLoop();
outboundBuffer.addFlush();
flush0();
}
@SuppressWarnings("deprecation")
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 {
if (isOpen()) {
outboundBuffer.failFlushed(FLUSH0_NOT_YET_CONNECTED_EXCEPTION, true);
} else {
// Do not trigger channelWritabilityChanged because the channel is closed already.
outboundBuffer.failFlushed(FLUSH0_CLOSED_CHANNEL_EXCEPTION, false);
}
} finally {
inFlush0 = false;
}
return;
}
try {
doWrite(outboundBuffer);
} catch (Throwable t) {
//ignore some code
} finally {
inFlush0 = false;
}
}
}