回答
在 Netty 中有多种方式可以发送消息。
Channel.writeAndFlush()
:调用 Channel 的write()
方法是最直接的方式。这种方式发送的消息会使数据经过整个出站处理器链。ChannelHandlerContext.writeAndFlush()
:在 ChannelHandler 中我们通过调用传入的ChannelHandlerContext
的writeAndFlush()
。这种方式发送的消息是从当前 ChannelHandler 开始流经出站处理器链。ChannelPipeline.writeAndFlush()
:通过ChannelHandlerContext
的pipeline()
获取到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);
}
//...
}
执行运行结果如下: