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; } } }