Netty 学习笔记(3) ------ ChannelPipeline 和 ChannelHandler
ChannelPipeline通过责任链设计模式组织逻辑代码(ChannelHandler),ChannelHander就如同Servlet的Filter一样一层层处理Channel的读写数据。
ChannelPipeline和ChannelHander的构成
Channel
Netty框架中,一个连接对应一个ChannelChannelPipeline
一个Channel绑定一条ChannelPipeline,ChannelPipeline以双向链表的结构组织所属Channel的所有逻辑处理器ChannelHandlerChannelHandler
逻辑处理器,ChannelHandler分为ChannelInboundHandler
入站处理器(处理读请求)和ChannelOutboundHandler
出站处理器(处理写请求)。一个ChannelHander可以添加到多条ChannelPipeline上。ChannelHanderContext
ChannelHandler添加到一条ChannelPipeline后,该Channelpipeline将创建一个ChannelHandlerContext与ChannelHandler绑定。ChannelHandlerContext能够拿到Channel相关的上下文信息。
ChannelInboundHandler 和 ChannelOutboundHandler
ChannelInboundHandler
入站处理器,主要处理读请求的逻辑,它将按照它被添加的顺序处理数据。ChannelOutboundHandler
出站处理器,主要处理写请求的逻辑,它将按照被添加的反顺序处理数据。ChannelInboundHandlerAdapter
和ChannelOutboundHandlerAdapter
实现了两大接口的所有功能,默认将事件提交给下一个处理器。
代码例子
入站处理器inboundHandler打印接受数据然后提交给下一个处理器,而出站处理器outboundHander打印写出数据然后提交给下一个处理器,writerHander在有客户端连接成功时写出helloClinet。
public class HanderServerDemo {
public static void main(String[] args) {
HanderServerDemo server = new HanderServerDemo();
server.init();
}
public void init(){
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.localAddress(8000)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// inBound,处理读数据的逻辑链
socketChannel.pipeline().addLast(new InBoundHandlerA());
socketChannel.pipeline().addLast(new InBoundHandlerB());
socketChannel.pipeline().addLast(new InBoundHandlerC());
//channel连接成功,返回hello client
socketChannel.pipeline().addLast(new WriteHandler());
// outBound,处理写数据的逻辑链
socketChannel.pipeline().addLast(new OutBoundHandlerA());
socketChannel.pipeline().addLast(new OutBoundHandlerB());
socketChannel.pipeline().addLast(new OutBoundHandlerC());
}
});
serverBootstrap.bind().addListener((future)->{
if(future.isSuccess()){
System.out.println("端口绑定成功");
}else{
System.out.println("端口绑定失败:"+future.cause());
}
});
}
public class InBoundHandlerA extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("InBoundHandlerA: " + msg);
super.channelRead(ctx, msg);
}
}
public class InBoundHandlerB extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("InBoundHandlerB: " + msg);
super.channelRead(ctx, msg);
}
}
public class InBoundHandlerC extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("InBoundHandlerC: " + msg);
super.channelRead(ctx, msg);
}
}
public class WriteHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.channel().writeAndFlush(Unpooled.copiedBuffer("hello client".getBytes()));
}
}
public class OutBoundHandlerA extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("OutBoundHandlerA: " + msg);
super.write(ctx, msg, promise);
}
}
public class OutBoundHandlerB extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("OutBoundHandlerB: " + msg);
super.write(ctx, msg, promise);
}
}
public class OutBoundHandlerC extends ChannelOutboundHandlerAdapter {
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("OutBoundHandlerC: " + msg);
super.write(ctx, msg, promise);
}
}
}
可以看读请求的数据时顺handler添加的顺序处理的,A-->B-->C
而写请求的处理是逆着添加顺序的,C-->B-->A
参考资料
netty in action
Netty 入门与实战:仿写微信 IM 即时通讯系统
Netty 学习笔记(3) ------ ChannelPipeline 和 ChannelHandler的更多相关文章
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- Netty学习笔记-入门版
目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...
- Netty 学习(四):ChannelHandler 的事件传播和生命周期
Netty 学习(四):ChannelHandler 的事件传播和生命周期 作者: Grey 原文地址: 博客园:Netty 学习(四):ChannelHandler 的事件传播和生命周期 CSDN: ...
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
- 自顶向下深入分析Netty(七)--ChannelPipeline和ChannelHandler总述
自顶向下深入分析Netty(七)--ChannelPipeline和ChannelHandler总述 自顶向下深入分析Netty(七)--ChannelPipeline源码实现 自顶向下深入分析Net ...
- Netty学习笔记(番外篇) - ChannelHandler、ChannelPipeline和ChannelHandlerContext的联系
这一篇是 ChannelHandler 和 ChannelPipeline 的番外篇,主要从源码的角度来学习 ChannelHandler.ChannelHandler 和 ChannelPipeli ...
- Netty学习笔记(二) - ChannelPipeline和ChannelHandler
ChannelPipeline 和 ChannelHandler 是 Netty 重要的组件之一,通过这篇文章,重点了解这些组件是如何驱动数据流动和处理的. 一.ChannelHandler 在上一篇 ...
- Netty学习笔记(二)——netty组件及其用法
1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...
- Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例
在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...
随机推荐
- Day10-微信小程序实战-交友小程序-实现删除好友信息与子父组件间通信
回顾:上一次已经把消息的布局以及样式做好了 效果图: 在removeList.js文件中,messageId就是发起这个消息的用户了 先查看一下自定义组件的生命周期 https://developer ...
- Centos7解压Zip文件
一.安装支持ZIP的工具 yum install -y unzip zip 二.解压zip文件 unzip 文件名.zip 三.压缩一个zip文件 zip 文件名.zip 文件夹名称或文件名称
- 消息总线(Bus)
Spring Cloud Bus将分布式系统的节点与轻量级消息代理链接.可以用于通知状态更改(例如配置更改)或其他管理指令.一个关键的地方是,Bus就像一个分布式执行器,用于扩展的Spring Boo ...
- Linux distributions 发布网站
Red Hat: http://www.redhat.com SuSE: https://www.suse.com Fedora: https://getfedora.org/ CentOS: htt ...
- NXP S32V eiq_auto tensorflow offline tool 环境配置
NXP S32V eiq_auto tensorflow offline tool 环境配置 完成cnn模型eiq移植的第一步 1.安装conda 下载.sh bash Anaconda3-5.3.1 ...
- sass安装与教程
首先下载ruby http://dlsw.baidu.com/sw-search-sp/soft/ff/22711/rubyinstaller_V2.2.2.95_setup.1439890355.e ...
- CF819B Mister B and PR Shifts 题解
题目 Some time ago Mister B detected a strange signal from the space, which he started to study. After ...
- 树的深度———树形DP
题目描述 输入 输出 样例 样例输入 样例输出 7 分析 这道题数据有1000000,把每一个顶点都枚举一次显然不现实,肯定会T掉 所以,我们还是从图中找规律 按照习惯,我们先把1号节点作为根节点模拟 ...
- Vue中computed的本质及与methods的区别
一.computed的本质? computed为什么不像methods一样加小括号使用? 正常使用computed方式 运行结果 至于为什么computed为什么不像methods一样使用小括号调用, ...
- sql-exists、not exists的用法
exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:select name from student where sex = 'm' and mark exists(select 1 ...