为什么从未调用过ByteToMessageDecoder解码方法?

时间:2018-10-17 14:13:37

标签: java netty

我正努力与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,然后看到播音员的方法来生成请求,但我再也没有看到接收方的解码方法,即

为什么?

1 个答案:

答案 0 :(得分:1)

在解码器实现中

  

您会发现,对于入站数据,channelRead方法/事件将被覆盖。从入站通道读取的每条消息都会调用此方法。然后它将调用提供的解码器的decode()方法,并将解码后的字节转发到管道中的下一个ChannelInboundHandler

在您的情况下,您已覆盖read的{​​{1}}方法,并且没有在此方法内调用ChannelOutboundHandlerAdapter。这意味着它将防止调用任何ctx.read()的{​​{1}}方法,从而防止任何解码器的channelRead方法的调用。在您的情况下,ChannelInboundHandler类阻止从通道读取。 同样,重写decode的read方法的目的也不应该是向通道中写入内容。

以下是read方法的定义。

  

Source 是根据请求调用的,以从渠道读取更多数据

您可以阅读Netty in action这本书,以更好地了解净值。