How Apache Tomcat Implemented WebSocket

posted by fhanik on May 1, 2012 07:13 AM

With the Apache Tomcat 7.0.27 release, the Apache Tomcat team introduced a WebSocket implementation. In a previous post, we took a look at what the WebSocket implementation means, including what benefits and limitations they present. Today, we will discuss specifically how WebSocket is implemented in Apache Tomcat 7.

Since WebSocket is a protocol sent over TCP after an initial HTTP handshake, you could effectively implement WebSocket using Tomcat’s Comet implementation. There is a back port to Tomcat 6 suggested that does exactly that with very minor changes.

The Apache Tomcat team however decided to go with a more substantial implementation with changes to the core of Tomcat’s network and protocol implementation. The reason for this was memory and scalability based. If Tomcat can recycle the HttpServletRequest/Response objects after the initial handshake, each WebSocket connection will take up less memory in the Java heap. It also opens up the Tomcat container for other future protocols that utilize the HTTP Upgrade feature.

The WebSocket implementation from an API standpoint is fairly straightforward. You really can only do two things:

  1. Send messages
  2. Receive messages

This means you have to implement a mechanism to send a message based on a specific action in your application and implement a callback listener when a message arrives from a client.

To get yourself familiarized with the best way is to walk through some of the examples within Tomcat. We will demonstrate the Chat example, and dive into the API a little bit deeper.

To get started with WebSocket you will have to extend Tomcat’s WebSocket class.

Step 1 – extend the WebSocketServlet class

public class ChatWebSocketServlet extends WebSocketServlet

Since it’s a servlet, you must map it to a URL 


In this step we have touched on several important aspects

  1. Since this is a servlet, Tomcat decides if a HTTP request is a WebSocket request based on the URL that you have mapped to your servlet in web.xml or using annotations.
  2. Your class has to import org.apache.catalina.websocket.WebSocketServlet
  3. You can protect access to this using standard methods (servlet security) or frameworks like Spring Security.
  4. It’s a servlet. Lifecycle events, initialization and request parameters, cookies, session data, all the goodies you already know how to use are available to you.

That’s the easy part, let’s move on to using the actual API to receive messages.

Step 2 – Implementing a message listener

Extending the WebSocketServlet requires you to implement the

