【问题标题】:Inject asynchronous, synthetic messages into inbound channel handler pipeline将异步合成消息注入入站通道处理程序管道
【发布时间】:2020-07-08 11:56:42
【问题描述】:

我有一个 netty 客户端从 TCP 连接读取消息,我想将合成消息添加到管道中,以便像正常消息一样由处理程序处理。

消息将每秒注入一次,使用周期性计时器,即这些消息与传入消息是异步的,因此我必须以某种方式手动调用管道,而无需等待 tcp 流量,但它肯定会有进行同步,因此不会同时调用管道处理程序。

在下面的简单示例管道中,必须在 1. 之后插入消息(因为否则帧解码器会混淆),但在 2. 之前(因为除了常规消息之外,它还应该处理合成消息那些)。

如何做到这一点?

【问题讨论】:

    标签: java netty


    【解决方案1】:

    您可以通过获取对位于您要注入合成消息的上游的处理程序的 ChannelHandlerContext 的引用来做到这一点。当您要插入消息时,调用上下文的fireChannelRead(Object) 方法,该方法调用管道中next 入站处理程序的channelRead 方法。

    Netty 会确保消息在正确的线程中处理。 (如果您已经在通道的事件循环线程中,则立即调用下一个处理程序;否则,调用将安排在下一个可用机会时在通道的事件循环线程上发生)。

    在您的情况下,您需要 frame-decoder 处理程序的上下文。 ChannelPipeline 有一些重载的“上下文”方法,它们返回处理程序的上下文。在本例中,假设您为处理程序指定了名称“frame-decoder”,我们将使用此名称查找上下文。 (或者,您可以通过传递对处理程序对象本身的引用或传递处理程序的Class 来查找它。)

    public static void injectMessage(ChannelPipeline pipeline,
                                     Object message) {
        ChannelHandlerContext ctx = pipeline.context("frame-decoder");
        ctx.fireChannelRead(message);
    }
    

    【讨论】:

    • 在仔细查看Netty code 之后,很明显Netty 会在正确的线程中触发“通道读取”事件(使用与此答案的初始版本非常相似的代码),所以你不必担心那部分。
    • 事实证明您甚至不需要创建自定义处理程序,因为您可以从管道中获取任何处理程序的上下文。
    • 像魅力一样工作。也感谢您的跟进和简化 - 它也简化了我的实际代码!
    猜你喜欢
    • 2021-12-25
    • 2020-09-28
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多