TomcatExpert

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 

<servlet>
<servlet-name>wsChat</servlet-name>
<servlet-class>
websocket.chat.ChatWebSocketServlet
<servlet-class>
</servlet> 
<servlet-mapping>
<servlet-name>wsChat</servlet-name>
<url-pattern>/websocket/chat</url-pattern>
</servlet-mapping>

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 {
 
@Override
protected void onBinaryMessage(ByteBuffer message)
throws IOException {
//this application does not expect binary data
throw new UnsupportedOperationException(
"Binary message not supported.");
}
 
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
String msg = message.toString();
//modify the message by adding a timestamp
msg = “(“ + System.currentTimeMillis()+”) “+ msg;
broadcast(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

@Override
protected void onOpen(WsOutbound outbound);
 
@Override
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

myStreamInbound.getWsOutbound()

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:

@Override
protected void onClose(int status);

Summary

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 Walmart.com, 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.

Comments

"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/

found

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
/one
/two
/three
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

jackson

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

GAME HACK

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

Pe

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

Davis

I prefer states it all has written the third blog page concerning dissertation penning. Previously I just launched, I just would always worry about penning dissertations. I did so n't need in order to a specific thing average. This unique replaced when real I just man-ed all the way up not to mention has written your to begin with basically l explore it's i'm all over this!
Pro DJ

Get instagram followers

You could buy Instagram followers to assist you to increase your landscapes. Instagram is regarded as the leading photo posting online websites found on the World Wide Web. It is also made use of by end users to display situation their style and creativity. People may take an image, submit it, utilize virtual screens, and after that write about it on various social bookmarking internet websites like Face book, Twitter and Tumbler and also to Instagram itself.

Buy instagram followers cheap
Buy likes on instagram
Buy instagram followers cheap
Get instagram likes

What a really awesome post

What a really awesome post this is. Truly, one of the best posts I've ever witnessed to see in my whole life. Wow, just keep it up. upresults.nic.in

Its a great pleasure reading

Its a great pleasure reading your post.Its full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work.Diabetes Destroyer

On this page, you'll see my

On this page, you'll see my profile, please read this information. quality management certification

Welcome to the party of my

Welcome to the party of my life here you will learn everything about me. cake bakeries in houston

A good blog always comes-up

A good blog always comes-up with new and exciting information and while reading I have feel that this blog is really have all those quality that qualify a blog to be a one.I wanted to leave a little comment to support you and wish you a good continuation. Wishing you the best of luck for all your blogging efforts. Rocket Spanish

Writing with style and

Writing with style and getting good compliments on the article is quite hard, to be honest.But you've done it so calmly and with so cool feeling and you've nailed the job. This article is possessed with style and I am giving good compliment. Best! Language of Desire

In this article understand

In this article understand the most important thing, the item will give you a keyword rich link a great useful website page: What Men Secretly Want

In this case you will begin

In this case you will begin it is important, it again produces a web site a strong significant internet site: The Instant Switch

These websites are really

These websites are really needed, you can learn a lot. Talk To His Heart

It's superior, however ,

It's superior, however , check out material at the street address. The Woman Men Adore

This is very interesting, but

This is very interesting, but it is necessary to click on this link: Ex Factor Guide Review

I can give you the address

I can give you the address Here you will learn how to do it correctly. Read and write something good. The Red Smoothie Detox Factor Review

Post new comment

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