- 浏览: 953972 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
netty Inboudn/Outbound通道Invoker:http://donald-draper.iteye.com/blog/2388233
netty 异步任务-ChannelFuture:http://donald-draper.iteye.com/blog/2388297
netty 管道线定义-ChannelPipeline:http://donald-draper.iteye.com/blog/2388453
netty 默认Channel管道线初始化:http://donald-draper.iteye.com/blog/2388613
netty 默认Channel管道线-添加通道处理器:http://donald-draper.iteye.com/blog/2388726
netty 默认Channel管道线-通道处理器移除与替换:http://donald-draper.iteye.com/blog/2388793
netty 默认Channel管道线-Inbound和Outbound事件处理:http://donald-draper.iteye.com/blog/2389148
引言:
在前面的几篇文章中我们看了Channle管道的默认实现,每个通道拥有一个Channel管道,管道用于管理通道处理器,管道以上下文模式管理通道处理器,每个通道上下文拥有一个前驱和后继上下文,可以说,即通道上下文在管道中是一个双向链表,上下文链表的头部为HeadContext,尾部为TailContext。管道主要通过上下文的inbound和oubound标志判断上下文类型。管道处理Inbound事件首先从头部上下文开始,直到尾部上下文,最后默认直接丢弃。 管道处理Outbound相关事件,从尾部上下文到头部上下文,到达头部时,交由上下文属管道关联的Channel的Unsafe处理。
今天我们来看一下通道处理器下文接口的定义:
总结:
通道处理器上下文ChannelHandlerContext,使通道处理器可以与管道和管道中其他处理器进行交互。当IO事件发生时,处理可以将事件转发给所属管道的下一个通道处理器,同时可以动态修改处理器所属的管道。通过上下文可以获取关联通道,处理器,事件执行器,上下文名,所属管道等信息。同时可以通过AttributeKey存储上下文属性,用alloc方法获取通道上下文的字节buf分配器,用于分配buf。
附:
//AttributeMap
//AttributeKey
//ConstantPool
//ByteBufAllocator
netty 异步任务-ChannelFuture:http://donald-draper.iteye.com/blog/2388297
netty 管道线定义-ChannelPipeline:http://donald-draper.iteye.com/blog/2388453
netty 默认Channel管道线初始化:http://donald-draper.iteye.com/blog/2388613
netty 默认Channel管道线-添加通道处理器:http://donald-draper.iteye.com/blog/2388726
netty 默认Channel管道线-通道处理器移除与替换:http://donald-draper.iteye.com/blog/2388793
netty 默认Channel管道线-Inbound和Outbound事件处理:http://donald-draper.iteye.com/blog/2389148
引言:
在前面的几篇文章中我们看了Channle管道的默认实现,每个通道拥有一个Channel管道,管道用于管理通道处理器,管道以上下文模式管理通道处理器,每个通道上下文拥有一个前驱和后继上下文,可以说,即通道上下文在管道中是一个双向链表,上下文链表的头部为HeadContext,尾部为TailContext。管道主要通过上下文的inbound和oubound标志判断上下文类型。管道处理Inbound事件首先从头部上下文开始,直到尾部上下文,最后默认直接丢弃。 管道处理Outbound相关事件,从尾部上下文到头部上下文,到达头部时,交由上下文属管道关联的Channel的Unsafe处理。
今天我们来看一下通道处理器下文接口的定义:
package io.netty.channel; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.util.Attribute; import io.netty.util.AttributeKey; import io.netty.util.AttributeMap; import io.netty.util.concurrent.EventExecutor; import java.nio.channels.Channels; /** * Enables a {@link ChannelHandler} to interact with its {@link ChannelPipeline} * and other handlers. Among other things a handler can notify the next {@link ChannelHandler} in the * {@link ChannelPipeline} as well as modify the {@link ChannelPipeline} it belongs to dynamically. *通道处理器上下文ChannelHandlerContext,使通道处理器可以与管道和管道中其他处理器进行交互。 当IO事件发生时,处理可以将事件转发给所属管道的下一个通道处理器,同时可以动态修改处理器所属的管道。 * <h3>Notify</h3> *通知 * You can notify the closest handler in the same {@link ChannelPipeline} by calling one of the various methods * provided here. *你可以使用提供的方法,通知邻近的通道处理器,事件触发。 * Please refer to {@link ChannelPipeline} to understand how an event flows. *同时可以参考管道来理解事件流 * <h3>Modifying a pipeline</h3> *修改管道 * You can get the {@link ChannelPipeline} your handler belongs to by calling * {@link #pipeline()}. A non-trivial application could insert, remove, or * replace handlers in the pipeline dynamically at runtime. *可以使用通道处理器上下文的#pipeline方法,获取处理器所属管道。引用在运行时环境 下,可以插入移除替换管道中的处理器 * <h3>Retrieving for later use</h3> *用于获取相关信息 * You can keep the {@link ChannelHandlerContext} for later use, such as * triggering an event outside the handler methods, even from a different thread. 在通道处理器方法之外的事件触发,甚至一个不同的线程中,你可以保存通道处理器上下文,以便使用。 * <pre> 下面是一个保存上下文信息的实例 * public class MyHandler extends {@link ChannelDuplexHandler} { * * <b>private {@link ChannelHandlerContext} ctx;</b> * * public void beforeAdd({@link ChannelHandlerContext} ctx) { * <b>this.ctx = ctx;</b> * } * * public void login(String username, password) { * ctx.write(new LoginMessage(username, password)); * } * ... * } * </pre> * * <h3>Storing stateful information</h3> *存储信息,不过当前已经被遗弃 * {@link #attr(AttributeKey)} allow you to * store and access stateful information that is related with a handler and its * context. Please refer to {@link ChannelHandler} to learn various recommended * ways to manage stateful information. *#attr(AttributeKey)方法运行你存储与通道处理器和上下文关联的信息。参考通道处理器学习更多管理 处理器和上下文属性方式。 * <h3>A handler can have more than one context</h3> *一个处理可以有多个关联上下文 * Please note that a {@link ChannelHandler} instance can be added to more than * one {@link ChannelPipeline}. It means a single {@link ChannelHandler} * instance can have more than one {@link ChannelHandlerContext} and therefore * the single instance can be invoked with different * {@link ChannelHandlerContext}s if it is added to one or more * {@link ChannelPipeline}s more than once. 需要注意的是,通道处理器实例可以添加到多个管道中。意味着一个通道处理器可以有多个上下文, 如果通道处理器添加不止一个管道中,那么实例可以被多个上下文调用。 * <p> * For example, the following handler will have as many independent {@link AttributeKey}s * as how many times it is added to pipelines, regardless if it is added to the * same pipeline multiple times or added to different pipelines multiple times: 比如,下面一个处理器由于多次添加到通道中,可以有很多独立的属性,不管是添加一个通道多次, 还是不同的管道多次。 * <pre> * public class FactorialHandler extends {@link ChannelInboundHandlerAdapter} { * * private final {@link AttributeKey}<{@link Integer}> counter = {@link AttributeKey}.valueOf("counter"); * * // This handler will receive a sequence of increasing integers starting * // from 1. * {@code @Override} * public void channelRead({@link ChannelHandlerContext} ctx, Object msg) { * Integer a = ctx.attr(counter).get(); * * if (a == null) { * a = 1; * } * * attr.set(a * (Integer) msg); * } * } * * // Different context objects are given to "f1", "f2", "f3", and "f4" even if * // they refer to the same handler instance. Because the FactorialHandler * // stores its state in a context object (using an {@link AttributeKey}), the factorial is * // calculated correctly 4 times once the two pipelines (p1 and p2) are active. * FactorialHandler fh = new FactorialHandler(); * 即使参考相同的处理器实例,但相应的上下文 "f1", "f2", "f3", and "f4",并不相同。 由于处理器存储着一个上下文属性,一旦管道线激活,将会调用4次。 * {@link ChannelPipeline} p1 = {@link Channels}.pipeline(); * p1.addLast("f1", fh); * p1.addLast("f2", fh); * * {@link ChannelPipeline} p2 = {@link Channels}.pipeline(); * p2.addLast("f3", fh); * p2.addLast("f4", fh); * </pre> * * <h3>Additional resources worth reading</h3> * <p>另外值得阅读的资源 * Please refer to the {@link ChannelHandler}, and * {@link ChannelPipeline} to find out more about inbound and outbound operations, * what fundamental differences they have, how they flow in a pipeline, and how to handle * the operation in your application. 请参考通道处理器和管道,获取更多的Inbound和Outbound操作信息,及两种操作的基本不同点,如何在管道中传输和 在应用中如何处理操作。 */ public interface ChannelHandlerContext extends AttributeMap, ChannelInboundInvoker, ChannelOutboundInvoker { /** * Return the {@link Channel} which is bound to the {@link ChannelHandlerContext}. 获取通道处理器上下文关联通道 */ Channel channel(); /** * Returns the {@link EventExecutor} which is used to execute an arbitrary task. 获取上下文事件执行器,用于执行任务 */ EventExecutor executor(); /** * The unique name of the {@link ChannelHandlerContext}.The name was used when then {@link ChannelHandler} * was added to the {@link ChannelPipeline}. This name can also be used to access the registered * {@link ChannelHandler} from the {@link ChannelPipeline}. 通道上下文的名字,即通道处理器添加到管道时的名字。此名字可以从管道获取对应的通道处理器 */ String name(); /** * The {@link ChannelHandler} that is bound this {@link ChannelHandlerContext}. 获取上下文关联的通道处理器 */ ChannelHandler handler(); /** * Return {@code true} if the {@link ChannelHandler} which belongs to this context was removed * from the {@link ChannelPipeline}. Note that this method is only meant to be called from with in the * {@link EventLoop}. 判断当前通道处理器关联上下文是否从管道移除。此方法在事件循环中调用 */ boolean isRemoved(); //触发Inbound事件方法 @Override ChannelHandlerContext fireChannelRegistered(); @Override ChannelHandlerContext fireChannelUnregistered(); @Override ChannelHandlerContext fireChannelActive(); @Override ChannelHandlerContext fireChannelInactive(); @Override ChannelHandlerContext fireExceptionCaught(Throwable cause); @Override ChannelHandlerContext fireUserEventTriggered(Object evt); @Override ChannelHandlerContext fireChannelRead(Object msg); @Override ChannelHandlerContext fireChannelReadComplete(); @Override ChannelHandlerContext fireChannelWritabilityChanged(); @Override ChannelHandlerContext read(); @Override ChannelHandlerContext flush(); /** * Return the assigned {@link ChannelPipeline} 获取所属管道 */ ChannelPipeline pipeline(); /** * Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s. 获取通道上下文的字节buf分配器,用于分配buf */ ByteBufAllocator alloc(); /** * @deprecated Use {@link Channel#attr(AttributeKey)} 获取指定key的属性值,已丢弃 */ @Deprecated @Override <T> Attribute<T> attr(AttributeKey<T> key); /** * @deprecated Use {@link Channel#hasAttr(AttributeKey)} 判断是否拥有属性值 */ @Deprecated @Override <T> boolean hasAttr(AttributeKey<T> key); }
总结:
通道处理器上下文ChannelHandlerContext,使通道处理器可以与管道和管道中其他处理器进行交互。当IO事件发生时,处理可以将事件转发给所属管道的下一个通道处理器,同时可以动态修改处理器所属的管道。通过上下文可以获取关联通道,处理器,事件执行器,上下文名,所属管道等信息。同时可以通过AttributeKey存储上下文属性,用alloc方法获取通道上下文的字节buf分配器,用于分配buf。
附:
//AttributeMap
package io.netty.util; /** * Holds {@link Attribute}s which can be accessed via {@link AttributeKey}. * * Implementations must be Thread-safe. */ public interface AttributeMap { /** * Get the {@link Attribute} for the given {@link AttributeKey}. This method will never return null, but may return * an {@link Attribute} which does not have a value set yet. */ <T> Attribute<T> attr(AttributeKey<T> key); /** * Returns {@code} true if and only if the given {@link Attribute} exists in this {@link AttributeMap}. */ <T> boolean hasAttr(AttributeKey<T> key); }
//AttributeKey
/** * Key which can be used to access {@link Attribute} out of the {@link AttributeMap}. Be aware that it is not be * possible to have multiple keys with the same name. * * @param <T> the type of the {@link Attribute} which can be accessed via this {@link AttributeKey}. */ @SuppressWarnings("UnusedDeclaration") // 'T' is used only at compile time public final class AttributeKey<T> extends AbstractConstant<AttributeKey<T>> { private static final ConstantPool<AttributeKey<Object>> pool = new ConstantPool<AttributeKey<Object>>() {
//ConstantPool
/** * A pool of {@link Constant}s. * * @param <T> the type of the constant */ public abstract class ConstantPool<T extends Constant<T>> { private final ConcurrentMap<String, T> constants = PlatformDependent.newConcurrentHashMap(); private final AtomicInteger nextId = new AtomicInteger(1);
//ByteBufAllocator
/** * Implementations are responsible to allocate buffers. Implementations of this interface are expected to be * thread-safe. */ public interface ByteBufAllocator { ByteBufAllocator DEFAULT = ByteBufUtil.DEFAULT_ALLOCATOR; /** * Allocate a {@link ByteBuf}. If it is a direct or heap buffer * depends on the actual implementation. */ ByteBuf buffer(); /** * Allocate a {@link ByteBuf} with the given initial capacity. * If it is a direct or heap buffer depends on the actual implementation. */ ByteBuf buffer(int initialCapacity); /** * Allocate a {@link ByteBuf} with the given initial capacity and the given * maximal capacity. If it is a direct or heap buffer depends on the actual * implementation. */ ByteBuf buffer(int initialCapacity, int maxCapacity); /** * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. */ ByteBuf ioBuffer(); /** * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. */ ByteBuf ioBuffer(int initialCapacity); /** * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. */ ByteBuf ioBuffer(int initialCapacity, int maxCapacity); /** * Allocate a heap {@link ByteBuf}. */ ByteBuf heapBuffer(); /** * Allocate a heap {@link ByteBuf} with the given initial capacity. */ ByteBuf heapBuffer(int initialCapacity); /** * Allocate a heap {@link ByteBuf} with the given initial capacity and the given * maximal capacity. */ ByteBuf heapBuffer(int initialCapacity, int maxCapacity); /** * Allocate a direct {@link ByteBuf}. */ ByteBuf directBuffer(); /** * Allocate a direct {@link ByteBuf} with the given initial capacity. */ ByteBuf directBuffer(int initialCapacity); /** * Allocate a direct {@link ByteBuf} with the given initial capacity and the given * maximal capacity. */ ByteBuf directBuffer(int initialCapacity, int maxCapacity); /** * Allocate a {@link CompositeByteBuf}. * If it is a direct or heap buffer depends on the actual implementation. */ CompositeByteBuf compositeBuffer(); /** * Allocate a {@link CompositeByteBuf} with the given maximum number of components that can be stored in it. * If it is a direct or heap buffer depends on the actual implementation. */ CompositeByteBuf compositeBuffer(int maxNumComponents); /** * Allocate a heap {@link CompositeByteBuf}. */ CompositeByteBuf compositeHeapBuffer(); /** * Allocate a heap {@link CompositeByteBuf} with the given maximum number of components that can be stored in it. */ CompositeByteBuf compositeHeapBuffer(int maxNumComponents); /** * Allocate a direct {@link CompositeByteBuf}. */ CompositeByteBuf compositeDirectBuffer(); /** * Allocate a direct {@link CompositeByteBuf} with the given maximum number of components that can be stored in it. */ CompositeByteBuf compositeDirectBuffer(int maxNumComponents); /** * Returns {@code true} if direct {@link ByteBuf}'s are pooled */ boolean isDirectBufferPooled(); /** * Calculate the new capacity of a {@link ByteBuf} that is used when a {@link ByteBuf} needs to expand by the * {@code minNewCapacity} with {@code maxCapacity} as upper-bound. */ int calculateNewCapacity(int minNewCapacity, int maxCapacity); }
发表评论
-
netty NioSocketChannel解析
2017-09-29 12:50 1242netty 抽象BootStrap定义:http://dona ... -
netty Pooled字节buf分配器
2017-09-28 13:00 1982netty 字节buf定义:http://donald-dra ... -
netty Unpooled字节buf分配器
2017-09-26 22:01 2369netty 字节buf定义:http://donald-dra ... -
netty 抽象字节buf分配器
2017-09-26 08:43 1265netty 字节buf定义:http:// ... -
netty 复合buf概念
2017-09-25 22:31 1260netty 字节buf定义:http://donald-dra ... -
netty 抽象字节buf引用计数器
2017-09-22 12:48 1534netty 字节buf定义:http://donald-dra ... -
netty 抽象字节buf解析
2017-09-22 09:00 1769netty 通道接口定义:http://donald-drap ... -
netty 资源泄漏探测器
2017-09-21 09:37 1334netty 通道接口定义:http://donald-drap ... -
netty 字节buf定义
2017-09-20 08:31 2758netty 通道接口定义:http://donald-drap ... -
netty 默认通道配置后续
2017-09-18 08:36 2102netty 通道接口定义:http://donald-drap ... -
netty 默认通道配置初始化
2017-09-17 22:51 1954netty 通道接口定义:http://donald-drap ... -
netty 通道配置接口定义
2017-09-17 14:51 1019netty 通道接口定义:http://donald-drap ... -
netty NioServerSocketChannel解析
2017-09-16 13:01 1814netty ServerBootStrap解析:http:// ... -
netty 抽象nio消息通道
2017-09-15 15:30 1168netty 通道接口定义:http:/ ... -
netty 抽象nio字节通道
2017-09-14 22:39 1150netty 通道接口定义:http:/ ... -
netty 抽象nio通道解析
2017-09-14 17:23 896netty 通道接口定义:http://donald-drap ... -
netty 抽象通道后续
2017-09-13 22:40 1244netty Inboudn/Outbound通道Inv ... -
netty 通道Outbound缓冲区
2017-09-13 14:31 2129netty 通道接口定义:http:/ ... -
netty 抽象Unsafe定义
2017-09-12 21:24 998netty 通道接口定义:http:/ ... -
netty 抽象通道初始化
2017-09-11 12:56 1796netty 管道线定义-ChannelPipeline:htt ...
相关推荐
在公司做项目的时候发现用Netty进行TCP/IP通信的Netty客户端接收到的数据进制乱码,经过摸索,终于成功解决了这个鸡肋的问题
Netty基础,用于学习Netty,参考黑马程序员的netty教程
netty定义1.netty定义2.阻塞与非阻塞3.同步与异步 1.netty定义 简单来讲,Netty是一个提供了易于使用的API的客户端/服务端框架。Netty并发非常高,一个非阻塞的IO,Netty传输速度也非常快,因为他是0拷贝,什么是零...
netty-3.2.5.Final.jar netty包
springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合...
Netty入门教程
Netty (netty-netty-4.0.56.Final.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
Netty 教程 Netty权威指南 507页完整版
netty-buffer-4.1.32.Final-sources.jar netty-buffer-4.1.32.Final.jar netty-build-22-sources.jar netty-build-22.jar netty-codec-4.1.32.Final-sources.jar netty-codec-4.1.32.Final.jar netty-codec-...
Netty (netty-netty-3.10.6.Final.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
85_Netty编解码器剖析与入站出站处理器详解;86_Netty自定义编解码器与TCP粘包拆包问题;87_Netty编解码器执行流程深入分析;88_ReplayingDecoder源码分析与特性解读;89_Netty常见且重要编解码器详解;90_TCP粘包与...
Netty在Android开发中的应用实战系列(一)——— 搭建服务端与客户端:https://azhon.blog.csdn.net/article/details/100569489 Netty在Android开发中的应用实战系列(二)——— Encoder | Decoder | Handler 的...
根据给定的消息协议,自己定义一个消息类,编写好服务端与客户端,自定义好编解码器,在客户端发送此消息,服务端获取消息并向客户端发送同样格式的消息;导入Eclipse maven项目运行即可跑通。
Netty (netty-netty-5.0.0.Alpha2.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
跟闪电侠学Netty:Netty即时聊天实战与底层原理-book-netty
Netty大纲-同步netty专栏
85_Netty编解码器剖析与入站出站处理器详解 86_Netty自定义编解码器与TCP粘包拆包问题 87_Netty编解码器执行流程深入分析 88_ReplayingDecoder源码分析与特性解读 89_Netty常见且重要编解码器详解 90_TCP粘包与拆包...
netty学习,netty进阶之路:实战,案列,进阶知识
netty代码demo