Callback 回调

  一个 Callback(回调)就是一个方法,一个提供给另一个的方法的引用。

  这让另一个方法可以在适当的时候回过头来调用这个 callback 方法。Callback 在很多编程情形中被广泛使用,是用于通知相关方某个操作已经完成最常用的方法之一。Netty在处理事件时内部使用了 callback;当一个 callback被触发,事件可以被 ChannelHandler 的接口实现处理。

1 public class ConnectHandler extends ChannelInboundHandlerAdapter {
2 //当一个新的连接建立时,channelActive被调用
3 @Override
4 public void channelActive(ChannelHandlerContext ctx) throws Exception {
5 System.out.println("client:"+ ctx.channel().remoteAddress() + " connected.");
6 }
7 }

  这个 ConnectHandler 实例 (相当于被调用者)以参数的形式传入创建 Channel 连接的函数(调用者)中,之后这个函数创建新连接后,就会回来调用这个 ConnectHandler 的 channelActive 方法,这个过程就叫回调

Future 未来结果的占位符

  Netty 中通道上的每个 IO 操作都是无阻塞的。

  这意味着调用后立即返回所有操作。标准 Java 库中有一个 Future 接口,用来访问未来异步操作在某个时刻完成,并用其提供对结果的访问,但是对于 Netty 而言并不方便使用(操作繁琐),我们只能询问 Future。

  将 Future 视为保存结果的对象(它可能暂时不保存结果),但将来会保存(一旦 Callable 回调函数返回)。因此,Future 基本上是主线程可以跟踪进度以及其他线程的结果的一种方式。

  这就是 Netty 拥有自己的 ChannelFuture 接口的原因。我们可以将回调传递给 ChannelFuture,该回调将在操作完成时被调用。

  例如以下代码, ChannelFuture channelFuture = bootstrap.bind(getBindAddress()); 服务器引导类绑定端口号,返回一个 ChannelFuture。

 1     private ChannelFuture doBind(final SocketAddress localAddress) {
2 final ChannelFuture regFuture = initAndRegister();
3 final Channel channel = regFuture.channel();
4 if (regFuture.cause() != null) {
5 return regFuture;
6 }
7
8 if (regFuture.isDone()) {
9 // At this point we know that the registration was complete and successful.
10 ChannelPromise promise = channel.newPromise();
11 doBind0(regFuture, channel, localAddress, promise);
12 return promise;
13 } else {
14 // Registration future is almost always fulfilled already, but just in case it's not.
15 final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
16 regFuture.addListener(new ChannelFutureListener() {
17 @Override
18 public void operationComplete(ChannelFuture future) throws Exception {
19 Throwable cause = future.cause();
20 if (cause != null) {
21 // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an
22 // IllegalStateException once we try to access the EventLoop of the Channel.
23 promise.setFailure(cause);
24 } else {
25 // Registration was successful, so set the correct executor to use.
26 // See https://github.com/netty/netty/issues/2586
27 promise.registered();
28
29 doBind0(regFuture, channel, localAddress, promise);
30 }
31 }
32 });
33 return promise;
34 }
35 }

  在 initAndRegister() 方法初始化并注册 NioServerSocketChannel 这个操作是异步非阻塞,通过这个 Future 来访问异步操作是否完成,以防万一,没有完成会添加一个 Listener 监听结果,当异步操作完成时通过回调来执行相应操作,成功执行 doBind0(regFuture, channel, localAddress, promise); 来设置要使用的正确执行器。

参考:《Netty In Action》

