I use netty and I want to send various objects from client to server and vice versa.
I created same decoders and encoders classes on client and server ;
Decoder:
public class UserInfoDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
...
list.add(new UserInfo(...))
}
}
Encoder:
public class UserInfoEncoder extends MessageToByteEncoder<UserInfo> {
@Override
protected void encode(ChannelHandlerContext ctx, UserInfo msg, ByteBuf out) {
...
out.writeBytes(...);
}
}
Here is my server initChannel method:
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
p.addLast(
// new ObjectEncoder(),
// new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new UserInfoDecoder(),
new UserInfoEncoder(),
new ObjectEchoServerHandler());
}
There is a method channelRead in server handler class
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
...
}
How to differ objects what was sent by client?
For e.g. now I have only UserInfo class and i can cast Object msg in channelRead to UserInfo, but i want to send UsersCar object too for e.g., how to differ objects by types which were sent?
As the current implementation stands, the easiest way to accomplish this would be to add a 'magic byte' prefix to your encoded bytes before sending them across the channel.
public class UserInfoEncoder extends MessageToByteEncoder<UserInfo> {
@Override
protected void encode(ChannelHandlerContext ctx, UserInfo msg, ByteBuf out) {
final int USER_BYTE = 0;
out.writeBytes(USER_BYTE);
out.writeBytes(msg.toBytes());
}
Then on the server side, when message is being decoded, check this magic byte and assign the appropriate decoder based on the value read. E.g. If the first undecoded byte has a value of 0, use the UserInfo decoder. If the value of the first undecoded byte is 1, use UsersCar decoder.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
final ByteBuf message = (ByteBuf) msg;
final byte magicByte= message.getByte(0);
if(magicByte == 0){
new UserInfoDecoder().decode(message);
}else if {
....
}
}
Not the neatest solution, but the simplest.
Note: This is assuming the handler you're using is extending ChannelInboundHandlerAdapter
A good example to get your head around Netty encoding/decoding: http://shengwangi.blogspot.ie/2016/03/netty-tutorial-hello-world-example.html