Reputation: 459
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. It works when I use Netty Client (instead of TCP client) & Netty Server.
At the Netty Server side, in ServerHandler class, I get the Object "msg" as type "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'.
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. The same server code works when I use a Netty Client (as opposed to plain 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();
Please let me know if any other input is required from my end. Many thanks.
Upvotes: 0
Views: 1549
Reputation: 459
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. Then 'ByteBuf' format needs to be converted to 'ByteString' and finally ProtobufModel can be retrieved from 'ByteString' format.
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.
Upvotes: 0