Я пытаюсь отправить объекту сообщение 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
}