Java Netty: Почему не вызывается channelActive?

#java #sockets #tcp #netty

Вопрос:

Я нахожусь в процессе изучения Netty и пытаюсь создать клиентско-серверную программу для передачи пользовательских пакетов с помощью ByteBuf . Моя главная проблема, однако, заключается в том, что один из моих #channelActive методов не вызывается, и я не понимаю, почему.

Чтобы дать немного контекста, у меня есть PacketHandlerBoss и InitialHandler , оба из которых обрабатывают входящие PacketWrapper объекты.

 public class PacketHandlerBoss extends ChannelInboundHandlerAdapter {

    private ChannelWrapper channelWrapper;
    @Setter
    private PacketHandler packetHandler;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("! ! ! Called channelActive in PacketHandlerBoss ! ! !");
        if (this.packetHandler != null) {
            this.channelWrapper = new ChannelWrapper(ctx);
            this.packetHandler.connected(this.channelWrapper);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if (this.packetHandler != null) {
            this.channelWrapper.markClosed();
            this.packetHandler.disconnected(this.channelWrapper);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (this.packetHandler != null) {
            PacketWrapper wrapper = (PacketWrapper) msg;
            boolean shouldHandle = this.packetHandler.shouldHandle(wrapper);
            try {
                if (shouldHandle amp;amp; wrapper.getPacket() != null) {
                    wrapper.getPacket().handle(this.packetHandler);
                }

                if (shouldHandle) {
                    this.packetHandler.handle(wrapper);
                }
            } finally {
                wrapper.singleRelease();
            }
        }
    }
}
 
 public class InitialHandler extends PacketHandler {

    private ChannelWrapper channelWrapper;

    @Override
    public boolean shouldHandle(PacketWrapper packet) {
        return !this.channelWrapper.isClosing();
    }

    @Override
    public void connected(ChannelWrapper channelWrapper) {
        this.channelWrapper = channelWrapper;
    }

    @Override
    public void disconnected(ChannelWrapper channelWrapper) {}

    @Override
    public void exception(Throwable t) {}

    @Override
    public void handle(PacketWrapper packetWrapper) {
        if (packetWrapper.getPacket() == null) {
            throw new QuietException("Unexpected packet received! "   ByteBufUtil.hexDump(packetWrapper.getBuf(), 0, Math.min(packetWrapper.getBuf().writerIndex(), 16)));
        }
    }
}
 

Ошибка возникает из this.packetHandler.shouldHandle(wrapper) -за . Трассировка стека говорит , что this.channelWrapper это значение равно нулю InitialHandler , но я устанавливаю экземпляр InitialHandler#connected , который вызывается PacketHandlerBoss#channelActive .

Я запустил программу с инструкцией печати в channel active, и ничего не печатается, то есть активный канал не вызывается PacketHandlerBoss . Я не понимаю, почему это так…

Ниже PipelineUtils приведен класс, который управляет всеми обработчиками:

 public class PipelineUtils {

    public static final Base BASE = new Base();
    public static final String TIMEOUT_HANDLER = "timeout";
    public static final String BOSS_HANDLER = "boss_handler";
    public static final String PACKET_ENCODER = "packet_encoder";
    public static final String PACKET_DECODER = "packet_decoder";
    public static final String CHANNEL_REGISTRAR = "channel_registrar";

    public static final ChannelInitializer<Channel> PROXY_CHILD_HANDLERS = new ChannelInitializer<>() {

        @Override
        protected void initChannel(Channel channel) {
            try {
                PipelineUtils.BASE.initChannel(channel);
            } catch (Exception e) {
                e.printStackTrace();
                channel.close();
                return;
            }

            channel.pipeline()
                    .addBefore(PipelineUtils.TIMEOUT_HANDLER, PipelineUtils.PACKET_DECODER, new MinecraftDecoder(Protocol.GAME, true))
                    .addBefore(PipelineUtils.BOSS_HANDLER, PipelineUtils.PACKET_ENCODER, new MinecraftEncoder(Protocol.GAME, true))
                    .get(PacketHandlerBoss.class).setPacketHandler(new InitialHandler());
        }
    };

    private static final class Base extends ChannelInitializer<Channel> {

        @Override
        protected void initChannel(Channel channel) {
            channel.pipeline()
                    .addLast(PipelineUtils.TIMEOUT_HANDLER, new ReadTimeoutHandler(30000, TimeUnit.MILLISECONDS))
                    .addLast(PipelineUtils.BOSS_HANDLER, new PacketHandlerBoss());
        }
    }
}
 

Комментарии:

1. Не могли бы вы также добавить код, который показывает, как вы используете ServerBootstrap etc ?