关于netty的多个handler链式模式
1. 老规矩, 引入我们喜闻乐见的maven依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.6.Final</version>
</dependency>
2. 服务端
2.1: 服务端引导类:
public class EchoServer {
private int port;
private EchoServer(int port) {
this.port = port;
}
private void start() throws Exception {
System.out.println("Echo Server Start");
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoOutboundHandler1());
ch.pipeline().addLast(new EchoOutboundHandler2());
ch.pipeline().addLast(new EchoInboundHandler1());
ch.pipeline().addLast(new EchoInboundHandler2());
}
});
ChannelFuture f = b.bind().sync();
System.out.println("Server Start Listen At: " + port);
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new EchoServer(port).start();
}
}
2.2 EchoOutboundHandler1
public class EchoInboundHandler1 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// 读取msg中的数据
ByteBuf result = (ByteBuf) msg;
byte[] bytes = new byte[result.readableBytes()];
result.readBytes(bytes);
String resultStr = new String(bytes);
System.out.println("Server Received: " + resultStr + ": Inbound 1 Is OK");
// 处理完msg中的数据后往msg中重新存放新的数据继续传递
result.writeBytes(resultStr.getBytes());
ctx.fireChannelRead(result);
}
}
2.3 EchoInboundHandler2
public class EchoInboundHandler2 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// 读取msg中的数据
ByteBuf result = (ByteBuf) msg;
byte[] bytes = new byte[result.readableBytes()];
result.readBytes(bytes);
String resultStr = new String(bytes);
System.out.println("Server Received: " + resultStr + ": Inbound 2 Is OK");
// 处理完msg中的数据后往msg中重新存放新的数据继续传递
result.writeBytes(resultStr.getBytes());
ctx.write(result);
}
}
2.4 EchoOutboundHandler2
public class EchoOutboundHandler2 extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
// 读取msg中的数据
ByteBuf result = (ByteBuf) msg;
byte[] bytes = new byte[result.readableBytes()];
result.readBytes(bytes);
String resultStr = new String(bytes);
System.out.println("Server Received: " + resultStr + ": Outbound 2 Is OK");
// 处理完msg中的数据后往msg中重新存放新的数据继续传递
result.writeBytes(resultStr.getBytes());
ctx.write(result);
}
}
2.5 EchoOutboundHandler1
public class EchoOutboundHandler1 extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
// 读取msg中的数据
ByteBuf result = (ByteBuf) msg;
byte[] bytes = new byte[result.readableBytes()];
result.readBytes(bytes);
String resultStr = new String(bytes);
System.out.println("Server Received: " + resultStr + ": Outbound 1 Is OK");
// 处理完msg中的数据后往msg中重新存放新的数据继续传递
result.writeBytes(resultStr.getBytes());
ctx.write(result);
ctx.flush();
}
}
3. 客户端
public class EchoClient {
private String host;
private int port;
private EchoClient(String host, int port) {
this.host = host;
this.port = port;
}
private void start() throws Exception {
System.out.println("Echo Client Start");
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f = b.connect().sync();
System.out.println("Server Client Listen IP: [" + host + ":" + port + "]");
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
String host = "127.0.0.1";
int port = 8080;
int len = 2;
if (args.length == len) {
host = args[0];
port = Integer.parseInt(args[1]);
}
new EchoClient(host, port).start();
}
}
public class EchoClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty Rocks!", CharsetUtil.UTF_8));
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// 读取msg中的数据
ByteBuf result = (ByteBuf) msg;
byte[] bytes = new byte[result.readableBytes()];
result.readBytes(bytes);
String resultStr = new String(bytes);
System.out.println("Echo Client Received Is OK: " + resultStr);
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
4. 结果:
服务端:

客户端:

