简体   繁体   English

使用 Java 的普通 TCP 客户端和 Netty 服务器之间的 Protobuf 消息交换

[英]Protobuf message exchange between plain TCP client & Netty Server using Java

I am trying to create a TCP socket connection between a plain TCP client and Netty Server using Protobuf message exchange format in Java and it does not work.我正在尝试使用 Java 中的 Protobuf 消息交换格式在普通TCP客户端和 Netty 服务器之间创建 TCP 套接字连接,但它不起作用。 It works when I use Netty Client (instead of TCP client) & Netty Server.当我使用 Netty 客户端(而不是 TCP 客户端)和 Netty 服务器时,它可以工作。

At the Netty Server side, in ServerHandler class, I get the Object "msg" as type "PooledUnsafeDirectByteBuf" .Netty 服务器端,在 ServerHandler class 中,我得到 Object "msg" 作为类型"PooledUnsafeDirectByteBuf" Now when I try to convert it to my custom Protobuf object it fails with error - 'java.lang.ClassCastException: class io.netty.buffer.PooledUnsafeDirectByteBuf cannot be cast to class ProtoModel'.现在,当我尝试将其转换为我的自定义 Protobuf object 时,它失败并出现错误 - 'java.lang.ClassCastException: class io.netty.buffer.PooledUnsafeDirectByteBuf 无法转换为 ZA2F2ED4F8EBC12ABCB4Z2C

public class ServerHandler extends ChannelInboundHandlerAdapter  {
---
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
--- 

Client Side Code客户端代码

Socket clientConnection = new Socket("localhost",SERVER_PORT);
ObjectOutputStream outToServer = new ObjectOutputStream(clientConnection.getOutputStream());
ProtoModel.writeTo(outToServer); //ProtoModel is the protobuf class

I think it is something to do with Protobuf message encoding at TCP client end and decoding at Netty Server end.我认为这与 TCP 客户端的 Protobuf 消息编码和 Netty Server 端的解码有关。 The same server code works when I use a Netty Client (as opposed to plain TCP Client).当我使用 Netty 客户端(而不是普通的 TCP 客户端)时,相同的服务器代码可以工作。

Netty Client Code Netty 客户端代码

EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ClientInitializer());
Channel ch = bootstrap.connect("localhost",SERVER_PORT).sync().channel();
ChannelFuture lastWriteFuture = ch.writeAndFlush(ProtoModel);
lastWriteFuture.channel().closeFuture().sync();

Please let me know if any other input is required from my end.如果我需要任何其他输入,请告诉我。 Many thanks.非常感谢。

I am able to resolve this issue.我能够解决这个问题。 I am posting the solution below.我在下面发布解决方案。

Server Code服务器代码

public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            ProtobufModel obj = ProtobufModel.parseFrom(ByteString.copyFrom(req));
}

The Object 'msg' is received as ByteBuf format in server end. Object 'msg' 在服务器端以 ByteBuf 格式接收。 Then 'ByteBuf' format needs to be converted to 'ByteString' and finally ProtobufModel can be retrieved from 'ByteString' format.然后需要将'ByteBuf'格式转换为'ByteString',最后可以从'ByteString'格式中检索ProtobufModel。

Client Code客户代码

SocketChannel channel = SocketChannel
                    .open(new InetSocketAddress(InetAddress.getByName("localhost"), SERVER_PORT));
          ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
          byteBuffer.put(ProtobufModel.toByteArray());
          byteBuffer.flip();
          channel.write(byteBuffer);

At client end the ProtobufModel is converted to ByteBuffer and passed to server.在客户端,ProtobufModel 被转换为 ByteBuffer 并传递给服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM