[编织消息框架][netty源码分析]7 Unsafe 实现类NioSocketChannelUnsafe职责与实现
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职责与实现的更多相关文章
- [编织消息框架][netty源码分析]6 ChannelPipeline 实现类DefaultChannelPipeline职责与实现
ChannelPipeline 负责channel数据进出处理,如数据编解码等.采用拦截思想设计,经过A handler处理后接着交给next handler ChannelPipeline 并不是直 ...
- [编织消息框架][netty源码分析]4 eventLoop 实现类NioEventLoop职责与实现
NioEventLoop 是jdk nio多路处理实现同修复jdk nio的bug 1.NioEventLoop继承SingleThreadEventLoop 重用单线程处理 2.NioEventLo ...
- [编织消息框架][netty源码分析]11 ByteBuf 实现类UnpooledHeapByteBuf职责与实现
每种ByteBuf都有相应的分配器ByteBufAllocator,类似工厂模式.我们先学习UnpooledHeapByteBuf与其对应的分配器UnpooledByteBufAllocator 如何 ...
- [编织消息框架][netty源码分析]5 eventLoop 实现类NioEventLoopGroup职责与实现
分析NioEventLoopGroup最主有两个疑问 1.next work如何分配NioEventLoop 2.boss group 与child group 是如何协作运行的 从EventLoop ...
- [编织消息框架][netty源码分析]8 Channel 实现类NioSocketChannel职责与实现
Unsafe是托委访问socket,那么Channel是直接提供给开发者使用的 Channel 主要有两个实现 NioServerSocketChannel同NioSocketChannel 致于其它 ...
- [编织消息框架][netty源码分析]9 Promise 实现类DefaultPromise职责与实现
netty Future是基于jdk Future扩展,以监听完成任务触发执行Promise是对Future修改任务数据DefaultPromise是重要的模板类,其它不同类型实现基本是一层简单的包装 ...
- [编织消息框架][netty源码分析]5 EventLoopGroup 实现类NioEventLoopGroup职责与实现
分析NioEventLoopGroup最主有两个疑问 1.next work如何分配NioEventLoop 2.boss group 与child group 是如何协作运行的 从EventLoop ...
- [编织消息框架][netty源码分析]13 ByteBuf 实现类CompositeByteBuf职责与实现
public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements Iterable<ByteBuf ...
- [编织消息框架][netty源码分析]3 EventLoop 实现类SingleThreadEventLoop职责与实现
eventLoop是基于事件系统机制,主要技术由线程池同队列组成,是由生产/消费者模型设计,那么先搞清楚谁是生产者,消费者内容 SingleThreadEventLoop 实现 public abst ...
随机推荐
- Scrollview中嵌套ListView(自定义组件解决)
首先,ScrollView中只能放一个控件,一般都放LinearLayout,orientation属性值为vertical.在LinearLayout中放需要呈现的内容.ListView也在其中,L ...
- Day3 Pyhon的六大数据类型
Python3 中有六个标准的数据类型: Number(数字) String(字符串) List(列表) Tuple(元组) Sets(集合) Dictionary(字典) Number(数字) Py ...
- js获取宽高
document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高度 document.docume ...
- 搭建后台页面布局利用属性target 属性
HTML 5 <form> target 属性 HTML 5 <form> 标签 实例 提交一个在新窗口中打开的表单: <form action="demo_f ...
- [刷题]算法竞赛入门经典(第2版) 6-8/UVa806 - Spatial Structures
题意:黑白图像的路径表示法 代码:(Accepted,0.120s) //UVa806 - Spatial Structures //Accepted 0.120s //#define _XIENAO ...
- Android ec环境配置
ec环境配置 1.0概述 鉴于很多同事,或者新从事android开发,虽然会做android的开发,但是会遇见一些最基本的环境搭建问题,本文仅作为(win7 64位系统)eclipse中集成andro ...
- Hadoop2.6.1中的Reducer实现
正在考虑怎么方便上传图片 1.Partitioner其是一个抽象类,只有一个抽象方法.其作用是对Reducer产生的中间结果进行分片,以方便将同一分组的数据交给同一个Reducer处理 2.类的继承结 ...
- 使用Spring MVC构建REST风格WEB应用
转自:http://fancy888.iteye.com/blog/1629120 对于运行在网络上的MIS系统而言,处理数据的是整个系统的主要任务,翻开程序我们可以看到,80%以上的代码都在处理数据 ...
- 【面向对象设计原则】之里氏替换原则(LSP)
里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing 教授于1994年提出,所以使用的是这位女博士的性命名的一个 ...
- G1收集器-原创译文[未完成]
G1收集器-原创译文 原文地址 Getting Started with the G1 Garbage Collector 目的 本文介绍了如何使用G1垃圾收集器以及如何与Hotspot JVM一起使 ...