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. EditPlus不能着色显示SQl语句的问题

    说明:今天重装了系统后,从网上安装下载了一个EditPlus阅读代码,发现sql语句是灰色的,不和以前的带有颜色的看着美观了,顿时心里别扭了起来.以为下错了版本,可是换了好几个,都是这样,网上查了一下 ...

  2. paip.语义相关是否可在 哈米 的语义分析中应用

    paip.语义相关是否可在 哈米 的语义分析中应用 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn. ...

  3. JavaScript-语法基础

    在学习任何一门编程语言之前,我们都需要了解这门语言并学习这么语言的语法基础,掌握语法基础之后才可以进行一门语言的使用,本文在这里将详细介绍JavaScript的语法基础,使得以后能够快速的进行Java ...

  4. iOS开发之静态库(一)—— 基本概念

    在项目开发过程中,经常出现优秀代码重用现象,又或者提供给第三方功能模块却又不想让其看到源代码,这些时候,通常的做法是将代码封装成库或者框架,这些在Windows编程或Linux编程中非常容易实现的过程 ...

  5. Proxy模式:管理第三方API

    软件中的Barrier. 数据从程序移到DB中时,要跨越数据库的Barrier.消息从一个PC到另一个PC时,要跨越网络Barrier. 跨越可能是复杂的,很可能处理Barrier的Code会多于处理 ...

  6. 在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。

    //在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’:输出这个数组中的所有元素. char [][]y=new char [10][10 ...

  7. Hello.class所在路径下, 输入命令:java Hello.class,会出现什么结果,为什么?

    所在路径下, 输入命令:java Hello.class: 因为DOS没有规定路径,所有么有在默认路径下找到Hello.class文件,导致提示 错误: 找不到或无法加载主类 Hello.class.

  8. FreeSwitch安装配置记录

    安装FreeSwitch 主要命令如下: git clone -b v1.2.stable git://git.freeswitch.org/freeswitch.gitcd freeswitch/. ...

  9. 在 C++Builder 工程里调用 DLL 函数

    调用 Visual C++ DLL 给 C++Builder 程序员提出了一些独特的挑战.在我们试图解决 Visual C++ 生成的 DLL 之前,回顾一下如何调用一个 C++Builder 创建的 ...

  10. c#之第三课

    学习获取终端输入的参数并且打印,以及使用循环. using System; public class CommandLine { public static void Main(string[] ar ...