ByteToMessageDecoder
1.socket 移除时触发,最后次读数据处理 @Override
public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf = internalBuffer();
if (buf.isReadable()) {
ByteBuf bytes = buf.readBytes(buf.readableBytes());
buf.release();
ctx.fireChannelRead(bytes);
}
cumulation = null;
ctx.fireChannelReadComplete();
handlerRemoved0(ctx);
} 2.读取数据 ByteBuf release,discardSomeReadBytes 方法后面研究 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
RecyclableArrayList out = RecyclableArrayList.newInstance();//创建包装过的数组
try {
if (msg instanceof ByteBuf) {
ByteBuf data = (ByteBuf) msg;
if (cumulation == null) { //是否继续读取数据
cumulation = data;
try {
callDecode(ctx, cumulation, out);
} finally {
if (cumulation != null && !cumulation.isReadable()) {
cumulation.release();
cumulation = null;
}
}
} else {//继续读取处理
try {
//如果剩余空间不够开创建新空间
if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes()) {
ByteBuf oldCumulation = cumulation;
cumulation = ctx.alloc().buffer(oldCumulation.readableBytes() + data.readableBytes());
cumulation.writeBytes(oldCumulation);
oldCumulation.release();
}
cumulation.writeBytes(data);
callDecode(ctx, cumulation, out);
} finally {
if (cumulation != null) {
if (!cumulation.isReadable()) {
cumulation.release();
cumulation = null;
} else {
cumulation.discardSomeReadBytes();
}
}
data.release();
}
}
} else {
out.add(msg);
}
} catch (DecoderException e) {
throw e;
} catch (Throwable t) {
throw new DecoderException(t);
} finally {
int size = out.size();
if (size == 0) {
decodeWasNull = true;
} else {
for (int i = 0; i < size; i ++) {
ctx.fireChannelRead(out.get(i));
}
}
out.recycle();
}
} //其实只要管核心代码 decode 调用业务处理
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
try {
//循环读取数据
while (in.isReadable()) {
int outSize = out.size();
int oldInputLength = in.readableBytes();
decode(ctx, in, out);//业务扩展处理 // Check if this handler was removed before continuing the loop.
// If it was removed, it is not safe to continue to operate on the buffer.
//
// See https://github.com/netty/netty/issues/1664
//如果 handler 删除之前,那么不读取数据了
if (ctx.isRemoved()) {
break;
}
//下面写得很不清晰。。。。。 if (outSize == out.size()) {
if (oldInputLength == in.readableBytes()) {
break;
} else {
continue;
}
} if (oldInputLength == in.readableBytes()) {
throw new DecoderException(
StringUtil.simpleClassName(getClass()) +
".decode() did not read anything but decoded a message.");
} if (isSingleDecode()) {
break;
}
}
} catch (DecoderException e) {
throw e;
} catch (Throwable cause) {
throw new DecoderException(cause);
}
}

netty ByteToMessageDecoder 分析的更多相关文章

  1. Netty原理分析

    Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用 ...

  2. Netty系列之Netty可靠性分析

      作者 李林锋 发布于 2014年6月19日 | 29 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 稍后阅读 我的阅读清单   1. 背景 1.1. 宕机的代价 1.1. ...

  3. Netty启动分析

    基于Netty-3.2.5 先看一段Netty的服务端代码: import java.net.InetSocketAddress; import java.util.concurrent.Execut ...

  4. 【转】Netty系列之Netty可靠性分析

    http://www.infoq.com/cn/articles/netty-reliability 首先,我们要从Netty的主要用途来分析它的可靠性,Netty目前的主流用法有三种: 1) 构建R ...

  5. Netty代码分析

    转自:http://www.blogjava.net/BucketLi/archive/2010/12/28/332462.html Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开 ...

  6. Netty系列之Netty可靠性分析--转载

    原文地址:http://www.infoq.com/cn/articles/netty-reliability 1. 背景 1.1. 宕机的代价 1.1.1. 电信行业 毕马威国际(KPMG Inte ...

  7. netty全局分析1

    这个系列都是别人的分析文 https://www.jianshu.com/p/ac7fb5c2640f 一丶 Netty基础入门 Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.U ...

  8. Netty 组件分析

    EventLoop 事件循环对象 EventLoop 本质是一个单线程执行器(同时维护了一个 Selector),里面有 run 方法处理 Channel 上源源不断的 io 事件. 它的继承关系比较 ...

  9. netty ByteBuf分析

    1.Heap Buffer(堆缓冲区) 2.Direct Buffer(直接缓冲区) 3.Composite Buffer(复合缓冲区) 4.PooledByteBuf 池缓冲 readerInex ...

随机推荐

  1. 工作圈redis 使用

    redis作为内存数据库,更多的是作为内存cache来使用. 再所负责的工作圈中的使用,主要是分两方面: 1.数据对象: 主题的内容存储 主题回复内容的存储 用户信息存储 圈子信息存储 2.各数据对象 ...

  2. Django实现一个相片管理系统01

    有些日子没写笔记,O(∩_∩)O哈哈~实在是肚子没有墨水啦!今天不写数据结构啦!多怀念研究数据结构的日子啊! 可是呢!最近有个项目要搞图像管理方面的,具体内容就不说啦!我们今天来实现一个简单的相册管理 ...

  3. java集合——题4,6

    4.(List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.add(“Hel ...

  4. 只写104行代码!在nopCommerce中如何实现自动生成网站地图

    表告诉我说你不知道nopCommerce是什么.它是目前.NET中最流行的完全开源网上商城,由俄罗斯的团队在2008年开始立项一直开发到现在已经是3.3版本了.代码目前托管在codeplex上,有兴趣 ...

  5. Cocos2dx.3x入门三部曲-软件环境配置(一)

    一.环境: Win7 32位 二.必备软件: l  Java JDK 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/inde ...

  6. HBase + Kerberos 配置示例(一)

    用过hbase的朋友可能都有过这样的疑问,我写一个java client,好像就提供了zookeeper quorum地址就连上hbase了,那么是不是存在安全问题?的确是,如何解决?hbase中引入 ...

  7. JavaScript 中数组实用浅析

    本文适用于HTML.ASP 中的 JavaScript 脚本代码.代码以 HTML 中的 JS 为例,如果在 ASP 中,请将 document.write 改为 Response.Write 即可. ...

  8. XMPP系列2:如何掌握XMPP协议

    michaely 回答于 2012-08-07 08:34 举报我要说的是:1.任何一个协议想学习并熟练掌握,都不是一天两天的事情.2.XMPP协议现在已经有很多成熟的架构和客户端,无需重新造轮子.3 ...

  9. MDT部署中命令行脚本的使用。

    参考:http://blogs.technet.com/b/deploymentguys/archive/2010/07/07/using-command-shell-scripts-with-mdt ...

  10. InteliJ IDEA15 安装jrebel破解文件

    使用InteliJ IDEA这个工具感觉比eclipse好用,例如它在没有源码的情况下自动反编译源码等,但是在使用的时,有个很不爽的地方就是不能实时编译,导致java代码更改了一点代码就需要重启项目, ...