LengthFieldBasedFrameDecoder не вызывает следующий обработчик

#netty

#netty

Вопрос:

Я использую LengthFieldBasedFrameDecoder в качестве своего первого обработчика для входящего трафика, который отправляется от клиента.

Длина: 4 байта Полезная нагрузка: Привет — 5 байт

[0, 0, 0, 9, 72, 101, 108, 108, 111]

 ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
    .channel(NioServerSocketChannel.class)
    .childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast("frameDecoder", new PacketFrameDecoder());
            ch.pipeline().addLast(new GameServerHandler());
        }
    })
    .option(ChannelOption.SO_BACKLOG, 128)
    .childOption(ChannelOption.SO_KEEPALIVE, true);

// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(port).sync();
  

ByteToMessageDecoder Я вижу fireChannelRead(ctx, out, size) , что вызывается с пустым out и размером 0. Похоже, что исключение не генерируется. Я пробовал оба порядка следования в декодере.

 public class PacketFrameDecoder extends LengthFieldBasedFrameDecoder {

    //Constants
    private static final int MAX_FRAME_LENGTH = Integer.MAX_VALUE;
    private static final int LENGTH_FIELD_OFFSET = 0;
    private static final int LENGTH_FIELD_LENGTH = 4;
    private static final int LENGTH_FIELD_ADJUSTMENT = 0;
    private static final int INITIAL_BYTES_TO_STRIP = 4;

    //Constructors
    public PacketFrameDecoder() {
        super(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH,
            LENGTH_FIELD_ADJUSTMENT, INITIAL_BYTES_TO_STRIP);

    }

}
  

После этого я хочу обработать свое тело / полезную нагрузку в GameServerHandler который расширяется ChannelInboundHandlerAdapter .

 public class GameServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * This method is called with the received message, whenever new data is received from a client.
     * @param context
     * @param message
     */
    @Override
    public void channelRead(ChannelHandlerContext context, Object message) {
        Log.i("GameServerHandler"); //Breakpoint here
        ByteBuf in = (ByteBuf) message;
        try {
            String test = in.toString(io.netty.util.CharsetUtil.US_ASCII);
            Log.i(test);
        } finally {
            ReferenceCountUtil.release(message);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        context.close();
    }

}
  

Но channelRead в моем GameServerHandler не вызывается и не запускается. Я понятия не имею, что я делаю не так.

Ответ №1:

Я только что узнал, что проблема, похоже, связана с регулировкой длины. Мои заголовки (4 байта) включены в общую длину, поэтому есть 2 варианта:

  1. Вычтите длину заголовка из настройки поля длины: LENGTH_FIELD_ADJUSTMENT = -4
  2. Не инкапсулируйте длину заголовка при отправке сообщения и содержите только полезную нагрузку