Netty 处理程序未调用

2024-04-08

我正在尝试使用简单的服务器客户端应用程序进入 Netty(代码见下文)。

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

  1. ConfigServerHandler 分别ConfigClientHandler 被正确调用。但是 FeedbackServerHandler 分别是。 FeedbackClientHandler 永远不会被调用。为什么?根据文档,处理程序应该被依次调用。

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

    • 我应该在处理程序(channelRead)收到消息后过滤它们吗?如何区分不同的字符串?对于不同的对象,通过解析它们应该很容易。
    • 是否可以为 SocketChannel 定义不同的 ChannelPipelines?
    • 进一步的方法?

感谢您的帮助!

KJ

这是服务器的创建方式:

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();
    }
}

Handler 类之一(FeedbackServerHandler 的作用完全相同,但解析为 Integer):

public class ConfigServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("ConfigServerHandler::channelRead, " +(String)msg);
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
   }
}

客户端看起来非常相似:

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();
    }
}

这是客户端处理程序之一(另一个处理程序发送一条整数消息并在“channelRead”方法中解析为整数):

public class ConfigClientHandler extends ChannelInboundHandlerAdapter {

    private final String firstMessage = "blubber";

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("ConfigClientHandler::channelActive");
        ctx.writeAndFlush(firstMessage);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("ConfigClientHandler::channelRead, " +(String)msg);
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

}


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

但你用channelRead方法然后在里面使用ctx.write(msg). ctx.write(msg)将首先通过前一个处理程序将消息写回到另一个服务器(ObjectDecoder),而不是下一个处理程序(FeedbackClientHandler在你的情况下)。

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

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    System.out.println("ConfigClientHandler::channelRead, " +(String)msg);
    ctx.fireChannelRead(msg);
}

当然没有ctx.flush() in channelReadComplete(因为不再在那里写)。 但在你的决赛中FeedbackClientHandler,当然,使用flush方法ctx.write(yourNewMessage) or use ctx.writeAndFlush(yourNewMessage).

所以恢复:

  • ctx.write会将消息发送到线路,然后发送到前一个处理程序,发送到通道,然后发送到网络,因此Outbound way
  • ctx.fireChannelRead将把消息发送到下一个处理程序(相反的方式),所以Inbound way

See http://netty.io/wiki/new-and-noteworthy-in-4.0.html#wiki-h4-16 http://netty.io/wiki/new-and-noteworthy-in-4.0.html#wiki-h4-16了解详情。

您也许还应该反转编码器/解码器,因为一般来说,在管道中首先使用解码器,然后使用编码器是个好主意。

            p.addLast(
                      new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
                      new ObjectEncoder(),
                      new ConfigClientHandler(),
                      new FeedbackClientHandler());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Netty 处理程序未调用 的相关文章

