объектное сообщение, отправленное с помощью Netty, не может быть правильно декодировано - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь отправить объекту сообщение PingMessage с помощью netty.Добавьте ObjectEncoder и ObjectDecoder в конвейер канала.Клиент успешно отправил пакет, но сервер не может декодировать сообщение.ObjectDecoder # decode () просто возвращает ноль.Версия Netty - 4.1.28.Final.

PingMessage

public class PingMessage implements Serializable {
    private static final long serialVersionUID = 1L;
    private int flag = 0xff3e;
    private String ping = "ping";

    public int getFlag() {
        return flag;
    }

    public void setFlag(int flag) {
        this.flag = flag;
    }

    public String getPing() {
        return ping;
    }

    public void setPing(String ping) {
        this.ping = ping;
    }
}

клиент

public class HeartbeatInitializer extends ChannelInitializer<Channel> {

    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new ObjectEncoder());
        pipeline.addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingResolver(PongMessage.class.getClassLoader())));
        pipeline.addLast(new IdleStateHandler(BusinessConstant.READER_IDLE_SECONDS, BusinessConstant.WRITER_IDLE_SECONDS, 0));
        pipeline.addLast(new HeartbeatServerHandler());
        pipeline.addLast(new ClientHandler());
    }
}

public class HeartbeatServerHandler extends ChannelDuplexHandler {
        private static Logger logger = LoggerFactory.getLogger(HeartbeatServerHandler.class);

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleState = (IdleStateEvent)evt;
            if (idleState.state() == IdleState.READER_IDLE) {
            } else if (idleState.state() == IdleState.WRITER_IDLE) {
                try {
                    ChannelFuture future = ctx.writeAndFlush(new PingMessage()).sync(); 
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

сервер

public class HeartbeatInitializer extends ChannelInitializer<Channel> {

    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new ObjectEncoder());
        pipeline.addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingResolver(this.class.getClassLoader())));
        pipeline.addLast(new IdleStateHandler(BusinessConstant.READER_IDLE_SECONDS, BusinessConstant.WRITER_IDLE_SECONDS, 0));
        pipeline.addLast(new HeartbeatServerHandler());
        pipeline.addLast(new ClientHandler());
    }
}

public class HeartbeatServerHandler extends ChannelDuplexHandler {
    private static Logger logger = LoggerFactory.getLogger(HeartbeatServerHandler.class);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof PingMessage) {
            logger.info("received ping");
            return;
        }
    }
}

источник nettyинформация отладки кода

AbstractChannelHandlerContext # invokeChannelRead ()

((ChannelInboundHandler) handler()).channelRead(this, msg);

переменная msg равна

UnpooledUnsafeDirectByteBuf (ridx: 0, widx: 61), cap: 1024)

ObjectDecoder # decode () просто возвращает ноль

суперкласс ObjectDecoder равен LengthFieldBasedFrameDecoder.LengthFieldBasedFrameDecoder # decode () возвращает ноль

// LengthFieldBasedFrameDecoder#decode()

int frameLengthInt = (int) frameLength;
if (in.readableBytes() < frameLengthInt) {
    return null; // get executed and return null
}
...