Netty入门(3) - ChannelHandler
ChannelPipeline
ChannelHandler实例的列表,用于处理或者截获通道的接收和发送数据,让用户可以在ChannelPipeline中完全控制一个事件以及处理ChannelHandler和ChannelPipeline的交互。
每一个新的通道,都会创建一个新的ChannelPipeline并且附加到通道,永久性的耦合。
一个入站I/O事件,这个事件会从ChannelPipeline的第一个Handler开始一次通过,出站IO事件则从最后一个Handler开始依次通过。Handler可以处理时间并检查类型,不能处理则跳过,并将事件传递给下一个Handler。
我们找到,不能有其他IO-Thread的阻塞拉力影响整体的IO处理,比如JDBC。这时候可以通过一个EventExecutorGroup,自定义的事件会被包含在EventExecutorGroup的EventExecutor处理。
ChannelHandlerContext
通过context,ChannelHandler允许与其他ChannelHandler实现交互:
1、通知下一个ChannelHandler
2、想事件流全部通过ChannelPipeline,可以通过调用Channel和ChannelPipeline的方法:

3、想事件从ChannelPipeline的指定位置开始:

ChannelHandlerContext是线程安全的,可以在外部使用。
修改ChannelPipeline
调用ChannelHandlerContext的pipeline()方法能访问ChannelPipeline,可以运行时动态调整ChannelHandler。可以保持ChannelHandlerContext供以后使用,线程安全:
public class WriteHandler extends ChannelHandlerAdapter {
private ChannelHandlerContext ctx;
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
this.ctx = ctx;
}
public void send(String msg) {
ctx.write(msg);
}
}
如果ChannelHandler实例带有@Sharable注解则可以被添加到多个ChannelPipeline中,也就是说单个ChannelHandler可以有多个ChannelHandlerContext;如果没有添加该注解的Handler实例添加到多个Pipeline中则会抛异常:
@Sharable
public class NotSharableHandler extends ChannelInboundHandlerAdapter { private int count; @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
count++;
System.out.println("channelRead(...) called the " + count + " time");
ctx.fireChannelRead(msg);
}
}
ChannelHandler及其子类
ChannelHandlerAdapter
ChannelInboundHandler / ChannelInboundHandlerAdapter 处理完消息之后不会自动释放,需要ReferenceCountUtil.release(msg);
ChannelOutboundHandler / ChannelOutboundHandlerAdapter
SimpleChannelInboundHandler<T> / SimpleChannelInboundHandler<T> 处理完消息之后自动释放
ChannelOutboundHandler所有重要方法采用ChannelPromise,如果ChannelPromise没有被通知,可能会导致其中一个ChannelFutureListener没有被通知去处理一个消息:
public class DiscardOutboundHandler extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
ReferenceCountUtil.release(msg);
promise.setSuccess();
}
}
总结一下:一般自定义消息,使用编码解码器实现字节传输,使用ChannelInboundHandlerAdapter/ChannelOutboundHandlerAdapter处理事件或者状态改变,使用SimpleChannelInboundHandler/SimpleChannelOutboundHandler处理消息。
Netty入门(3) - ChannelHandler的更多相关文章
- Netty入门
一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...
- netty入门(一)
1. netty入门(一) 1.1. 传统socket编程 在任何时候都可能有大量的线程处于休眠状态,只是等待输入或者输出数据就绪,这可能算是一种资源浪费. 需要为每个线程的调用栈都分配内存,其默认值 ...
- Netty入门教程——认识Netty
什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...
- Netty 系列(三)Netty 入门
Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...
- Netty入门二:开发第一个Netty应用程序
Netty入门二:开发第一个Netty应用程序 时间 2014-05-07 18:25:43 CSDN博客 原文 http://blog.csdn.net/suifeng3051/article/ ...
- 1.Netty入门
Netty入门 1.Netty介绍 (1)百度百科介绍: Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络 ...
- Java网络编程 -- Netty入门
Netty简介 Netty是一个高性能,高可扩展性的异步事件驱动的网络应用程序框架,它极大的简化了TCP和UDP客户端和服务器端网络开发.它是一个NIO框架,对Java NIO进行了良好的封装.作为一 ...
- Netty Pipeline与ChannelHandler那些事
Pipeline和ChannelHandler是Netty处理流程的重要组成部分,ChannelHandler对应一个个业务处理器,Pipeline则是负责将各个ChannelHandler串起来的& ...
- Netty入门与实战教程总结分享
前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...
随机推荐
- SQL 事务 begin tran、commit tran、rollback tran 的用法
首先理解一下这三个事务的大概意思: begin Transaction 可以理解成新建一个还原点. commit Transaction 提交这个自begin tran开始的修改 rollback T ...
- BZOJ1002 [FJOI2007] 轮状病毒 【递推】
题目分析: 推基尔霍夫矩阵后可以发现递推式 代码: n = input() f0 = 1 f1 = 5 f3 = 0 if n == 1: print f0 elif n == 2: print f1 ...
- HS BDC HDU - 3472(混合欧拉路径)
题意: 就是混合欧拉路径板题 解析: 欧拉路径加一条t_ ---> s_ 的边就变成了欧拉回路,所以利用这一点,如果存在两个奇点,那么这两个奇点出度大的是s_,入度大的是t_,加一条t_ -- ...
- bzoj 2202 [HNOI2010] Bounce 弹飞绵羊(分块)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 思路:和之前那道树分块的题很像,只不过那道是在树上,这道简单些在序列上 还是维护两个数 ...
- JavaScript 隐式类型转换
JavaScript 隐式类型转换 原文:https://blog.csdn.net/itcast_cn/article/details/82887895 · 1.1 隐式转换介绍 · 1.2 隐式转 ...
- 【BZOJ1879】[SDOI2009]Bill的挑战(动态规划)
[BZOJ1879][SDOI2009]Bill的挑战(动态规划) 题面 BZOJ 洛谷 题解 本来还想着容斥来着,这个数据范围直接暴力就好.设\(f[i][S]\)表示当前填到了第\(i\)位,和\ ...
- [USACO 2018 December Contest]作业总结
t1 Convention 题目大意 每一头牛都有一个来的时间,一共有\(n\)辆车,求出等待时间最长的那头牛等待的最小时间. 解法 第一眼看到这道题还以为是\(2018noip\)普及组的t3魔鬼题 ...
- BZOJ2150 部落战争 【带上下界最小流】
题目链接 BZOJ2150 题解 复习: 带上下界网络流两种写法: 不建\(T->S\)的\(INF\)的边,即不考虑源汇点,先求出此时超级源汇的最大流,即无源汇下最大的自我调整,再加入该边,求 ...
- service的生命周期
Managing the Lifecycle of a Service service的生命周期,从它被创建开始,到它被销毁为止,可以有两条不同的路径: A started service 被开启的s ...
- ioi2018集训队自选题:最短路练习题
题意:链接 定义pos[i]表示i这个值在数组里的下标. 我们先用单调栈找到每个元素左边和右边第一个比它大的元素$l_i$和$r_i$,然后建一棵二叉树,我们就叫做maxtree吧 (upd:mdzz ...