Netty:Netty的介绍以及它的核心组件(二)—— ChannelFuture与回调的更多相关文章

  1. Netty:Netty的介绍以及它的核心组件(一)—— Channel

    1. Netty 介绍 Netty 是一个无阻塞的输入/输出(NIO)框架,它使开发低级网络服务器和客户端变得相对简单.Netty为需要在套接字级别上工作的开发人员提供了令人难以置信的强大功能,例如, ...

  2. Netty重要概念介绍

    Netty重要概念介绍 Bootstrap Netty应用程序通过设置bootstrap(引导)类开始,该类提供了一个用于网络成配置的容器. 一种是用于客户端的Bootstrap 一种是用于服务端的S ...

  3. netty05(netty的一些介绍)

    netty的一些理论 netty是一个异步事件驱动的网络应用框架(NIO框架),所有IO操作都是异步非阻塞的,NIO是对IO的一个补充 用于开发客户端和服务器的通信(TCP/UDP)长短连接 nett ...

  4. [Netty] - Netty IN ACTION(导言)

    最近没什么事儿做,刚好看到有需要网络编程的知识,java中有NIO和IO两种不同的方式,但是NIO的编写比较麻烦,刚好找到一个成熟的网络框架Netty.接下来的一个月就准备将Netty IN ACTI ...

  5. Netty入门之客户端与服务端通信(二)

    Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...

  6. Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话.输入的语句是如何变成搜索条件的上一篇已经略有提及. 4.3.1 观察 ...

  7. Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的 ...

  8. ArUco----一个微型现实增强库的介绍及视觉应用(二)

    ArUco----一个微型现实增强库的介绍及视觉应用(二) 一.第一个ArUco的视觉应用 首先介绍第一个视觉应用的Demo,这个应用场景比较简单,下面具体介绍: 1. 应用场景 主线程:通过摄像头检 ...

  9. Netty:Netty的介绍以及它的核心组件(三)—— 事件和ChannelHandler

    Netty 使用异步事件驱动(Asynchronous Event-Driven)的应用程序范式,因此数据处理的管道(ChannelPipeLine)是经过处理程序(ChannelHandler)的事 ...

随机推荐

  1. Centos6.5时间服务器NTP搭建

    NTP时间服务器安装与配置 第1章 Server端的安装与配置 1.1 查看系统是否已经安装ntp服务组件 rpm -qa | grep "ntp" #<==查看是否已经安装 ...

  2. Android系统编程入门系列之应用数据文件化保存

    应用中关于数据的持久化保存,不管是简单的SharedPreferences还是数据库SQLiteDatabase,本质上都是将数据保存到系统的某种类型的文件中.因此可以直接使用java.io.File ...

  3. Jenkins操作手册 - 巨详细,一篇足矣!

    一.继续集成相关概念 1.1.什么是持续集成? 随着软件开发复杂度的不断提高,团队开发成员间如何更好的协同工作以确保软件开发的质量已经成为开发过程中不可回避的问题.尤其是近年来敏捷开发在软件领域越来越 ...

  4. python的列表和java的数组有何异同

    今天面试被问到,自己学习一下. python的列表是可变长的,定义时不需要指定长度:pyhton是弱对象类型,python的列表存储的数据类型可以不相同:python的列表更加灵活,如可以通过''命令 ...

  5. 你会阅读appium官网文档吗

    高效学习appium第一步,学会查看appium官方文档.如果能把appium文档都通读一遍,对学习appium大有益处. 而能做到通读appium官方文档的人,想必不是很多,刚开始学习appium的 ...

  6. 自己写登陆验证及借用auth的is_authenticated验证是否登陆

    一. 自己写登陆需要注册,一个session的处理,还有一个session的删除 #自定义一个闭包装饰器,来验证def checkLogin(func): def wrapper(request, * ...

  7. english note(6.2 to 5.30)

    notes 6.2 to 5.30  http://www.51voa.com/VOA_Special_English/suicide-rates-among-young-americans-on-t ...

  8. c++ 的学习 第二集函数的重载之3 -利用IDA分析bebug里面

    1. 对项目右击,在文件资源管理器中打开文件夹 2.看debug里面的.exe     这个文件 函数的真实的名字 打开.exe文件就是还是显示,,, 3.debug模式有太多的断点信息还有许多不精简 ...

  9. Winform 控件命名规范

    前言 最近 Winform 项目做得比较多,控件命名规范上常用的能记住,但是有些总要查,写个记录吧.方便以后自己用,大家也可以参考. 标准控件 序号 控件类型简写 控件类型 1 btn Button ...

  10. JS返回一个字符串中长度最小的单词的长度

    题目:编写一个方法,返回字符串中最小长度的单词的长度. var str = 'What a good day today!'; 1 //方法一 2 function returnString1(str ...