Java & Ruby Development: Coding Cures, Concepts, API examples and more


Atmosphere Websockets & Comet with Spring MVC

Since writing this guide, Spring has come out with their own Comet and Websocket implementations. I suggest you first read through their guides before deciding on atmosphere as your Comet & Websocket solution.

1. Messaging with Stomp over Websockets
2. Spring Messaging

On to the guide...

Feel free to clone the source of this project on github.
springMVC-atmosphere-comet-websockets

The Websocket protocol is defined by W3C here. The protocol is considered an HTTP upgrade protocol. Essentially what happens is, a websocket request is made by a client browser, via the HTTP protocol. Once, the request is in, the server should respond with a success. Then the browser and server establish a TCP link to handle communication from there on out. This protocol enables bi-directional communication between a client and server. Here is a link to browser and servers that support Websockets and/or Comet: comet/websocket support link

Comet is a protocol set that uses HTTP to perform the same tasks. It is a clear abuse of the protocol, but high demand has forced support on most servers. Websockets is less developed, but will be the engineers choice in the near future. Unfortunately, as of now, the AJP protocol does not support Websockets. See here. Although powerful, websockets may need to wait before release to production environments

In our example we will be working directly with server to client communication. Details about the Tomcat Websocket servlet API are not included. Instead we will use the atmosphere framework to do all the work for us. What's nice about the atmosphere framework, is that it supports both Websockets, and Comet protocols. If set up to support both, you can transition between each protocol seamlessly, without any modifications to your backend code. This demo, is an example of this.

Screen Shot of Demo


Demo Application Uses:
  1. Tomcat 7.0.27 (Required for websocket support)
  2. Atmosphere Runtime
  3. Spring MVC
  4. Web 3.0
  5. Spring Social 
Atmosphere Maven Dependency



Configuring Tomcat for Comet/Websocket support

First, locate and open the Tomcat server.xml file. This can be found in ${CATALINA_HOME}/conf/server.xml. Locate the Connector that configures your HTTP connections. Modify it as such:


Why do we change the protocol?
NIO stands for Non Blocking IO. This will allow Comet transports to be handled specifically as NIO connections. When a connection dies, it tells the server to close off any read/write resources attached to the connection.
We increase the connection timeout due to an existing bug in Tomcat. See here. **This issue is resolved as of Tomcat 7.0.28. We are expecting full websocket support with the .28 release.

Configuring Web.xml
Your web.xml requires a servlet declaration for atmosphere transactions.


The Meteor Servlet defined, will use the Spring DispatcherServlet when adding it as a param-value. Now all Spring Servlet requests are dispatched through the Meteor Servlet. For more details on each param value, click here.

Another note, atmosphere will not recognize your application as Comet supported, unless you add the following to your MET-INF/context.xml file.


The Spring MVC Controller Method


Click here, to view the source of this controller class. Some things to note. When a request is made to the method, it passes in an Atmosphere resource. This resource is attached to the client. It also has a broadcaster. By default all client's share the same broadcaster. What this method does, is schedules the client broadcaster to dispatch to the client, twitter messages every 10 seconds. Interestingly, with atmosphere we don't need to know how the server communicates to the client, we just pass it the text we want the client to see. In our case, JSON formated twitter messages.

Configuring the Client
Atmosphere has it's own javascript file to handle the different Comet/Websocket transport types and requests. By using this, you can set the Spring URL Controller method endpoint to the request. Once subscribed to the controller, you will receive dispatches, which can be handled by adding a request.onMessage method. Here is an example request with transport of websockets.


In this demo, we use jquery and jquery-tmpl to add the new twitter messages to a table. All in all, atmosphere is very useful for quick support of Comet in an existing web application.

If you are trying to add the MeteroServlet to an existing SpringMVC application. I suggest that you first add a subscription controller that handles endpoint subscriptions. Now you can configure websocket and comet Spring methods separately. You could use a context file like, comet-websocket-spring-context.xml to configure your websocket controller and services. Map this file to the MeteorServlet param-name: contextConfigLocation. Let all of your original spring stuff be handled by the original Spring DispatcherServlet you have in the web.xml. Now if you decide to use a different Comet framework later, you aren't required to nit pick out Comet supported Controller methods. Make sure your meteor servlet is set to load on startup first. Now choose a meaningful URL for your Comet and Websocket endpoints. For example: "feeds". In the servlet mapping, set your url-pattern attribute to it: "/feeds/**". This will override your original pattern mapping. Now any requests coming into /feeds will be handled by the MeteorServlet. All other requests are un-effected by atmosphere.

Not all information on Atmopshere setup can be found in this guide. There is still important information on suspending resources, resolving AtmosphereResource's, and configuring that resolver in Spring. All of this is boring, and can be found in the demo project's source code.

I would suggest cloning into the demo project I have created, to get yourself more familiar with the framework.