protected StreamInbound createWebSocketInbound(String subProtocol) {

return new ChatMessageInbound();


method. The StreamInbound class has a few onXXX methods that can be implemented to be notified of events. The two required methods are

protected void onBinaryData(InputStream is);
protected void onTextData(Reader r);


WebSocket messages can come in binary form, onBinaryData, or text form, onTextData, and your application may choose to utilize one or both of these methods. Once you’ve created a class that implements both these methods your application is ready to receive messages.

An example implementation would look like this (only text data)

private final class ChatMessageInbound extends MessageInbound {
protected void onBinaryMessage(ByteBuffer message)
throws IOException {
//this application does not expect binary data
throw new UnsupportedOperationException(
"Binary message not supported.");
protected void onTextMessage(CharBuffer message) throws IOException {
String msg = message.toString();
//modify the message by adding a timestamp
msg = “(“ + System.currentTimeMillis()+”) “+ msg;
private void broadcast(String message) {
//write some code to process the message

If you wish to be notified when a WebSocket connection is opened or closed, simply override the onOpen and onClose methods

protected void onOpen(WsOutbound outbound);
protected void onClose(int status);

In the Chat example, these two methods track when Chat clients arrive or leave the chat.


Step 3 – Writing data to the client

Writing data is pretty straightforward. Your StreamInbound implementation will have a reference to the sender component, WsOutbound. You simply retrieve it by calling


at that point you can send either binary

public void writeBinaryData(int b);
public void writeBinaryMessage(ByteBuffer msgBb);

or textual data to the client

public void writeTextData(char c);
public void writeTextMessage(CharBuffer msgBb);

So why do we have two methods for sending textual and two methods for sending binary data? The answer is one of them is streaming, the other is to send a buffered message. When streaming messages, meaning you are using one of these two methods

public void writeTextData(char c);
public void writeBinaryData(int b);

These methods are mutually exclusive. Don’t call both of these methods and expect both binary and textual data to be sent. When you’re done streaming, simply call

public synchronized void flush() throws IOException;

If you previously called writeTextData(char c) you can switch to binary data after calling flush(). Calling flush() completes the WebSocket message. A message can be sent down to the client in multiple frames (or fragments), a frame being a WebSocket defined set of data. When you use the

public void writeTextMessage(CharBuffer msgBb);
public void writeBinaryMessage(ByteBuffer msgBb);

methods each set of data gets transferred as a message.

In the Apache Tomcat WebSocket Chat example, each time a message is received, it broadcasts that message to the other clients as a separate message.

private void broadcast(String message) {
for (ChatMessageInbound connection : connections) {
try {
CharBuffer buffer = CharBuffer. wrap(message); connection.getWsOutbound().writeTextMessage(buffer);
} catch (IOException ignore)
// Ignore

Step 4 – Closing the connection to the client

The one additional piece of important information is that there are two ways a channel can close in both a “clean” and a “not clean” manner. Clean implies that a handshake has been completed over TCP, using the

public synchronized void close(int status, ByteBuffer data)

method when initiated on the server. Not clean closure means that the TCP connection was disconnected or aborted prior to the close handshake taking place. To be notified of when a channel has been closed by the client or uncleanly, you override with:

protected void onClose(int status);


Tomcat’s WebSocket implementation utilizes servlets as the URL based endpoint for WebSocket communications and can utilize all the features that are available within a servlet. A developer implementing a WebSocket application can receive and send messages in the org.apache.catalina.websocket.StreamInbound and org.apache.catalina.websocket.WsOutbound classes. Messages can be streamed or sent as entire messages using the writeTextMessage, writeTextData, writeBinaryMessage, writeBinaryData methods. The first released version of WebSocket in Apache Tomcat was released with Apache Tomcat 7.0.27 and the above Chat example can be found in the webapps/examples/websocket folder of the Apache Tomcat installation.

We encourage Tomcat users to try it out, and if you have feedback or issues please address them on the official Apache Tomcat user mailing lists.

Filip Hanik is a Senior Software Engineer for the SpringSource Division of VMware, Inc. (NYSE: VMW) and a key participant in the company's Apache Tomcat initiatives. Filip brings 15 years of extensive experience in architecture, design and development of distributed application frameworks and containers and is recognized for his top-quality system development skills and continuous participation of Open Source development projects. Filip is an Apache Software Foundation member and a committer to the Apache Tomcat project where he is a leading authority on Tomcat clustering and a key contributor to the core of the platform. Filip has made contributions to software initiatives for, Sony Music, France Telecom and has held a variety of senior software engineering positions with technology companies in both the United States and Sweden. He received his education at Chalmers University of Technology in Gothenburg, Sweden where he majored in Computer Science and Computer Engineering.


"connections" variable

In method broadcast() in Step3 above you loop on a variable called "connections" - where do you get this from? Thanks!

Paste this and GO! in you

Paste this and GO! in you browser while tomcat is running: http://localhost:8084(change to your port)/examples/websocket/


Ok found the full-servlet code! Awesome stuff, well done!

broadcasting a message through a specific websocket in java

Thanks for the tutorial. I got my app to work but I need help with retrieving an object of a specific websocket so that i can brodcast a message to it, within a java Spring Controller for example:
I have three sockets that are created by url-parttened in the web.xml as
NB: these are in three different servlets
This means that I would have 3 websockets that users have choice to connect to. Also note that I am using Spring MVC 3.

My Question: When a user posts a form that has data going to the database & then upon successfully persisting the data, I would want to use a Controller to broadcast the message to websocket "one" and not the other two. How do I achieve that?

Your assistence is well appreciated. :)

How do you access the request parameters ?

I can only see the reference of HttpServletRequest in createWebSocketInbound. How can I access request parameters in the onTextMessage event ?

How To Debt Negotiation

The most interesting text on this interesting topic that can be found on the net ...
learn about debt management


how to get subscribers
The online world is usually bogged decrease having untrue information sites without the need of authentic meaning even so the write-up seemed to be excellent in addition to worthwhile this understand. Appreciate it intended for giving that by himself.
buy comments


hungry shark evolution cheat Acknowledges for penmanship such a worthy column, I stumbled beside your blog besides predict a handful advise. I want your tone of manuscript... cheat clash of clans android

Appreciate it intended for giving that by himself.

Obat Kista Sakit kista tidak bisa menyebar ke bagian organ tubuh lain.
obat gagal ginjal Dalam tempo satu tahun proses pengobatan gagal ginjal Pak Sigit sudah menghabiskan sebanyak 150 juta rupiah.
obat miom ancaman keguguran karna miom yang membesar akan mendorong janin.

Obat rematik Tradisional

let it be the one Obat Rematik Tradisional

Jelly Gamat

Harga Jelly Gamaat

Ace Maxs


obat kanker payudara Tahukah

obat kanker payudara Tahukah anda arti dari dari Kanker Payudara?
obat stroke Pemulihan Penyakit Stroke menggunakan amazon Plus Obat Tradisional Alami.
obat kanker serviks Faktor alami sebagai pelopor kanker leher rahim adalah umur lebih dari 40 tahun.
obat kanker prostat Penyakit Kanker Prostat adalah suatu penyakit kanker yang mana berkembang di bagian prostat.

I like viewing web sites

I like viewing web sites which comprehend the price of delivering the excellent useful resource free of charge. I truly adored reading your posting. Thank you! download Text Your Ex Back

Post new comment

This question is for testing whether you are a human visitor and to prevent automated spam submissions.