我正在使用 Netty 4.1.0.Final 并且我面临消息未通过出站处理程序传递的问题。我发布了一个示例程序,其中有一个入站处理程序和一个出站处理程序。入站处理程序在 ChannelHandlerContext 中使用 writeAndFlush,我的理解是它应该将消息转发到管道中第一个可用的出站处理程序。为简单起见,忽略内存管理。
引导代码
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.localAddress(12021)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TestHandler1(), new TestOutHandler1());
}
});
ChannelFuture future = bootstrap.bind().sync();
System.out.println("Server Started...");
future.channel().closeFuture().sync();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
System.out.println("Server Shutdown");
Run Code Online (Sandbox Code Playgroud)
入站处理程序代码
public class TestHandler1 extends ChannelInboundHandlerAdapter {
private static Log logger = LogFactory.getLog(TestHandler1.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
logger.info("channelRead");
ctx.writeAndFlush(msg);
}
Run Code Online (Sandbox Code Playgroud)
}
出站处理程序代码
public class TestOutHandler1 extends ChannelOutboundHandlerAdapter {
private static Log logger = LogFactory.getLog(TestOutHandler1.class);
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
logger.info("write");
ctx.writeAndFlush(msg);
}
Run Code Online (Sandbox Code Playgroud)
}
输出
信息 TestHandler1:通道读取
如果我通过在通道而不是 ChannelHandlerContext 上执行 writeAndFlush() 来如下更改我的入站处理程序,我将获得预期的输出
修改的入站处理程序
public class TestHandler1 extends ChannelInboundHandlerAdapter {
private static Log logger = LogFactory.getLog(TestHandler1.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
logger.info("channelRead");
ctx.channel().writeAndFlush(msg);
}
Run Code Online (Sandbox Code Playgroud)
}
输出
信息 TestHandler1:通道读取
信息 TestOutHandler1:write
根据诺曼在以下链接中的解释,我理解 ChannelHandlerContext.write(...) 应该通过它前面的 ChannelOutboundHandlers,在我的情况下,它是唯一的出站处理程序。
让我知道我的理解是错误的还是我遗漏了什么。
这是因为您在ChannelOutboundHandler之前ChannelInboundHandler添加将会从添加 的点ChannelPipeline. ChannelHandlerContext.writeAndFlush(...)开始。因此在它会按预期工作之前添加。ChannelPipelineChannelHandlerChannelOutboundHandler
小智 5
以前的答案很棒,我想解释问题的另一个方面:通过调用ctx.writeAndFlush()和ctx.channel.writeAndFlush()

ctx.writeAndFlush()ctx.channel.writeAndFlush()ctx.channel.writeAndFlush()会调用 pipeline.tail.writeAndFlush()。这相当于writeAndFlush()在您的频道中调用tail ctx。这样,TestOutHandler1 就会被找到并被TestOutHandler1.write()调用。然后打印两个信息。| 归档时间: |
|
| 查看次数: |
2621 次 |
| 最近记录: |