本小节一起学习一下ChannelHandler,ChannelHandlerContext,ChannelPipeline这三个Netty常用的组件,不探究它们的底层源码,我们就简单的分析一下用法

首先先分析一下ChannelHandler,ChannelHandler是我们日常开发中使用最多的组件了,大概我们平时写的最多的组件就是Handler了,继承图如下

我们平时继承的最多的就是ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter,这两个不是接口也不是抽象类,所以我们可以仅仅重写我们需要的方法,没有必须要实现的方法,当然我们也会使用SimpleChannelInboundHandler,这个类我们上个小节也稍微讲了它的优缺点,这里不赘述

ChannelHandler,ChannelHandlerContext,ChannelPipeline这三者的关系很特别,相辅相成,一个ChannelPipeline中可以有多个ChannelHandler实例,而每一个ChannelHandler实例与ChannelPipeline之间的桥梁就是ChannelHandlerContext实例,如图所示:

看图就知道,ChannelHandlerContext的重要性了,如果你获取到了ChannelHandlerContext的实例的话,你可以获取到你想要的一切,你可以根据ChannelHandlerContext执行ChannelHandler中的方法,我们举个例子来说,我们可以看下ChannelHandlerContext部分API:

这几个API都是使用比较频繁的,都是调用当前handler之后同一类型的channel中的某个方法,这里的同一类型指的是同一个方向,比如inbound调用inbound,outbound调用outbound类型的channel,一般来说,都是一个channel的ChannnelActive方法中调用fireChannelActive来触发调用下一个handler中的ChannelActive方法

我们举例来说,我们修改Helloworld版中的部分代码,在客户端中的channel中修改一下代码

首先我们修改一下bootstrap的启动类代码:

  1. try {
  2. Bootstrap b = new Bootstrap();
  3. b.group(group)
  4. .channel(NioSocketChannel.class)
  5. .option(ChannelOption.TCP_NODELAY, true)
  6. .handler(new ChannelInitializer<SocketChannel>() {
  7. @Override
  8. public void initChannel(SocketChannel ch) throws Exception {
  9. ChannelPipeline p = ch.pipeline();
  10. p.addLast("decoder", new StringDecoder());
  11. p.addLast("encoder", new StringEncoder());
  12. p.addLast(new BaseClient1Handler());
  13. p.addLast(new BaseClient2Handler());
  14. }
  15. });
  16. ChannelFuture future = b.connect(HOST, PORT).sync();
  17. future.channel().writeAndFlush("Hello Netty Server ,I am a common client");
  18. future.channel().closeFuture().sync();
  19. } finally {
  20. group.shutdownGracefully();
  21. }

我们在channelhandler链中加了两个自定义的BaseClient1Handler和BaseClient2Handler的处理器

BaseClient1Handler的方法也很简单:

BaseClient1Handler.java

  1. package com.lyncc.netty.component.channelhandler;
  2. import io.netty.channel.ChannelHandlerContext;
  3. import io.netty.channel.ChannelInboundHandlerAdapter;
  4. /**
  5. *
  6. * @author bazingaLyncc
  7. * 描述:客户端的第一个自定义的inbound处理器
  8. * 时间  2016年5月3日
  9. */
  10. public class BaseClient1Handler extends ChannelInboundHandlerAdapter{
  11. @Override
  12. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  13. System.out.println("BaseClient1Handler channelActive");
  14. //        ctx.fireChannelActive();
  15. }
  16. @Override
  17. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  18. System.out.println("BaseClient1Handler channelInactive");
  19. }
  20. }

BaseClient2Handler.java

  1. package com.lyncc.netty.component.channelhandler;
  2. import io.netty.channel.ChannelHandlerContext;
  3. import io.netty.channel.ChannelInboundHandlerAdapter;
  4. /**
  5. *
  6. * @author bazingaLyncc
  7. * 描述:客户端的第二个自定义的inbound处理器
  8. * 时间  2016年5月3日
  9. */
  10. public class BaseClient2Handler extends ChannelInboundHandlerAdapter{
  11. @Override
  12. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  13. System.out.println("BaseClient2Handler Active");
  14. }
  15. }

其他的代码不修改的,我们先启动服务器端,然后启动客户端,你会发现控制台打印了:

不会打印BaseClient2Handler类中channelActive方法中的输出语句,如果你想要打印,你可以将BaseClient1Handler中的channelActive的ctx.fireChannelActive()注释去掉。重新运行:

也就是说如果一个channelPipeline中有多个channelHandler时,且这些channelHandler中有同样的方法时,例如这里的channelActive方法,只会调用处在第一个的channelHandler中的channelActive方法,如果你想要调用后续的channelHandler的同名的方法就需要调用以“fire”为开头的方法了,这样做很灵活

目前来说这样做的好处:

1)每一个handler只需要关注自己要处理的方法,如果你不关注channelActive方法时,你自定义的channelhandler就不需要重写channelActive方法

2)异常处理,如果 exceptionCaught方法每个handler都重写了,只需有一个类捕捉到然后做处理就可以了,不需要每个handler都处理一遍

3)灵活性。例如如下图所示:

如图所示在业务逻辑处理中,也许左侧第一个ChannelHandler根本不需要管理某个业务逻辑,但是从第二个ChannelHandler就需要关注处理某个业务需求了,那么就可以很灵活地从第二个ChannelHandler开始处理业务,不需要从channel中的第一个ChannelHandler开始处理,这样会使代码显得让人看不懂~

