Java 未调用Netty Handler

Java 未调用Netty Handler,java,client-server,netty,Java,Client Server,Netty,我试图使用一个简单的服务器客户端应用程序(代码见下文)进入Netty 我正在努力解决两个问题: ConfigServerHandler响应。已正确调用ConfigClientHandler。但是反馈服务器处理程序响应。从未调用反馈ClientHandler。为什么?根据文档,应该一个接一个地调用处理程序 我想要几位经理。这些处理程序中的每一个只对由另一方发送的一些消息感兴趣(例如,由客户端发送,由服务器接收) 在处理程序(channelRead)接收到消息后,我是否应该过滤这些消息?如何区分不

我试图使用一个简单的服务器客户端应用程序(代码见下文)进入Netty

我正在努力解决两个问题:

  • ConfigServerHandler响应。已正确调用ConfigClientHandler。但是反馈服务器处理程序响应。从未调用反馈ClientHandler。为什么?根据文档,应该一个接一个地调用处理程序

  • 我想要几位经理。这些处理程序中的每一个只对由另一方发送的一些消息感兴趣(例如,由客户端发送,由服务器接收)

    • 在处理程序(channelRead)接收到消息后,我是否应该过滤这些消息?如何区分不同的字符串?对于不同的对象,通过解析它们应该很容易
    • 是否可以为承插通道定义不同的通道管道
    • 进一步的办法
  • 谢谢你的帮助

    千焦

    以下是创建服务器的方式:

    public void run() throws Exception {
    
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     p.addLast(
                         new ObjectEncoder(),
                         new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
                         new ConfigServerHandler(),
                         new FeedbackServerHandler());
                 }
             });
          b.bind(mPort).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
    客户端看起来非常相似:

    public Client(String host, int port) throws InterruptedException {
    
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup)
             .channel(NioSocketChannel.class)
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                      p.addLast(
                          new ObjectEncoder(),
                          new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
                          new ConfigClientHandler(),
                          new FeedbackClientHandler());
                 }
             });
             b.connect(host, port).sync().channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
    

    }

    您正在使用
    ChannelInboundHandlerAdapter
    ,这对于您的“中间”处理程序
    ConfigXxxxxHandler
    来说很好

    但是您可以使用
    channelRead
    方法,然后使用inside
    ctx.write(msg)
    ctx.write(msg)
    将首先通过前一个处理程序(
    ObjectDecoder
    )将msg写回另一个服务器,而不是下一个处理程序(
    FeedbackClientHandler

    如果要将消息发送到下一个处理程序,应使用以下命令:

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("ConfigClientHandler::channelRead, " +(String)msg);
        ctx.fireChannelRead(msg);
    }
    
    当然,
    channelReadComplete
    中没有
    ctx.flush()。
    但是在最后的
    FeedbackClientHandler
    中,当然可以使用
    ctx.write(yourNewMessage)
    的flush方法,或者使用
    ctx.writeAndFlush(yourNewMessage)

    因此,请继续:

    • ctx.write
      会将消息发送到有线电视,因此会将消息发送到上一个处理程序的频道,然后再发送到网络,因此出站方式
    • ctx.fireChannelRead
      将消息发送到下一个处理程序(相反的方式),因此入站方式
    有关详细信息,请参阅

    您可能还应该反转编码器/解码器,因为通常最好先让解码器,然后让编码器在管道中

                p.addLast(
                          new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
                          new ObjectEncoder(),
                          new ConfigClientHandler(),
                          new FeedbackClientHandler());
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("ConfigClientHandler::channelRead, " +(String)msg);
        ctx.fireChannelRead(msg);
    }
    
                p.addLast(
                          new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
                          new ObjectEncoder(),
                          new ConfigClientHandler(),
                          new FeedbackClientHandler());