Netty的InboundHandler 和OutboundHandler

一、InboundHandler 和OutboundHandler的区别

在Netty中,"inbound"表示来自外部来源(如网络连接)的数据,而"outbound"则表示从应用程序发送到外部目标(如网络连接或其他服务)的数据。

"Inbound"主要涉及应用程序接收和处理外部数据的过程。这包括从网络连接读取数据、解码处理数据、执行业务逻辑等操作。例如,在一个服务器应用程序中,inbound操作可能涉及监听和接受客户端连接,读取客户端发送的请求数据,并将其转发给适当的处理程序进行处理。inbound监听的事件如下:

  • channelRegistered/channelUnregistered
  • channelActive/channelInactive
  • channelRead
  • channelReadComplete
  • channelWritabilityChanged
  • userEventTriggered
  • exceptionCaught

"Outbound"主要涉及应用程序发送数据到外部目标的过程。这包括将数据编码为网络传输的格式、通过网络连接发送数据、处理发送的数据等操作。例如,在一个客户端应用程序中,outbound操作可能涉及将请求数据编码为适当的传输协议,通过网络连接发送给服务器,并等待响应数据。outbound监听的事件如下:

  • bind
  • connect
  • disconnect
  • close
  • deregister
  • read
  • write
  • flush

Netty的Pipeline采用责任链设计模式,责任链的每个节点是ChannelHandlerContext,通过prev和next节点实现双向链表。ChannelHandlerContext对象封装了ChannelHandler对象。Pipeline的首尾节点分别是io.netty.channel.DefaultChannelPipeline.HeadContext和io.netty.channel.DefaultChannelPipeline.TailContext。

Pipeline在分发事件的时候,会根据事件类型选择合适的handler(Inbound/Outbound本身会通用掩码位注册监听的事件类型),可参考 《Netty之ChannelHandlerMask详解》

总结:

  • InboundHandler处理从网络接收的数据,负责解析和处理输入数据。
  • OutboundHandler处理向网络发送的数据,负责封装和处理输出数据。
  • InboundHandler和OutboundHandler在处理数据的方向上有所区别,但它们通常一起使用,通过ChannelPipeline连接在一起,形成一个完整的数据处理链。

二、客户端消息在handler的流向

我们通过简单的例子来说明

2.1注册一个简单的Netty服务器

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class EchoServer {private int port;public EchoServer(int port) {this.port = port;}public void start() throws Exception{EventLoopGroup boss = new NioEventLoopGroup();EventLoopGroup worker = new NioEventLoopGroup();ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(boss, worker).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();for (int i = 0; i < 3; i++) {pipeline.addLast(new InboundHandler(i + 1));}for (int i = 0; i < 3; i++) {pipeline.addLast(new OutboundHandler(i + 1));}System.out.println("handler注册顺序:");pipeline.names().forEach(x -> {System.out.println("handler:" + x);});}}).option(ChannelOption.SO_BACKLOG,100000).childOption(ChannelOption.SO_KEEPALIVE,true);bootstrap.bind(port).sync();System.out.println("服务启动,监听端口@"+port);}public static void main(String[] args)  throws Exception {new EchoServer(8001).start();}static class InboundHandler extends ChannelInboundHandlerAdapter {private int index;public InboundHandler(int index) {this.index = index;}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("InboundChannel["+index+"]接收消息");ctx.fireChannelRead(msg);if (index == 3) {ctx.channel().write("df");}}}static class OutboundHandler extends ChannelOutboundHandlerAdapter {private int index;public OutboundHandler(int index) {this.index = index;}@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {System.out.println("OutboundChannel["+index+"]发送消息");ctx.write(msg, promise);}}}

在这个例子,启动一个简单的socket服务器,并依次注册了三个inboundhandler,三个outboundhandler。启动之后,通过简单的telnet命令,往socket发送数据

2.2使用telnet发送数据

使用windows自带的telnet,输入命令:telnet localhost 8001,然后随便输入一个字符

(部分系统需要通过按“Win+R”快捷键,打开“运行”对话框,输入“optionalfeatures”后按回车键;在打开的“Windows功能”窗口中,找到并勾选“Telnet客户端”)

2.3服务端响应

从这个例子,可以看出

InboundHandler是按照Pipleline的加载顺序,顺序执行;

而OutboundHandler是按照Pipleline的加载顺序,逆序执行。

