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实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...
随机推荐
- Mybatis学习笔记(1)
CRUD操作 1.从实体类参数中取值 #{属性名} select * from user where username = #{username} 2.当sql语句只有一个参数且参数类型是基本类型或基 ...
- JavaWEB实现qq邮箱发送验证码——qq1692700664
// 随机验证码public String achieveCode() { String[] beforeShuffle = new String[] { "2", "3 ...
- ceph SSD HDD分离与openstack调用
本例子ceph L版本采用的是filestore,而不是bluestore. 一.查看class类型,只有一个hdd,.Luminous 为每个OSD添加了一个新的属性:设备类.默认情况下,OSD将根 ...
- CListCtrl 控件即使跟新数据,即时刷新以及属性设置
用 m_CtrItem.Update( i );来即使跟新每行的数据,因为有时用某些函数如SetItemText()来设置某一行一列的数据是,控件上面的显示数据没有即使跟新,这是就有update来跟新 ...
- 查看Oracle当前用户下的(表视图,同义词...)
查看Oracle当前用户下的信息(用户,表视图,索引,表空间,同义词,存储过程函数,约束条件) 0.表空间 SQL>select username,default_tablespace from ...
- 华为云—环境安装(jdk安装,tomcat安装)
前言 在前面咱们讲到华为云的购买以及一些配置,通过上一文即可获得一个可以直接访问使用的云服务器.但是对于不同的人群服务器的使用用途可能不同,对于咱们大部分的java程序员来说,jdk.tomcat.m ...
- 禁用rm命令
(1)[root@tf ~]# alias rm='echo do not use rm command'[root@tf ~]# vim /etc/profile alias rm='echo ...
- SharePoint删除图片库文件
SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite site = new SPSite(SPContext.Current. ...
- java语言基础(九)_final_权限_内部类
final关键字 final关键字代表最终.不可改变的. 常见四种用法: 可以用来修饰一个类 可以用来修饰一个方法 还可以用来修饰一个局部变量 还可以用来修饰一个成员变量 1)修饰一个类 public ...
- Web开发HTTP协议知识_常用http方法、http状态码等(前端开发和面试必备))
http请求由三部分组成,分别是:请求行.消息报头.请求正文. HTTP(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连 ...