Simple example of Netty 4 usage

I feel the title of this post over-promises, since I was not able to make an example that seemed simple to me.

Anyway, here is a near-minimal example of how to use Netty to make a server that shouts back at you whatever you say:

NettyExample.java:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import java.nio.charset.Charset;

class NettyExample
{
    public static void main( String[] args ) throws Exception
    {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try
        {
            new ServerBootstrap()
                .group( bossGroup, workerGroup )
                .channel( NioServerSocketChannel.class )
                .childHandler( new Init() )
                .bind( 1337 ).sync().channel().closeFuture().sync();
        }
        finally
        {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static class Init extends ChannelInitializer
    {
        @Override
        public void
        initChannel( SocketChannel ch ) throws Exception
        {
            ch.pipeline().addLast( new ShoutyHandler() );
        }
    }

    private static class ShoutyHandler extends ChannelInboundHandlerAdapter
    {
        @Override
        public void channelRead( ChannelHandlerContext ctx, Object msg )
        {
            try
            {
                Charset utf8 = CharsetUtil.UTF_8;
                String in = ( (ByteBuf)msg ).toString( utf8 );
                String out = in.toUpperCase(); // Shout!
                ctx.writeAndFlush( Unpooled.copiedBuffer( out, utf8 ) );
            }
            finally
            {
                ReferenceCountUtil.release( msg );
            }
        }

        @Override
        public void exceptionCaught(
            ChannelHandlerContext ctx, Throwable cause )
        {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

The lines that actually do something useful are highlighted in red. If anyone knows how to make it shorter, please comment below. It seems a lot to me.

To run this, do:

sudo apt-get install openjdk-8-jdk
wget 'http://search.maven.org/remotecontent?filepath=io/netty/netty-all/4.1.5.Final/netty-all-4.1.5.Final.jar -O netty-all-4.1.5.Final.jar'
javac -Werror -cp netty-all-4.1.5.Final.jar:. NettyExample.java && java -cp netty-all-4.1.5.Final.jar:. NettyExample

Then in another terminal:

echo "Hello, world" | nc localhost 1337

and observe the response:

HELLO, WORLD

Comparison with Node.js

Just for comparison, here is an approximate equivalent in Node.js:

shouty.js:

var net = require('net');

var server = net.createServer(
    function( socket ) {
        socket.setEncoding('utf8');
        socket.on(
            'data',
            function( data ) {
                socket.end( data.toUpperCase() );
            }
        )
    }
);

server.listen( 1337, "localhost" );

To run it, do:

sudo apt-get install nodejs-legacy
node shouty.js

Then in another terminal:

echo "Hello, world" | nc localhost 1337

and observe the response:

HELLO, WORLD

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.