客户端不使用ChannelHandlerContext刷新Int刷新#writeAndFlush(java.lang.Object)

时间:2018-04-01 18:26:19

标签: netty

客户端不使用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

2 个答案:

答案 0 :(得分:0)

默认情况下,Netty中客户端和服务器之间的通信是使用ByteBuf对象完成的。为了发送不同类型的对象,我们需要DecoderEncoder

回到你的问题,在管道中没有适当的编码器(在服务器中)和解码器(在客户端中),将无法识别Integer对象。为了使其工作,您可以尝试执行以下步骤:

  1. ObjectEncoder添加到服务器管道中(例如,对传出的Integer对象进行编码。
  2. ObjectDecoder添加到客户端管道ObjectDecoder(ClassResolvers .cacheDisabled(getClass().getClassLoader()))中(例如,解码传入的Integer对象。
  3. 添加相应的SimpleChannelInboundHandler<Integer>处理程序以处理消息。
  4. 以上方法仅供您进行测试。对于生产实现,必须明确定义客户端和服务器之间的消息格式合同。希望它有所帮助。

答案 1 :(得分:0)

在向通道写入内容之前,您需要encode反对有线格式,并且在从通道读取后,您需要将其转换回适当的对象(decode)。为了让你的生活轻松,netty有两个类用于编写和阅读对象。它们是ObjectEncoderObjectDecoder

您可以将以下代码传递到服务器/客户端的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。它将引导您完成所有基础知识。