Sunday, February 23, 2014

Netty: Basics for beginners

[Update:] please check my next post (Moving on to Netty4 )  here   

[If you dont like this GUI, click here to see this post in better format ]

  • Synchrnous vs Asynchronous:

Suppose you go to +Starbucks Coffee  , you EnQueue (brush up Data Structures :P )  to order your coffee, you stay in the queue until you get your chance to order, and once you order and pay, you still stay there blocking the queue until you get your coffee, won't that be awkward ?? (if No then go Synchronous, that's best for you :) else come to the world of Netty ) because we love Asynchronous things in life e.g Chat vs Call. 

In Synchronous systems you wait for reply, while in Asynchronous you don't.

  • Why Netty:  

"Netty is an asynchronous event-driven network application framework 
for rapid development of maintainable high performance protocol servers & clients."  from here  
  1. an asynchronous Non blocking IO API.
  2. provides low level data transfer and mechanism
  3. No response is generated, while invocation is instantaneous and response is generated in another thread
  4. works through listeners and events. 
  5. still lot many reasons more to use it see here

  • What is NIO and how it differs from OIO:

Old IO was a stream of bytes and the new IO is a block of bytes, old one was a synchronous while this one is Asynchronous. NIO is good for the situations where you have to keep a lot of connections open and do a little work amongst them, like in chat applications. In Old IO you keep thread pools to manage lot of thread IO work.  source here 

  • Netty terminology (Rough overview)

  1. Channel: a abstraction for communication or transfer of data (byte array)
  2. ChannelBuffer: Byte array which can provide random or direct data storage mechanism.
  3. ChannelPipeline: collection of handlers to process your events in the way you want.  
  4. ChannelFactory: Resource allocators, like thread pools.
  5. ChannelHandler: Provides method to handle events on channel.
  6. ChannelEvents: Events like connected, exception raised, message recieved etc. see in detail here

Writing a simple client server application using Netty and understand its working. 

Write a Server ChannelHandler.(call it ChatServerHandler)

Step1: Create a class named ChatServerHandler by extending         SimpleChannelHandler later you can learn advanced ways of doing this. 

Step2: Override its methods to access ChannelEvents, i have overrided 

  • messageRecieved(): helps us to fetch the message server recieved from client. MessageEvent e object provides getMessage() method to retreve message and you can use it to print or process. 
    Remember everything in Netty happens through channelBuffers. 

          public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
                ChannelBuffer buf = (ChannelBuffer) e.getMessage(); 
                while(buf.readable()) {
                    System.out.print((char) buf.readByte());
  • excaptionCaught(): helps you to get the exception while connecting or like events.
      public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {

            Channel ch = e.getChannel();

Write a server to use this ChannelHandler(call it ChatServer)

Step1: Create a ChannelFactory in server it has to be NioServerSocketChannelFactory there are several other channel Factories provided by Netty.

       ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool());

Step2: Create a server Bootstrap object it helps you create a basic setup of server else there are more detailed way of doing this, for simplicity i use this.
       ServerBootstrap bootstrap = new ServerBootstrap(factory);

Step3: set your channelHandler to ChannelPipeline so that it can process messageEvents. 

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
          public ChannelPipeline getPipeline() {
             return Channels.pipeline(new ChatServerHandler());

Step4:  Bind your server to run on a host and port.
      bootstrap.bind(new InetSocketAddress(8090));

Write a client (ChatClient) which simply takes user input and sends it to Channel.

Step1: Since Netty is asynchrnous in nature it does not assign dedicated thread for particular operation so we have create two threads:
  • Boss thread: they do main work like connect, bind and pass them for real work to worker threads. 
  • Worker thread: they do the real work.
Executor BossPool = Executors.newCachedThreadPool();
    Executor WorkerPool = Executors.newCachedThreadPool();    

Step2: Create a ClientChannelFactory object this time. 

     ChannelFactory channelFactory = new NioClientSocketChannelFactory(BossPool,WorkerPool);

Step3: create a clientBootstrap object as we did in server
    ClientBootstrap clientBootstrap = new ClientBootstrap(channelFactory);

Step4: Again set the ChannelPipeline in client (you can ignore it as of now in later steps you will know pipelines better.)
//setup the Channel PipeLine Factory ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline( new ObjectEncoder() ); } };
Step5: Give the server socket address to which this client is supposed to connect to.
   InetSocketAddress addressToConnectTo = new InetSocketAddress("localhost", 8090);

Step6: Once again since Netty is asynchronous it doesn't give you a immeadiate result back instead it returns a channelFuture which is kind of a result which will be generated in future.
    ChannelFuture cf = clientBootstrap.connect(addressToConnectTo);

Step7: Now get the channel object and write your Input data to it.

Import three source files and run and and run it.   

PS:- This post needs to be updated to be used with Netty v4 , there are some changes in terminology as compared to v3, will try to come with a new post with those changes explained.