5. 注意事项:
5.1. ChannelInboundHandler之间的传递, 通过调用 ctx.fireChannelRead(msg) 实现; 调用ctx.write(msg) 将传递到ChannelOutboundHandler
5.2. ctx.write()方法执行后, 需要调用flush()方法才能令它立即执行
5.3. ChannelOutboundHandler 在注册的时候需要放在最后一个ChannelInboundHandler之前, 否则将无法传递到ChannelOutboundHandler
关于netty的多个handler链式模式的更多相关文章
- JavaScript 链式结构序列化详解
一.概述 在JavaScript中,链式模式代码,太多太多,如下: if_else: if(...){ //TODO }else if(...){ //TODO }else{ //TODO } swi ...
- jQuery链式操作[转]
用过jQuery的朋友都知道他强大的链式操作,方便,简洁,易于理解,如下 $("has_children").click(function(){ $(this).addClass( ...
- javascript实现数据结构:线性表--线性链表(链式存储结构)
上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...
- 用php实现一个简单的链式操作
最近在读<php核心技术与最佳实践>这本书,书中第一章提到用__call()方法可以实现一个简单的字符串链式操作,比如,下面这个过滤字符串然后再求长度的操作,一般要这么写: strlen( ...
- C#用链式方法表达循环嵌套
情节故事得有情节,不喜欢情节的朋友可看第1版代码,然后直接跳至“三.想要链式写法” 一.起缘 故事缘于一位朋友的一道题: 朋友四人玩LOL游戏.第一局,分别选择位置:中单,上单,ADC,辅助:第二局新 ...
- 由表单验证说起,关于在C#中尝试链式编程的实践
在web开发中必不可少的会遇到表单验证的问题,为避免数据在写入到数据库时出现异常,一般比较安全的做法是前端会先做一次验证,通过后把数据提交到后端再验证一次,因为仅仅靠前端验证是不安全的,有太多的htt ...
- 如何写 JS 的链式调用 ---》JS 设计模式《----方法的链式调用
1.以$ 函数为例.通常返回一个HTML元素或一个元素集合. 代码如下: function $(){ var elements = []; ;i<arguments.length;i++){ v ...
- iOS 链式编程探索(Masonry)
看了几篇关于链式编程的文章,还是理解的不透彻,我想这可能是因为我自己对block掌握的不熟练. 我已经明白了,所以,和大家分享一下我的理解!如有问题,麻烦大家指出! 直接看代码吧!关键的注释都有. 我 ...
- jQuery插件编写及链式编程模型小结
JQuery极大的提高了我们编写JavaScript的效率,让我们可以愉快的编写代码,做出各种特效.大多数情况下,我们都是使用别人开发的JQuery插件,今天我们就来看看如何把我们常用的功能做出JQu ...
随机推荐
- vue.js基础知识总结
初始化一个项目 npm init -y 安装一些依赖 npm install 名称 --save 例如 npm install vue axios bootstrap --save --save 表示 ...
- [Usaco2007 Oct] Super Paintball超级弹珠
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 489 Solved: 384[Submit][Status][Discuss] Description ...
- Python基础教程笔记——第2章:列表和元组
python shell 里重复上一次的命令:Alt+p 2.3 列表:Python的苦力 (1)list函数 (2)列表赋值,不蹦蹦为一个元素不存在的位置赋值 (3)删除元素,del name[1] ...
- Xcode waring: no rule to process file *** 警告提示
在编译程序的时候,Xcode给出了警告:warning: no rule to process file *** 类似的警告, 解决方法: 在[build Phases] -> [Compile ...
- HDU 4609 FFT+组合数学
3-idiots Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- Fibonacci--poj3070(矩阵快速幂)
http://poj.org/problem?id=3070 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn ...
- 安装使用Spring boot 写一个hello1
一.创建springboot 项目 二.进行代编写 1.连接数据库:application.properties里配置 spring.datasource.driverClassName=com.my ...
- AE的Annotation学习摘记
http://xg-357.blog.163.com/blog/static/36263124201151763512894/ IFeatureWorkspaceAnno pFWSAnno = (IF ...
- ubuntu安装ftp环境
ubuntu安装ftp环境 安装: apt install vsftpd 启动: service vsftpd start 查看状态: service vsftpd status root登录: vi ...
- 在DIV中自己主动换行
word-break:break-all和word-wrap:break-word都是能使其容器如DIV的内容自己主动换行. 它们的差别就在于: 1,word-break:break-all 比如di ...