標籤:adb failure 使用 ios end 實現 warning 釋放 rabl
Unsafe 是channel的內部介面, 負責跟socket底層打交道。從書寫跟命名上看是不公開給開發人員使用的,直到最後實現NioSocketChannelUnsafe也沒有公開出去
public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> { interface Unsafe { RecvByteBufAllocator.Handle recvBufAllocHandle(); SocketAddress localAddress(); SocketAddress remoteAddress(); void register(EventLoop eventLoop, ChannelPromise promise); void bind(SocketAddress localAddress, ChannelPromise promise); void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); void disconnect(ChannelPromise promise); void close(ChannelPromise promise); void closeForcibly(); void deregister(ChannelPromise promise); void beginRead(); void write(Object msg, ChannelPromise promise); void flush(); ChannelPromise voidPromise(); ChannelOutboundBuffer outboundBuffer(); } public interface NioUnsafe extends Unsafe { SelectableChannel ch(); void finishConnect(); void read(); void forceFlush(); }}
NioSocketChannelUnsafe 繼承關係為: NioSocketChannelUnsafe -> NioByteUnsafe -> AbstractNioUnsafe -> AbstractUnsafe
AbstractUnsafe:負責socket 鏈路綁定、接受、關閉,資料fush操作
每個操作大概分四個階段處理
@Override public final void bind(final SocketAddress localAddress, final ChannelPromise promise) { assertEventLoop(); //執行前檢查 if (!promise.setUncancellable() || !ensureOpen(promise)) { return; } boolean wasActive = isActive(); //調用實現 try { doBind(localAddress); } catch (Throwable t) { safeSetFailure(promise, t); closeIfClosed(); return; } //調用業務,通知pipeline if (!wasActive && isActive()) { invokeLater(()-> pipeline.fireChannelActive();); } //完成階段處理 safeSetSuccess(promise); }
@Override public final void flush() { assertEventLoop(); ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; if (outboundBuffer == null) { return; } outboundBuffer.addFlush(); flush0(); } @SuppressWarnings("deprecation") protected void flush0() { //剛完成Flush操作 if (inFlush0) { return; } final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; if (outboundBuffer == null || outboundBuffer.isEmpty()) { return; } inFlush0 = true; //發送資料前鏈路檢查 if (!isActive()) { try { if (isOpen()) { //true 通知 handler channelWritabilityChanged方法 outboundBuffer.failFlushed(FLUSH0_NOT_YET_CONNECTED_EXCEPTION, true); } else { outboundBuffer.failFlushed(FLUSH0_CLOSED_CHANNEL_EXCEPTION, false); } } finally { inFlush0 = false; } return; } try { //調用channel實現 doWrite(outboundBuffer); } 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; } }
AbstractNioUnsafe:是NioUnsafe介面模板類,簡單的封裝
NioByteUnsafe:主要對NioUnsafe介面 read操作實現
NioSocketChannelUnsafe:只是簡單的封裝,最終公開給內部使用
NioByteUnsafe read方法
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); //填充byteBuf 調用channel實現 int size = doReadBytes(byteBuf); //記錄最後讀取長度 allocHandle.lastBytesRead(size); //鏈路關閉,釋放byteBuf if (allocHandle.lastBytesRead() <= 0) { byteBuf.release(); byteBuf = null; close = allocHandle.lastBytesRead() < 0; break; } //自增訊息讀取處理次數 allocHandle.incMessagesRead(1); //已完成填充byteBuf 調用業務pipeline readPending = false; pipeline.fireChannelRead(byteBuf); byteBuf = null; } while (allocHandle.continueReading()); allocHandle.readComplete(); pipeline.fireChannelReadComplete(); if (close) { closeOnRead(pipeline); } } catch (Throwable t) { handleReadException(pipeline, byteBuf, t, close, allocHandle); } finally { //如果不是主動read 要完成後要清理read op if (!readPending && !config.isAutoRead()) { removeReadOp(); } } } }
小結:可以看出沒有任何的計算代碼,Unsafe只實現邊界檢查、流程式控制制,具體實現交給上層處理
[編織訊息架構][netty源碼分析]7 Unsafe 實作類別NioSocketChannelUnsafe職責與實現