2024-04-04  阅读(7)
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/6180343995

回答

在 Netty 中有多种方式可以发送消息。

  • Channel.writeAndFlush():调用 Channel 的 write() 方法是最直接的方式。这种方式发送的消息会使数据经过整个出站处理器链。
  • ChannelHandlerContext.writeAndFlush():在 ChannelHandler 中我们通过调用传入的 ChannelHandlerContextwriteAndFlush()。这种方式发送的消息是从当前 ChannelHandler 开始流经出站处理器链。
  • ChannelPipeline.writeAndFlush():通过 ChannelHandlerContextpipeline() 获取到 ChannelPipeline,然后调用它的 writeAndFlush()。这种方式发送的消息和 Channel 一致,数据会经过整个出站处理器链。

详解

下面大明哥来演示下上面的三种方式。

新建 6 个 ChannelHandler:

public class ChannelHandlerTest01 extends ChannelDuplexHandler {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.fireChannelRead(msg);
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        System.out.println("传递到了 [ChannelHandlerTest01] 中的 write()...");
        ctx.write(msg);
    }
}


......

public class ChannelHandlerTest06 extends ChannelDuplexHandler {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.fireChannelRead(msg);
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        System.out.println("传递到了 [ChannelHandlerTest06] 中的 write()...");
        ctx.write(msg);
    }
}

按照 ChannelHandlerTest01 —> ChannelHandlerTest02 —> ChannelHandlerTest03 —> ChannelHandlerTest04 —> ChannelHandlerTest05 —> ChannelHandlerTest06 这个顺序构建一个 ChannelPipeline 链表出来。

1、Channel.writeAndFlush()

现在 ChannelHandlerTest04 中的 channelRead() 调用 ctx.channel().write(msg); 如下:

public class ChannelHandlerTest04 extends ChannelDuplexHandler {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.channel().writeAndFlush(msg);
    }

    //...
}

执行运行结果如下: