Обмен сообщениями Protobuf между обычным TCP-клиентом и Netty Server с использованием Java - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь создать сокет TCP-соединения между обычным TCP-клиентом и Netty Server, используя формат обмена сообщениями Protobuf в Java , и это не работает. Это работает, когда я использую Netty Client (вместо TCP-клиента) и Netty Server.

На стороне Netty Server в классе ServerHandler я получаю объект "msg" как тип "PooledUnsafeDirectByteBuf" . Теперь, когда я пытаюсь преобразовать его в свой пользовательский объект Protobuf, происходит сбой с ошибкой - 'java.lang.ClassCastException: класс io.netty.buffer.PooledUnsafeDirectByteBuf не может быть приведен к классу ProtoModel'.

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

Код на стороне клиента

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

Я думаю, что это связано с кодированием сообщений Protobuf на стороне TCP-клиента и декодированием на стороне Netty Server. Тот же код сервера работает, когда я использую Netty Client (в отличие от обычного TCP Client).

Netty Client Code

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();

Пожалуйста, дайте мне знать, если какой-либо другой ввод требуется с моей стороны. Большое спасибо.

1 Ответ

0 голосов
/ 23 октября 2019

Я могу решить эту проблему. Я публикую решение ниже.

Код сервера

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));
}

Объект 'msg' получен как формат ByteBuf на стороне сервера. Затем необходимо преобразовать формат «ByteBuf» в «ByteString» и, наконец, ProtobufModel можно извлечь из формата «ByteString».

Код клиента

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);

На стороне клиента ProtobufModel преобразуется в ByteBuffer и передается на сервер.

...