- Differences (Netty 3 vs Netty4 )
- Sample application , code walk through
- Communication Process in Netty
- understanding how Handlers and Pipeline works
Differences (Netty 3 vs Netty4 ): There are various changes which has been incorporated in Netty4 so as to make it far much better, efficient and easy to understand as compared to v3, below are some which are enough for beginners to keep going.
- write vs writeandflush: in Netty4 you have three methods to write messages to channel i.e write(), flush() and writeandflush(). write() keeps on writing data to buffer(no flush) whereas writeandflush() writes and flushes all the data to channel. Key thing to keep in mind is that every single write is a SYSCALL which is pretty costly so you should be very careful while using write() / writeandflush().
- Changed ChannelEvents: in Netty4 there are fewer channelEvents as compared to Netty3 as [channelopen, channelBound, and channelConnected ] = channelActive ,where as channelInactive = [channelDisconnected,channelUnbound,channelClosed]
- messageRecieved() vs ChannelRead0(): you can read all received messages by channelRead0 method in Netty4 which was messageReceived() in Netty3 and will be same again in Netty5 🙂
- upStream/downstream handlers vs InboundHandlers/OutBoundHanders: Netty3 had pretty confusing terminology with handlers which has been simplified in Netty4 as InboundHandler to act upon incoming data & OutboundHandler for outgoing data (pretty intuitive isn’t it 🙂
- releaseExternalResources() vs shutdownGracefully(): Netty4 uses shutdownGracefully() method close all eventloop groups.
- channelPipelineFactory() vs channelInitializer(): Netty4 provides channelInitializer for you to configure your custom handler which is one of best feature of Netty according to me.
- There are various other changes not mentioned here infact major ones, see this page for complete reference http://netty.io/wiki/new-and-noteworthy-in-4.x.html
- Sample application:
- Now there is no need of channelFactory , use EventLoop group one for BossGroup and one for workerGroup, generally Boss threads accepts the connection and workers handle them and process them.
- ServerBootstrap it has been rewritten from scratch in Netty4 and provides similar basic setup to create a server, it also provides methods to configure options like customhandler, socketchannel type etc.
- You can add a custom handler via channelInitializer (to do some business logic) to your pipeline, this typically provides a great deal of flexibility to your application.One more worth point to note here is that this handler is evaluated for each channel.
- bind to this port or keep listening to this port for incoming connections.
- shutdownGracefully() is the new method, a new way of closing connections.
- Remember there is no immediate return of call, instead you get a channelFuture, you can check the completion of channelFuture to get the status of your call.
- create a EventLoopGroup similar to server
- ChannelInitializer class so as to create a customHandler for client pipeline
- connect method for connecting to the mentioned port and host.
- line 41 shows the use of listener to check response of write method (since no response is generated instantaneously , a future is returned instead ). By attaching a listener you can wait for response, you can use some methods to see what exactly is your response.
- close channel, try the same code with un-commenting some of the commented lines for fun 🙂
Since now we have seen complete code to write a client and server, one key thing to mention here is we have used channelInitializer to add custom handlers for our pipeline, here our handler does nothing except printing the message it has received.
Communication process in Netty:
Pictorial representation of Communication in Netty
Now when you are able to run all the code you need to understand
- When you run server.java, it gets bounded to a particular port and keeps on listening to that particular port for incoming connection
- As soon as any client connect to this port (try to override channelHandlerAdded() Method to see this ) and writes something to channel, message gets processed via specific handlers inside pipeline and later sent to server socket via network.
- Pipeline consists of series of handlers which act upon messages in pipeline and forwards message to the next appropriate handler.
- Message when reaches the server socket it has to go through the server pipelines in a similar fashion as client pipeline.
Role of pipeline and Handlers in our application :
- All communication happens in form of ByteBuffer
- we used Encoders to convert String (user-input) to ByteBuff and Decoders to convert them back to ByteBuff
- At server pipeline:
- You might have already noticed that we are null terminating each line before sending message to server, in server pipeline FRAMER (DelimiterBasedFrameDecoder) decodes the received ByteBuff by delimiter( “/n” )
- now our second handler StringDecoder converts striped ByteBuff into String format after which our customHandler comes into action and we simply asks it to print message to console, you could do all sort of interesting stuff here.
- If you extend this application and asks it to send the received message back to client, you need to add these lines inside serverHandler read0 method:
String msg_ = “Response: “+msg;ctx.write(msg_+”\n”);ctx.flush();so now after printing the received message we append it by a “\n” and sends it back to the client, here the StringEncoder of server comes in action and play its role by converting string back to ByteBuff
- At client side:
- Response from server gets Decoded by FRAMER , stripped message can be printed now by converting it to a string via StringDecoder, so just write a SYSOUT in channelRead0 method of clientHandler.PS: Comments and suggestions are more than welcome !!!