当前位置: 首页 > 知识库问答 >
问题:

netty中的解码器、编码器、ServerHandler管道

耿和韵
2023-03-14

看看文档,它说:

https://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html

假设用户在管道中有一个或多个ChannelHandlers来接收I/O事件(例如读取)和请求I/O操作(例如写入和关闭)。例如,一个典型的服务器在每个通道的管道中都有以下处理程序,但是根据协议和业务逻辑的复杂性和特征,这些处理程序可能会有所不同:

协议解码器-将二进制数据(如ByteBuf)翻译成Java对象。协议编码器——将Java对象翻译成二进制数据。

业务逻辑处理程序 - 执行实际的业务逻辑(例如数据库访问)。它可以表示如下例所示:静态最终事件演示组 = 新的默认事件演示组(16);...

通道管道 = 通道管道();

pipeline.addLast("decoder ",new MyProtocolDecoder());

pipeline.addLast(“encoder”, new MyProtocolEncoder());

告诉管道在与 I/O 线程不同的线程中运行 MyBusinessLogicHandler 的事件处理程序方法 //,以便 I/O 线程不会被耗时的任务阻塞 。如果业务逻辑是完全异步的或完成速度非常快,则无需 // 指定组。

pipeline.addLast(group,"handler", new MyBusinessLogicHandler());

在Github上的很多例子中,我看到了同样的模式。我想知道是否有人可以解释为什么商业Handler不在解码器和编码器之间。我认为你会得到你的POJO,然后在业务处理程序中处理它,然后对其进行编码。

共有3个答案

柯波峻
2023-03-14

事实上,如果您在服务器中添加1.decoder、2.businessHandler和3.encoder,并编写ctx.channel()。writeAndFlush()ctx.pipeline()。writeAndFlush(),然后将调用编码器。在这种情况下是bc,它将从尾部查找前一个outboundChannel。但是,如果您编写了ctx。writeAndFlush(),它将从businessHandler的位置查找前一个outboundChannel。在AbstractChannelHandlerContext的findContextOutbound()的第一行添加一个断点,您就会得到它。

java prettyprint-override">private AbstractChannelHandlerContext findContextOutbound(int mask) {
        AbstractChannelHandlerContext ctx = this;
        EventExecutor currentExecutor = executor();
        do {
            ctx = ctx.prev;
        } while (skipContext(ctx, currentExecutor, mask, MASK_ONLY_OUTBOUND));
        return ctx;
    }
邢焕
2023-03-14

当然,业务处理程序位于解码器和编码器之间。以阶乘为例。

   public void initChannel(SocketChannel ch) {
    ChannelPipeline pipeline = ch.pipeline();
    if (sslCtx != null) {
        pipeline.addLast(sslCtx.newHandler(ch.alloc()));
    }
    // Enable stream compression (you can remove these two if unnecessary)
    pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
    pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
    // Add the number codec first,
    pipeline.addLast(new BigIntegerDecoder());
    pipeline.addLast(new NumberEncoder());
    // and then business logic.
    // Please note we create a handler for every new channel
    // because it has stateful properties.
    pipeline.addLast(new FactorialServerHandler());
}`

思想在initChannel的函数中,流水线首先添加编码器和解码器,最后添加处理程序。执行流程实际上是按解码器、处理程序和编码器排序的。解码器、处理程序和编码器等处理程序实际上存储AbstractChannelHandlerContext类中。Netty中有一个AbstractChannelHandlerContext的链表。该列表的排列方式类似于解码器上下文--

刘永望
2023-03-14

解码器和编码器通常位于管道的开头,因为调用处理程序的顺序。对于传入的数据,它是自下而上的,对于传出的数据,它是自上而下的。

例如。

pipeline.addLast(new MyEncoder());
pipeline.addLast(new MyDecoder());
pipeline.addLast(new MyBusiness());

在这种情况下,对于传入数据调用顺序为:我的解码器(将数据转换为POJO)-

如果您在业务处理程序(实际上是解码器之后的POJOs)中接收到一个传入的流,并对其进行处理和写回,看起来好像MyBusiness位于编码器和解码器之间,因为数据返回到编码器。

 类似资料:
  • 我最近开始用netty做我的一个项目。为了理解netty是如何工作的,我实现了HexDumpProxy示例。当我在通道管道中添加StringDecoder和StringEncoder时,我遇到了一个问题,这会导致管道损坏。如果解码器/编码器不存在,程序会正常工作。有人能解释一下为什么会这样吗?非常感谢任何帮助! 下面我正在添加代码。 主要类别: 初始值设定项类: 前端处理程序类: 后端处理程序类:

  • Netty 的是一个复杂和先进的框架,但它并不玄幻。当我们请求一些设置了 key 的给定值时,我们知道 Request 类的一个实例被创建来代表这个请求。但 Netty 并不知道 Request 对象是如何转成 Memcached 所期望的。Memcached 所期望的是字节序列;忽略使用的协议,数据在网络上传输永远是字节序列。 将 Request 对象转为 Memcached 所需的字节序列,N

  • 我用Netty制作了一个服务器,但我遇到了一个问题。我创建的编码器没有被执行。 我在服务器上的管道: 我的编码器: 我的解码器: 我的通道处理程序: 调用解码器,然后调用通道处理程序,但不调用编码器。我试图改变管道中的顺序,但同样的问题也试图使用fireChannelRead(...)和同样的问题。 谢谢

  • 我们已经在前两节中表征并变换了不定长的输入序列。但在自然语言处理的很多应用中,输入和输出都可以是不定长序列。以机器翻译为例,输入可以是一段不定长的英语文本序列,输出可以是一段不定长的法语文本序列,例如 英语输入:“They”、“are”、“watching”、“.” 法语输出:“Ils”、“regardent”、“.” 当输入和输出都是不定长序列时,我们可以使用编码器—解码器(encoder-de

  • 我使用apache camel Netty使用此代码将ebcdic输入转换为ascii。 任何建议或答案...

  • 我希望将传入的Netty的消息转换为我的类的实例。为此,我使用以下: 现在,由于消息是引用计数的,我们必须在处理完它之后释放它。这是由我们正在扩展的自动完成的。 现在,既然ButeBuf已经发布,这难道不意味着支持阵列处于危险之中吗?它将被回收,我不确定我会在我的MyBuffer的数组中看到什么。 这个解码器可以安全使用吗?这是正确的编写方式吗?