客户端不使用ChannelHandlerContext#writeAndFlush(java.lang.Object)读取服务器编写的Int。实际上,客户端的io.netty.channel.SimpleChannelInboundHandler#channelRead0没有执行。
但是,当服务器使用ChannelHandlerContext#writeAndFlush(java.lang.Object)写入ByteBuf时,客户端会按预期读取数据。
客户代码:
@Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
final ByteBuf buffer = Unpooled.buffer();
final ByteBuf bytes = in.getBytes(in.readerIndex(), buffer);
System.out.println("Client received: " + bytes.getInt(bytes.readerIndex()) + " " + bytes.readableBytes());
}
非工作服务器代码:
ctx.writeAndFlush(100)
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
工作服务器代码(在scala中):
val buf = Unpooled.buffer()
buf.writeInt(length)
ctx.writeAndFlush(buf)
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
请帮助我理解其中的差异。
谢谢, Prateek
答案 0 :(得分:0)
默认情况下,Netty中客户端和服务器之间的通信是使用ByteBuf
对象完成的。为了发送不同类型的对象,我们需要Decoder
和Encoder
。
回到你的问题,在管道中没有适当的编码器(在服务器中)和解码器(在客户端中),将无法识别Integer
对象。为了使其工作,您可以尝试执行以下步骤:
ObjectEncoder
添加到服务器管道中(例如,对传出的Integer
对象进行编码。ObjectDecoder
添加到客户端管道ObjectDecoder(ClassResolvers .cacheDisabled(getClass().getClassLoader()))
中(例如,解码传入的Integer
对象。SimpleChannelInboundHandler<Integer>
处理程序以处理消息。以上方法仅供您进行测试。对于生产实现,必须明确定义客户端和服务器之间的消息格式合同。希望它有所帮助。
答案 1 :(得分:0)
在向通道写入内容之前,您需要encode
反对有线格式,并且在从通道读取后,您需要将其转换回适当的对象(decode
)。为了让你的生活轻松,netty有两个类用于编写和阅读对象。它们是ObjectEncoder
和ObjectDecoder
。
您可以将以下代码传递到服务器/客户端的Bootstrap.hander()
方法,并在YourBusinessLogicHandler
类中编写业务逻辑。
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ObjectEncoder());
pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
pipeline.addLast(new YourBusinessLogicHandler())
}
}
客户端:
@Override
public void channelRead0(ChannelHandlerContext ctx, Object o) {
int number = (Integer) o;
System.out.println("Client received: " + number);
}
服务器:
Integer number = 100;
ctx.writeAndFlush(number);
从Netty阅读这篇优秀的getting started article。它将引导您完成所有基础知识。