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

网状管道中的多通道边界HandlerAdapter's

冀俊良
2023-03-14

我对netty很陌生,我想创建一个TCP服务器,当连接被实例化时,它会进行自定义应用层握手。握手后,我想将消息(ByteBuf)传递给队列,以便它们可以由其他线程处理。

我的问题是,通道管道中是否可以有多个ChannelInboundHandlerAdapter?一个用于应用层握手协议,另一个用于将消息传递到队列。此外,我想知道消息是如何通过管道的。如果一个处理程序(或解码器/编码器)接收到消息,则如何将其传递给另一个处理程序。

具体来说,如果我从这里更改EchoServer并添加另一个ChannelInboundHandlerAdapter,EchoServer处理程序将停止接收任何消息。

ServerBootstrap b = new ServerBootstrap();
            b.group(group)
             .channel(NioServerSocketChannel.class)
             .localAddress(new InetSocketAddress(port))
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) 
                     throws Exception {
                 ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                     @Override
                     public void channelRead(ChannelHandlerContext ctx,
                          Object msg) {
                           }
                          });

                  ch.pipeline().addLast(
                       new EchoServerHandler());
                 }
                 });

我的逻辑是:让2个ChannelInboundHandlerAdapter与第一个处理程序进行握手,如果数据包不符合握手条件,则丢弃数据包,然后通过第二个ChannelInboundHandlerAdapter将消息传递到队列。我的逻辑正确吗?如果不是,应该是什么?

非常感谢你。

共有2个答案

澹台浩广
2023-03-14

我必须提醒大家:

只能将一个SimpleChannelInboundHandler扩展添加到管道链。因为SimpleChannelInboundHandler有一个finally代码块,所以将释放所有消息。

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    boolean release = true;
    try {
        if (acceptInboundMessage(msg)) {
            @SuppressWarnings("unchecked")
            I imsg = (I) msg;
            channelRead0(ctx, imsg);
        } else {
            release = false;
            ctx.fireChannelRead(msg);
        }
    } finally {
        if (autoRelease && release) {
            //release all handled messages,so the next handler won't be executed
            ReferenceCountUtil.release(msg);**
        }
    }
}

改用ChannelInboundHandlerAdapter:

public class CustomizeChannelInboundHandler extends ChannelInboundHandlerAdapter {
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    System.out.println("do something you like!")

    super.channelRead(ctx, msg);
  }

}

周超英
2023-03-14

ChannelInboundHandlerAdapterChannelInBoundHandler接口的适配器类。首先,您可以使用SimpleChannelInboundHandler(或者更复杂的是,您可以扩展适配器类,编写自己的处理程序来扩展channelinboundhandleadapter)。SimpleCHannelInboundHandlerchannelRead()之后自动释放消息(从而将消息传递给ChannelPipeline中的下一个处理程序)。

要使用更简单的SimpleChannelInboundHandler请参阅此线程Netty hello world示例不工作

因此,不要使用这个ch.pipeline()。addLast(新ChannelInboundHandlerAdapter(){}

您必须编写一个新类来扩展SimpleChannelInboundHandlerlike

public class MyHandler extends SimpleChannelInboundHandler{


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {


        try {
            System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII));
        } finally {
            in.release();
        }


    }
}

然后像这样调用它

public void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new MyHandler());
                    }

如上所述,在channelRead()之后,SimpleCHannelInundHandler会自动释放消息(从而将其传递给ChannelPipeline中的下一个处理程序)。

如果使用ChannelInboundHandlerAdapter,则必须自己将消息/事件传递给下一个处理程序

处理程序必须调用ChannelHandlerContext ctx中的事件传播方法,以将事件转发给下一个处理程序。(在SimpleChannelInboundHandler类中,这一点尚未实现)

 public class MyInboundHandler extends ChannelInboundHandlerAdapter {
   @Override
   public void channelActive(ChannelHandlerContext ctx) {
       System.out.println("Connected!");
       ctx.fireChannelActive();
    }
 }

看到这个了吗http://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html

 类似资料:
  • 无状态管道是纯粹的功能,通过输入数据流动而不记住任何东西或引起可检测的副作用。 大多数管道是无状态的。 我们使用的CurrencyPipe和我们创建的长度管是无状态管的示例。 状态管道是能够管理它们转换的数据的状态的管道。 创建HTTP请求,存储响应并显示输出的管道是有状态的管道。 有状态管道应谨慎使用。 Angular 2提供 ,这是有状态的。 View Example 实现有状态管道 // n

  • 我正在使用netty 4.0。25编写netty HTTP服务器的最终步骤。我需要根据HTTP GET请求中的一些参数在管道中添加各种处理程序。 如果多个请求来自同一连接,则使用相同的管道。Request1可能需要Handler1,Request2可能需要Handler2,Request3可能需要Handler3。假设请求以Request1、Request2、Request3的形式出现。Reque

  • 我使用的HLF版本是2.2 我建立了自己的网络,由3个组织、1个订购者和2个通道组成。网络已经建立,我可以用200个调用链码函数来响应。到目前为止,一切顺利。问题是我没有在CouchDB中看到世界状态。我认为这是由于链码没有正确实例化或根本没有实例化 当我打电话时: 它不会返回任何东西。但是如果我试图在第一次调用时设置标志。 答案是: 当我尝试通过以下方式实例化Chaincode时: 我得到的回应

  • 现在多分支管道作业类型已经成熟,还有什么理由再使用简单的管道作业类型吗?即使您现在只有一个分支,考虑到未来多个分支的可能性可能是明智的,那么假设您将Jenkins管道存储在SCM中,那么为您的Jenkins管道使用管道作业类型与始终使用多分支管道作业类型的动机是什么?现在这两种作业类型之间是否存在功能平价?

  • 前面两节里我们用到的输入和输出都是二维数组,但真实数据的维度经常更高。例如,彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。假设彩色图像的高和宽分别是$h$和$w$(像素),那么它可以表示为一个$3\times h\times w$的多维数组。我们将大小为3的这一维称为通道(channel)维。本节我们将介绍含多个输入通道或多个输出通道的卷积核。 多输入通道 当输入数据含多个通道时

  • 然而,我不明白如何扩展这个模型来处理多个通道。每个特征图是否需要三个独立的权重集,并在每种颜色之间共享? 参考本教程的“共享权重”部分:http://deeplearning.net/tutorial/lenet.html特征图中的每个神经元都引用层m-1,颜色是从单独的神经元引用的。我不明白他们在这里表达的关系。神经元是核还是像素?为什么它们引用图像的不同部分? 根据我的例子,一个神经元内核似乎