初步看懂的ChannelHandler,ChannelHandlerContext,ChannelPipeline之间的关系就是如上总结的

Netty的ChannelHandler,ChannelHandlerContext,ChannelPipeline的更多相关文章

  1. ChannelHandler,ChannelHandlerContext,ChannelPipeline

    本小节一起学习一下ChannelHandler,ChannelHandlerContext,ChannelPipeline这三个Netty常用的组件,不探究它们的底层源码,我们就简单的分析一下用法 首 ...

  2. 【Netty】ChannelHandler和ChannelPipeline

    一.前言 前面学习了Netty的ByteBuf,接着学习ChannelHandler和ChannelPipeline. 二.ChannelHandler和ChannelPipeline 2.1 Cha ...

  3. Netty学习笔记(番外篇) - ChannelHandler、ChannelPipeline和ChannelHandlerContext的联系

    这一篇是 ChannelHandler 和 ChannelPipeline 的番外篇,主要从源码的角度来学习 ChannelHandler.ChannelHandler 和 ChannelPipeli ...

  4. Netty实战六之ChannelHandler和ChannelPipeline

    1.Channel的生命周期 Interface Channel定义了一组和ChannelInboundHandler API密切相关的简单但功能强大的状态模型,以下列出Channel的4个状态. C ...

  5. Netty 系列四(ChannelHandler 和 ChannelPipeline).

    一.概念 先来整体的介绍一下这篇博文要介绍的几个概念(Channel.ChannelHandler.ChannelPipeline.ChannelHandlerContext.ChannelPromi ...

  6. netty中的ChannelHandler和ChannelPipeline

    netty中的ChannelHandler和ChannelPipeline ChannelHandler 家族 https://www.w3cschool.cn/essential_netty_in_ ...

  7. 自顶向下深入分析Netty(七)--ChannelPipeline和ChannelHandler总述

    自顶向下深入分析Netty(七)--ChannelPipeline和ChannelHandler总述 自顶向下深入分析Netty(七)--ChannelPipeline源码实现 自顶向下深入分析Net ...

  8. Netty 框架学习 —— ChannelHandler 与 ChannelPipeline

    ChannelHandler 1. Channel 生命周期 Channel 的生命周期状态如下: 状态 描述 ChannelUnregistered Channel 已经被创建,但还未注册到 Eve ...

  9. Netty学习摘记 —— 再谈ChannelHandler和ChannelPipeline

    本文参考 本篇文章是对<Netty In Action>一书第六章"ChannelHandler和ChannelPipeline",主要内容为ChannelHandle ...

随机推荐

  1. Mac安装最新tensorflow遇到的坑,记录下方便后人

    之前其他mac电脑安装tensorflow时候一切顺利,一行命令sudo pip install tensorflow就高搞定了,但是今天在新mac上安装tensorflow时候出现了一个bug,搞了 ...

  2. getPropertyValue (实现 js框架中 css 的最终调用的函数)

    ,取得元素最终计算出的css 样式 var a = document.getElementById("content");    alert("style "+ ...

  3. BZOJ3687 简单题 【bitset】

    BZOJ3687 简单题 Description 小呆开始研究集合论了,他提出了关于一个数集四个问题: 1.子集的异或和的算术和. 2.子集的异或和的异或和. 3.子集的算术和的算术和. 4.子集的算 ...

  4. 接口结构+一个selenium例子

    大家今天可以先建一个项目目录,明天我们在码代码: 我看好多朋友都在看selenium方面的东西,在这里给大家一个和讯网自动发文章的selenium代码,有兴趣的朋友可以试试,船长已亲测可用,不明白的地 ...

  5. BZOJ1556 墓地秘密

    题意 费尽周折,终于将众将士的残骸运送到了KD军事基地地底层的大型墓地入口.KD的伙伴和战友们都参加了这次重大的送葬仪式.右边是一扇敞开的大门,进去便是墓地了,左边是一堵凹进去的墙,没有什么特别的地方 ...

  6. [MEF] 学习之一 入门级的简单Demo(转)

    MEF 的精髓在于插件式开发,方便扩展. 我学东西,习惯性的先搞的最简单的Demo出来,看看有没有好玩的东东,然后继续深入.这个博文,不谈大道理,看demo说事儿. 至于概念,请google ,大把大 ...

  7. ballerina 学习六 xml && json

    ballerina xml && json 参考使用 代码比较简单,使用起来还是比较方便的 xml 代码说明: import ballerina/io; function main ( ...

  8. ArangoDB Foxx service 使用

    备注:   项目使用的是github https://github.com/arangodb-foxx/demo-hello-foxx 1. git clone git clone https://g ...

  9. Cocos2d-x第一次调试出现的问题

    1.无法打开包括文件:“CCStdC.h“ http://blog.csdn.net/jbboy/article/details/9773087 2.无法打开文件“libcocos2d.lib” 用v ...

  10. 系列文章--ASP.NET之AJAX入门教程

    ASP.NET AJAX入门系列将会写关于ASP.NET AJAX一些控件的使用方法以及基础知识,其中部分文章为原创,也有一些文章是直接翻译自官方文档,本部分内容会不断更新. 目录 ASP.NET A ...