1

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?

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

4 Comments

my previous question stackoverflow.com/questions/39500234/sockets-interaction-java decode - is a protected method
using decoder in channelRead we are changing logic of Netty, is it good?
I'm not sure I understand your comment. You're overriding the decode method in your UserInfoDecoder, which I assume you wrote yourself. There's no reason you can't make that method public instead of protected in that class, increasing the visibility of a field in subclasses is supported by java.
UserInfoDecoder extends ByteToMessageDecoder the signature of method is protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception I can create my own decoder and use it in channelRead, but i think it will change the original encoders/decoders logic of netty; Creating new Decoder object for each recieved query can load server (many queries in the period of time) I found a similar question stackoverflow.com/questions/23377089/… take a look please

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.