我正在尝试掌握 Netty。我在这里使用 HTTP 作为示例(我知道库中有 HTTP(解码/编码)编码器,但本次练习的目的是让我了解管道的运行方式。
我有一个简单的管道构造如下
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel){
socketChannel.pipeline().addLast(new Announcer());
socketChannel.pipeline().addLast(new Receiver());
socketChannel.pipeline().addLast(new Source());
}
});
播音员是MessageToByteEncoder<String>
与 encode
方法:
@Override
protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) {
byte[] bytes = msg.getBytes(CharsetUtil.US_ASCII);
out.writeBytes(bytes);
}
来源是ChannelOutboundHandlerAdapter
与 read
方法:
@Override
public void read(ChannelHanderContext ctx) {
String path = "/";
String host = "xkcd.com"
String content = "GET " + path + " HTTP/1.1\n" +
"Host: " + host + "\n" +
"\n";
ctx.writeAndFlush(content);
}
接收者是ByteToMessageDecoder
与 decode
方法:
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
String e = in.toString(CharsetUtil.UTF_8);
System.err.println(e);
out.add(e);
}
我已验证 Source 的输出是有效的 HTTP 请求,并从 xkcd.com:80 获取响应
我看到源,然后调用播音员的方法来生成请求,但我从未看到调用接收者的解码方法。
为什么?
最佳答案
在解码器实现中
You’ll find that for inbound data the
channelRead
method/event is overridden. This method is called for each message that’s read from the inbound Channel . It will then call thedecode()
method of the provided decoder and forward the decoded bytes to the nextChannelInboundHandler
in the pipeline.
在您的情况下,您已经重写了 ChannelOutboundHandlerAdapter
的 read
方法,并且您没有在此方法内调用 ctx.read()
。这意味着它将阻止调用任何 ChannelInboundHandler
的 channelRead
方法,从而阻止调用任何解码器的 decode
方法。在您的情况下, Source
类正在阻止从 channel 读取。
另外,重写 ChannelOutboundHandlerAdapter
的读取方法的目的不应该是向 channel 写入内容。
以下是read方法的定义。
read(ChannelHandlerContext)
Invoked on request to read more data from the Channel
您可以阅读Netty in action本书可以帮助您更好地理解 netty。
关于java - 为什么我的 ByteToMessageDecoder 解码方法从未被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52857012/