随机推荐

  • 在日历中的特定日期之后更改背景颜色

    我有一个事件日历 我想将特定日期 SOC DATE 之后所有列的背景颜色更改为绿色 该日期之后更改为红色 我的日历如下 td class fc day fc wed fc widget content fc past td class fc
  • 如何禁用Android Studio更新通知?

    我不想更新到 2 3 他们坏了即时运行对于 4 4 4 设备 现在仅适用于 5 及更高版本 只是想隐藏通知 没问题 对于 Android Studio 你可以尝试一下 1 单击文件 gt 设置 在 Mac 上 Android Studio
  • 使用 display:none 读取 div 的滚动高度

    With a div父元素中的元素div隐藏着display none 我正在抛弃 jQuerytextarea元素到控制台 我看到scrollHeight第 0 个元素的属性是88 我尝试将此属性读取到 var 使用 element 0
  • 通过命令提示符将参数传递给 CMAKE

    我的项目有一个 makefile 我可以用它传递一个控制某些构建标志的参数 现在我想使用 CMake 做同样的事情 我创造了CMakeLists txt但我不知道如何传递参数并检查参数值CMakeLists txt 我的 Makefile
  • MongoDB 连接被对等方重置

    我研究过其他解决方案 例如 Mongodb 连接被对等方重置 https stackoverflow com questions 2961648 mongodb connection reset by peer Mongodb 自动重新连接
  • 如何将 Facebook 聊天工具添加到 Next.js?

    我尝试在 Next js 应用程序中添加 Facebook 客户聊天 但不起作用 我找不到我的代码有任何问题 如何在我的 Next js 应用程序中添加 Facebook 客户聊天 我的代码有什么错误吗 有更好的实现来解决这个问题吗 这是我
  • 如何从控制器返回 JavaScript?

    我正在处理 ASP NET Core 2 2 项目 需要从控制器返回 JavaScript 但是 我怀疑没有直接的方法 因此 我遵循this https stackoverflow com a 42698821 4753489操作系统回答并
  • 错误:未定义无法解析模块`@react-navigation/bottom-tabs`

    一直在寻找有关导航错误模块的解决方案 我尝试过重置缓存 删除 nodu modules 重新安装模块 但仍然无法正常工作 错误的完整详细信息 Unable to resolve module react navigation native
  • 使用 Interface Builder 在 nib 中设计 UICollectionView 单元格(无故事板)

    我正在尝试设计一个定制的UICollectionViewCell原型 在 Xcode 5 0 2 中 但是 Interface Builder 不允许我向我的UICollectionView在设计笔尖时 如果我使用故事板 我可以设置项目 单
  • 指向具有不同参数的成员函数的指针的容器

    我到处寻找 现代 C 设计和合作 但我找不到一种好方法来存储一组接受不同参数并对不同类进行操作的回调 我需要这个 因为我希望应用程序的每个对象都有可能将其方法之一的执行推迟到主对象Clock对象 跟踪当前时间 可以在正确的时刻调用此方法 我
  • 类型错误:names_to_saveables 必须是将字符串名称映射到张量/变量的字典

    我正在尝试使用 freeze graph py 转换 MobileNet 0 50 的重新训练版本 这是我的代码 python m tensorflow python tools freeze graph input checkpoint
  • DB 连接关闭后从 Oracle DB 读取 CLOB

    在我正在查看的 Java 类之一中 我看到以下代码 private oracle sql CLOB getCLOB oracle sql CLOB xmlDocument null CallableStatement cstmt null
  • php - 输出值到屏幕中间循环

    在长 foreach 循环期间是否可以将任何内容输出到屏幕 每当我执行一个需要很长时间的循环时 在循环完全完成之前 屏幕上不会输出任何内容 即使 echo 语句位于循环内部 有没有办法改变这种行为 您需要刷新缓冲区 如何执行取决于您的服务器
  • 如何在 CUDA 应用程序中构建数据以获得最佳速度

    我正在尝试编写一个简单的粒子系统 利用 CUDA 来更新粒子位置 现在 我定义的粒子有一个对象 该对象的位置由三个浮点值定义 速度也由三个浮点值定义 更新粒子时 我向速度的 Y 分量添加一个常量值以模拟重力 然后将速度添加到当前位置以得出新
  • 为什么删除不完整的类型实际上是未定义的行为?

    考虑这个经典的例子来解释什么not与前向声明有关 in Handle h file class Body class Handle public Handle Handle delete impl private Body impl in
  • JQUERY DOM:选择 Dom 加载后创建的元素

    我正在开发一个项目 在该项目中 我需要在调用函数时更改某个类的所有选择输入的值 问题是一些选择输入在 dom 首次加载时并不存在 它们是通过 Javascript 动态创建的 该函数适用于选择页面加载时存在的所有选择输入 但不适用于动态添加
  • Delphi REST API 帖子示例

    有人可以发布一个使用 Delphi 2005 向 API 发送 JSON POST 请求的简单示例 我发现了许多使用 GET 的示例 但 API 提供程序不允许通过 HTTP GET 请求 也不支持 URL 编码参数 我对调用 REST 服
  • 什么时候在排序之外使用太空船运算符?

    我只见过 Perl 宇宙飞船运算符 在数字排序例程中使用 但它在其他情况下似乎很有用 我只是想不出实际用途 什么时候可以在 Perl 排序之外使用它 This is a best practice question 我正在为机器人乔编写一个
  • App.Config 应该是应用程序的伴随文件还是放在自己的组件中?

    当我创建 Windows Installer 程序包 例如使用 WiX 并安装该应用程序时App exe以及App exe config配置文件应该有自己的组件还是应该是应用程序可执行文件的伴随文件
  • Netty 处理程序未调用

    我正在尝试使用简单的服务器客户端应用程序进入 Netty 代码见下文 我正在努力解决两个问题 ConfigServerHandler 分别ConfigClientHandler 被正确调用 但是 FeedbackServerHandler