Netty: A Different Kind of Web(Socket) Server

John Boardman Java, Technology Snapshot 9 Comments

Netty is used today in all kinds of applications, all over the Internet, to handle thousands (if not millions) of chat conversations, multiplayer games including Minecraft, Twitter, and many other applications. However, it hasn’t made it very far into the mindshare of enterprise programmers developing business applications.

I believe that Netty can introduce a new wave of functionality that other solutions simply cannot match because of its fully bi-directional text and binary non-HTTP data transport, along with its support for many more concurrent clients than traditional “thread-per-socket” servers.

You may know about Netty’s prowess with WebSockets, but did you know it can function extremely well as a traditional web server? Due to its very thoughtful design, by adding appropriate handlers to its pipeline, Netty can handle virtually any traffic. It can also handle multiple types concurrently, such as WebSockets and HTTP over the same port at the same time. By combining these together, programmers are spared from dealing with nuisances such as CORS (Cross Origin Resource Sharing) that can rear their ugly head when a browser tries to make requests to servers it did not download from.

The Power of Netty

To give an inkling of its power to transform enterprise applications, I put together a code example showing one of the traditional examples of the web, which is retrieving stock prices.

Other applications would have to make AJAX requests, poll, have refresh buttons, etc. to update prices. WebSockets removes the need for any of that. After creating a constantly open bi-directional connection, both the client and the server can talk to each other whenever there is a need, without any negotiation. So, the client lets the server know when any user alters criteria, and the server updates the client whenever relevant data changes based on that criteria.

You can find the fully functional code here.

I’ve set up a little JSON-based protocol for the client to let the server know what the user has decided. To add a new symbol to the list that the server is watching for the client, a simple call is all that is necessary. Here’s an example:

doSend('{"command":"add", "tickerSymbol":"GOOG"}');

This adds the symbol to the list. The next update from the server includes the current stock price (from Yahoo Finance’s REST API) for the new symbol in its data. It is equally easy to remove an item:

doSend('{"command":"remove", "tickerSymbol":"GOOG"}');

With these two commands, the client controls the list of symbols the server is watching for each user. On the server-side in the Netty handler, the only thing the programmer has to do to account for multiple users is ensure that a new handler is created for each new connection, and that no static members are used where data is not to be shared. Unless told otherwise with an annotation, Netty assumes that handlers are not shareable.

Let’s look at how the handlers are defined to the Netty pipeline. This is from the StockTickerServer class:

ServerBootstrap b = new ServerBootstrap();, workerGroup)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast("encoder", new HttpResponseEncoder());
p.addLast("decoder", new HttpRequestDecoder());
p.addLast("aggregator", new HttpObjectAggregator(65536));
p.addLast("handler", new StockTickerServerHandler());

The order here is very important, as each handler in the pipeline has a chance to process (or not process) data and pass it on to the next handler. The stock ticker handler is at the bottom, as it is the one that sends data back to the client and is therefore at the end of the pipeline. By creating new instances of the handlers, each new connection gets its own instances of each handler. If handlers are stateless and thread safe, singletons can be used instead where applicable to save memory. None of the handlers I’m using are shareable, so I’m not showing an example of that.

Netty as a Web Server

A few tricks are used to get Netty to handle HTTP and WebSocket traffic at the same time.

1. StockTickerServerHandler extends SimpleChannelInboundHandler < Object >

This tells Netty that we want all traffic to come to this handler. Otherwise, we could use SimpleChannelInboundHandler<FullHttpRequest> if we only wanted to handle HTTP traffic, or SimpleChannelInboundHandler<WebSocketFrame> if we only wanted to handle WebSocket traffic.

2. The channelRead0 (channel read zero) method

protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) {
this.handleHttpRequest(ctx, (FullHttpRequest)msg);
} else if (msg instanceof WebSocketFrame) {
this.handleWebSocketFrame(ctx, (WebSocketFrame)msg);

This allows us to process HTTP and WebSocket traffic according to each protocol. handleHttpRequest serves up HTML, images, CSS, JavaScript, and all the other normal web traffic, and handleWebSocketFrame figures out what to do with the custom messages that are sent from the client.

3. Mime types

Netty doesn’t come built-in with support for processing mime types, as WebSocket calls don’t inherently need them.

I added a slightly modified version of Apache’s mime types file and load it statically. I’m synchronizing on the load because Netty can create quite a lot of handlers at the start for a pool if it wants to, and the constructor can be being executed by many handlers at the same time. Since the field is static, the map could be loaded many times before it becomes non-null. Synchronizing on a static lock (NOT the current instance of the class) prevents this from happening.

Other Details

The handleWebSocketFrame method takes care of the different “known” types of Frames that the WebSocket protocol defines. Once a full text frame is received, I pass it off to the implementor of the Interface I created to specify how to deal with the business logic.

That code lives in StockTickerMessageHandler. It creates a background thread to retrieve the stock quotes and send them to the client, and processes the commands that are sent by the client.

There is a bit of messy code in there for handling the Gzip compressed data sent by Yahoo and parsing the JSON returned by the service, along with some code that uses java.util.concurrent classes like Executor, AtomicBoolean, AtomicReference, and CopyOnWriteArrayList to keep the background thread and the Netty handler from stomping on each other as they share the details about the channel and the current list of symbols.

I’m also using Gson to turn the incoming JSON into POJOs so they are more easily processed. Other than that, it is just the business end of this example.

A Note About Authentication

I didn’t have time to add authentication to this example. If I did, I would have used Shiro, a super powerful authentication/authorization/cipher framework that works with both normal applications and web applications. HTTPS support is also lacking as this is a public application for checking stock prices. There is an example for adding HTTPS (and WSS) here.

One thing that is very difficult (if not impossible) with JavaScript WebSockets is sending authentication data along with the upgrade request (i.e. calling new WebSocket(uri)). For this reason, it is typical to first send a HTTPS POST like a normal website would and set an auth cookie token. That way, when the upgrade request is sent, the cookie is automatically sent along with it. When using authentication, remember to use HTTPS and WSS instead of HTTP and WS to protect data. Once the authentication is in place, it just becomes a matter of checking for the authenticated user where necessary, noting that some traffic should always pass through (HTML, images, etc.).


Netty has come into its own as a high performance, game changing way to build new applications. Today’s enterprise applications can be much more interactive than they are now by utilizing the capabilities offered by WebSockets. I hope you’ve enjoyed this little adventure into Netty, and please forgive the awful browser client, I just didn’t have the time to do a nice Backbone.js client app for this example.


— John Boardman,

About the Author
John Boardman

John Boardman


John is a Sr. Keyhole Consultant with 20+ years of experience in C, C++, Java, and IoT enterprise software design and development. Also currently writing a multi-platform, multi-user game in Unity3d (and server in Java) and have written custom graphical game engine clients in C and C++ on several platforms.

Share this Post

Comments 9

  1. Zach Gardner

    Excellent overview, JB. I’ll definitely give it a look the next time I’m designing a single page app.

    Do you have any insight onto why Netty hasn’t made it into the enterprise consciousness yet? I’ve heard some chatter about WebSockets, but AJAX seems to be the de facto choice.

  2. John Boardman Post
    John Boardman

    Thanks Zach!

    I think it may be because AJAX is more well understood and accepted by the enterprise, and WebSockets is more of a wild west mentality. It takes a lot of time for enterprises to add new things to the mix because of the very real concerns they have about reliability, security, scalability, and maintainability. Netty checks off all these boxes, so there really isn’t a showstopper reason for not adding it.

    Deployment is another concern at the enterprise level, and Netty is developed as a standalone application instead of being embedded in a typical web server environment. Perhaps a company will come along and add the enterprise level configuration and deployment support that will help overcome this hurdle.

  3. Remigius Stalder

    Thanks for the hint.

    I didn’t know that port sharing between http and websockets with netty was *THAT* simple. I’m currently experimenting with a HTTP pipeline and a netty-socketio pipeline on the same port, which works but I don’t know about its future support. Therefore I might decide to go with plain-vanilla websockets.

    The reason for all this is that I want to replace AJAX responses by server push, as this leads to change events that can be consumed by all clients working on the same aggregate at a time (i.e. automated updates on remote data changes).

    A word about Shiro: In my proof-of-concept I have tried to integrate Shiro with netty, but this (imho) turned out to be a non-trivial task. No sample code (except some resources mentioning that SecurityUtils.getSubject() must be replaced because it uses threadlocal storage) and a stackoverflow question regarding shiro/netty asked two months ago had so far 38 views and 0 replies – which earned me the Tumbleweed badge). So I decided to brew my own authentication handler which I’ll eventually publish.

    1. John Boardman Post
      John Boardman

      Thank you for your comment. I was surprised at how easy it was as well! Adding Shiro is non-trivial as you said, but it is possible. I’ll look at putting together a blog on how to do it successfully.

      Feel free to add a link here to your authentication handler if you end up publishing it. I’d be interested in looking at how you approached the problem.

  4. PJ

    Hi John,

    Impressive work. So far the best demo on WebSocket with netty. Better explained than the official version. You made a less well-known concept a fully-featured working solution. The only suggestion is to make it easier for eclipse users by adding a gradle task for eclipse project.


    1. John Boardman Post
      John Boardman

      Thank you for your nice words, I really appreciate it. If I can help even one person then the effort was worth it! I’ll see about firing up Eclipse for a gradle task. I used IntelliJ to create the demo but there’s no reason Eclipse wouldn’t be just as capable.

    2. John Boardman Post
      John Boardman

      I installed the Mars release of Eclipse and gradle support, then imported the gradle project and committed the resulting Eclipse project files. Hope that helps!

    1. John Boardman Post
      John Boardman

      I’m sorry but no, I just have not had the time to dedicate to it. The key to integrating Shiro with Netty from a Shiro perspective is in this section of the Shiro documentation:

      It may be a while yet before I am able to work up an example and a blog. It is still on my to-do list.

Leave a Reply