2

I'm using Netty to develop a TCP server. I understand that the usual usage is to create a ServerBootstrap and pass an Initializer object to the childHandler() method. In the Initializer there is an initChannel method where we set up the pipeline with a bunch of addLast commands, adding things like DelimiterBasedFrameDecoder, StringEncoder, etc. This assumes that we know a priori that we will always get text/string messages.

However, I would like to implement a capability like what exists in python Twisted Protocols like LineReceiver where we can switch back and forth between raw mode and line mode. Yes one way to do that is to remove and add items from the pipeline dynamically. But I'm wondering if there is any good reason why I couldn't just use a minimal pipeline that uses a basic ChannelInitializer where the handler is just an extension of ChannelInboundHandlerAdapter. This way the channelRead method in the handler just processes the raw bytes (in ByteBuf). If I want to use line mode, isn't it possible for me to use DelimiterBasedFrameDecoder, StringEncoder, etc inside the channelRead method, i.e, call those directly and use them outside the context of the pipeline? Is there any good reason why I should NOT do this?

2 Answers 2

1

A simple comparison:

  • First, you have to know how those codec are working...
    • Some of them use a context that keep data as long as there are not enough, data coming from the incoming messages (as in DelimiterBasedFrameDecoder).
    • Some need you to write some extra methods, so doing your way does not prevent you to write those extra methods as you need.
    • Some are using context of the handler (ChannelHandlerContext), even if rare, to store some internals (session or like).
  • Tree call: So you will need to "manually" maintain the same behavior, passing the right argument by hand to each of them (ChannelHandlerContext at least). Not sure you have any gain therein. Moreover, the pipeline is made to be efficient, not reallocating when not needed for instance.
  • Memory: As you will need to create one per channel (since they are not sharable, and if they are, then the same for the pipeline), this is the same cost than creating one in the pipeline. So from memory side, not better.
  • Initialization: Adding/removing it manually to/from the pipeline, without the cost to maintain yourself the correct order of call, are I believe easier than making all by hand, allocating, keeping it somewhere in a private channelhandler attribute.
  • Behavior: some could rely on the Netty context (ChannelHandlerContext) to work correctly (for instance CompatibleObjectEncoder, MarshallingDecoder). WIll it work if this ChannelHandlerContext is not build by Netty ? Don't know... But then you need to be sure the codec act as YOU KNOW, for sure. And if it is changed (because the external API is the same but the way it implements it changed and so the behavior in your case), you HAVE TO KNOW it or your code may fail and you will not know before long why...

So in resume, I did not see any advantage to use those codes manually instead of inserting/removing them into the pipeline as needed, but I do see risk if the internal implementation change while you didn't notice and it breaks your "non standard" logic...

After that, nothing is impossible, so your choice ;-) But as noted in other comments, you might want to write your own codec, inspiring yourself from existing ones...

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

Comments

1

It's possible to put all encoders/decoders logic into the handler, but it's bad idea from architecture point.

Would be better to write new codec (encoder/decoder), maybe even based on them, you can look inside of StringEncoder or StringDecoder or even to DelimiterBasedFrameDecoder to understand how to do it, in fact they are pretty simple, or check on the netty site how they implementing TimeEncoder.

After that, codec will have opportunity to be tested separately and handler and code in general will be much clearer.

Comments

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.