我正努力与Netty保持联系。我在这里使用HTTP作为示例(我知道库中有HTTP(de / en)编码器,但是对我而言,此练习的目的是让我了解管道的工作方式。
我有一个构造如下的简单管道
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获得了响应
我先看到Source,然后看到播音员的方法来生成请求,但我再也没有看到接收方的解码方法,即。
为什么?
答案 0 :(得分:1)
在解码器实现中
您会发现,对于入站数据,
channelRead
方法/事件将被覆盖。从入站通道读取的每条消息都会调用此方法。然后它将调用提供的解码器的decode()
方法,并将解码后的字节转发到管道中的下一个ChannelInboundHandler
。
在您的情况下,您已覆盖read
的{{1}}方法,并且没有在此方法内调用ChannelOutboundHandlerAdapter
。这意味着它将防止调用任何ctx.read()
的{{1}}方法,从而防止任何解码器的channelRead
方法的调用。在您的情况下,ChannelInboundHandler
类阻止从通道读取。
同样,重写decode
的read方法的目的也不应该是向通道中写入内容。
以下是read方法的定义。
Source
是根据请求调用的,以从渠道读取更多数据
您可以阅读Netty in action这本书,以更好地了解净值。