需要注意的是,由于pipeline采取的是责任链方式,在任何一个节点,如果没有把事件往下传,事件就会在本节点终止。

   public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("InboundChannel["+index+"]接收消息");ctx.fireChannelRead(msg);  //注释次代码,则事件不会往下个handler传递数据}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/505270.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv9有效改进|使用空间和通道重建卷积SCConv改进RepNCSPELAN4

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、改进点介绍 SCConv是一种即插即用的空间和通道重建卷积。 RepNCSPELAN4是YOLOv9中的特征提取模块&#xff0c;类似YOLOv5和v8中的C2f与C3模块。 …

【数据结构】B树,B+树,B*树

文章目录 一、B树1.B树的定义2.B树的插入3.B树的中序遍历 二、B树和B*树1.B树的定义2.B树的插入3.B*树的定义4.B树系列总结 三、B树与B树的应用 一、B树 1.B树的定义 1. 在内存中搜索效率高的数据结构有AVL树&#xff0c;红黑树&#xff0c;哈希表等&#xff0c;但这是在内存…

若依框架使用mars3d的环境配置,地球构建

因项目需要&#xff0c;原本使用过的cesium依赖&#xff0c;现在想使用火星科技mars3d的一些功能&#xff0c;所以需要引入mars3d依赖&#xff0c;整个过程非常的坎坷&#xff0c;以至于我都不知道到底是哪些部分是标准的。。。先把我认为对的记录一下&#xff1a; 1.vue.conf…

leetcode括号生成

题目描述 解题思路 首先看到题目&#xff0c;一开始是并没有思路的。这时候可以在纸上进行演算一下结果。当只有一对括号的时候&#xff0c;我们可以得知结果[“()”],当有两对括号的时候&#xff0c;我们可以发现&#xff0c;括号在第一个基础上&#xff0c;要么在括号内部出…

实例驱动计算机网络

文章目录 计算机网络的层次结构应用层DNSHTTP协议HTTP请求响应过程 运输层TCP协议TCP协议面向连接实现TCP的三次握手连接TCP的四次挥手断开连接 TCP协议可靠性实现TCP的流量控制TCP的拥塞控制TCP的重传机制 UDP协议 网际层IP协议&#xff08;主机与主机&#xff09;IP地址的分类…

JavaSec 基础之 JNDI 注入

文章目录 JNDI简介JNDI 支持的服务协议JNDI 注入JNDI 复现修复 JNDI 简介 JNDI(Java Naming and Directory Interface)是一个应用程序设计的 API&#xff0c;一种标准的 Java 命名系统接口。JNDI 提供统一的客户端 API&#xff0c;通过不同的访问提供者接口JNDI服务供应接口(…

three.js 叉乘判断物体在人前左,前右,后左、后右

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs"></div><div style"padding: 10px;text-align: left;">叉乘判断物体…

SpringBoot整合SpringSecurity

什么是SpringSecurity&#xff1f; Spring Security是Spring提供的一套web的应用安全性的完整解决方案。 SpringSecurity采用责任式链的设计模式&#xff0c;它的核心是一组过滤器链。 主要包括&#xff1a; 认证&#xff08;Authentication&#xff09;&#xff1a;什么是…

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II 112. 路径总和解法&#xff1a;递归 有递归就有回溯 记得return正确的返回上去 113. 路径总和 II解法 递归 如果需要搜索整棵二叉树&#xff0c;那么递归函数就不要返回值 如果要搜索其中一条符合条件的路径&#xff…

vue中将某个不太规则的json转成对象,或者将对象转成json字符串

vue中将某个不太规则的json转成对象&#xff0c;或者将对象转成json字符串 以我自己做的项目某个不规则的json为例 将json对象转成json字符串&#xff1a; JSON.stringify(jsonData); 将不规则json字符串转成对象并获取对应的属性的值&#xff1a; JSON.parse(jsonData).Name…

详细了解C++中的namespace命名空间

键盘敲烂&#xff0c;月薪过万&#xff0c;同学们&#xff0c;加油呀&#xff01; 目录 键盘敲烂&#xff0c;月薪过万&#xff0c;同学们&#xff0c;加油呀&#xff01; 一、命名空间的理解 二、&#xff1a;&#xff1a;作用域运算符 三、命名空间&#xff08;namespace&…

双周回顾#007 - 前端与后端

前端的问题不是难&#xff0c;而是它面对最终用户。只要用户的喜好和口味发生变化&#xff0c;前端就必须跟上。 这导致前端不得不快速变化&#xff0c;因为用户的口味正在越来越快地改变。 后端不需要面对最终用户&#xff0c;需要解决的都是一些经典的计算机科学问题&#…