Home > Atmosphere, Comet, JQuery, Websocket > Using Atmosphere’s JQuery Plug In to build applications supporting both Websocket and Comet

Using Atmosphere’s JQuery Plug In to build applications supporting both Websocket and Comet

Until all Browsers and WebServers properly supports the Websocket protocol, it will be difficult to write portable asynchronous applications. Not anymore, using the new JQuery Atmosphere Plugin which is able to auto-detect which transport (Websocket or Comet) to use based on what the Browser and Web Server support.

Since the Websocket protocol is relatively new, not all web servers and browser supports it which means writing a websocket application always lock your users with a limited set of browsers and web server. For example, as of today, only Jetty 8, Resin 4 and GlassFish 3.1 supports Websocket on the server side,  and  Chrome 4 and Safari 5 on client side. Eventually they may all support the protocol, but it will take a couple of years before it happens. Not to say that Internet Explorer will probably implement a subset of it, or a broken version just to continue what they started with IE 6. On the server side, as I discussed here, it will takes years before the Java Community Process (JCP) comes with a specification for all java side Web server. The good new is we already have a solution for the server side named Atmosphere, which allow the creation of portable Async/Real Time application supporting both Websocket and Comet at the same time.

Does portable library exists on the client side, e.g being able to write application that can use Websocket when available, and fallback/downgrade to use Comet technique (http streaming or long polling)? As far as I can tell, there is no such open source library available today supporting both Websocket and Comet (feel free to point me to them). Not anymore, with the new Atmosphere JQuery Plugin.

Introducing the Atmosphere JQuery Plug In

The  Atmosphere JQuery Plug In easily allow you to write asynchronous and real time applications without the need to wait for Websocket adoption. The Atmosphere JQuery Plug In can be used with any Webserver that support Websocket and/or Comet. The Atmosphere Framework is not mandatory on the Server side, but you will miss something if you don’t use it as I will demonstrate in this blog. That means you can use it with node.js or any existing Comet framework like Grizzly Comet, Jetty Continuation and Servlet 3,0 Async.

Using it with a server side application build on top of Atmosphere allow the plug in to detect what the Web Server support and optimally select Websocket or any  Comet technique.  As an example, you can set the default transport to Websocket, deploy in Jetty 8 and use Chrome to run your application. In that case, the Websocket protocol will be used. Now if you try with Firefox, the Plug In will  downgrade to Comet without any changes required on both client and server side. You can also deploy your application in Tomcat 7, which doesn’t support Websocket and still the application will works without any change. The great news is as soon as Tomcat starts supporting Websocket, your application will still works without requiring any code changes, and will upgrade automatically and use the Websocket protocol.

Writing a PubSub application that supports both Websocket and Comet.

To demonstrate how the Atmosphere JQuery Plug In works, let’s write a simple PubSub application that can support WebSocket and Comet (long-polling and http streaming). If you can’t wait, you can browse the entire code here. On the client side, let’s create a very simple HTML page which allow us to:

  1. Select the topic we want to subscribe to.
  2. Select the transport to use: Auto-Detect, Websocket, Long-Polling or Http Streaming. Auto-Detect means the Atmosphere JQuery Plug In will try to pick the best one for us.
  3. Publish message to the topic we have subscribed to.

The goal here is to write a simple PubSub that you can deploy anywhere, use with any browsers without having to care about the transport used. Something like:

First, the user needs to enter a topic. Next is to pick the transport to use to communicate to the Web Server. By default, let’s use Websocket and fallback to http-streaming in case the browser or the server isn’t supporting Websocket.


document.location.toString() + ‘pubsub/’ + getElementByIdValue(‘topic’),

callback : null

$.atmosphere.request = {transport: getElementByIdValue(‘transport’)});

The subscribe function takes three parameters:

  1. The location of the server application, including the topic value. More details about the server side in the next section.
  2. A function callback which will get invoked when the server is receiving topic’s messages.
  3. A Request object that can be used to configure the Plug In.

The Request object is where you can configure the Plug In. The object default value are:

connected: false,
timeout: 60000,
method: ‘GET’,
headers: {},
contentType : “text/html;charset=ISO-8859-1”,
cache: true,
async: true,
ifModified: false,
callback: null,
dataType: ‘ ‘,
url : url,
data : ‘ ‘,
suspend : true,
maxRequest : 60,
logLevel :  ‘info’,
requestCount : 0,
fallbackTransport : ‘long-polling’,
transport : ‘websocket’

This is where you can configure the HTTP request similar to JQuery.ajax() function, with extra configuration like transport, fallbackTransport and callback. With the above configuration, the Plug In will first try to use Websocket and if  the client of server (or both) isn’t supporting Websocket, will use the fallbackTransport as the second choice.  Next is to define a callback which will be invoked when the server sent us update about our subscribed topic:

function callback(response)

var data = response.responseBody

if (data.length > 0) {

$(‘ul’).prepend($(‘<li></li>’).text(” Message Received: ” + data + ” using transport: ” + response.transport));



The important piece here is the response object, which is defined as:

status: 200,
responseBody : ‘ ‘,
headers : [],
state : “messageReceived”,
transport : “websocket”,
push : [],
error: null

The responseBody contains what the server has just sent us. You can also retrieve some headers depending on which transport is used, if there is an error, etc. The push function is a key piece here as it allow you to publish message to the Web Server message. The Plug In will either re-use the current transport to push messages to the Web Server, or open a new one if the current transport doesn’t support it. All of this done magically by the Plug In. For our sample, the push function is defined as:

response.push(document.location.toString() + ‘pubsub/’ + getElementByIdValue(‘topic’),


$.atmosphere.request = {data: ‘message=’ + getElementByIdValue(‘phrase’) })

This function will be invoked every time you click on the “Push Message” button.

Make it fun

As a try, you can deploy the application on Jetty 8, use Chrome and Firefox to see how it works (download here). You can switch transport on the fly be selecting the transport using the drop down menu. If you use Chrome, all transport will works where Firefox fake Websocket (using the default fallbackTransport value). Do the same on Tomcat and now Chrome will still works event if you set the transport to Websocket.

Humm…what about the server side?

Without going into the details of how to write an Atmosphere application (download the white paper or search this blog), the server side for this sample JUST consists of:



public class JQueryPubSub {

private @PathParam(“topic”) Broadcaster topic;

public SuspendResponse<String> subscribe() {

return new SuspendResponse.SuspendResponseBuilder<String>()



.addListener(new EventsLogger())



public Broadcastable publish(@FormParam(“message”) String message) {

return new Broadcastable(message, “”, topic);



The mapping is simple:

  • Invoking $.atmosphere.subscribe will invoke the subscribe() method on the server side. This method will tells Atmosphere to suspend the connection and create a topic (Broadcaster). The Broadcast is like a queue. As soon as you offer a message to it the message will be sent to all the subscriber of that queue. In our case it means all browser connected to that topic.
  • Invoking response.push will invoke the publish() method on the server side. The value will be broadcasted to all subscribed connections, independently of the transport used.

Simple, is it 🙂 Did you noted that there is no mention of Comet or Websocket on the server side? With the Atmosphere Framework, you write an application without having to care about it.

For any questions or to download Atmosphere JQuery Plug In, go to our main site and use our Google Group forum (no subscription needed), or follow the team or myself and tweet your questions there! You can also checkout the code on Github. Or download our latest presentation to get an overview of what the framework is.

Categories: Atmosphere, Comet, JQuery, Websocket
  1. Drew
    June 15, 2010 at 4:20 pm

    You mention that there are no open source libraries for client-side… have you heard of socket.io?

    And for server side sockets, have you heard of node.js? It’s kind of kicking butt right now.

    • June 15, 2010 at 4:23 pm

      @kirbysayshi Yes, and this Plugin also works with node.js (as I said in the text :-)).

  2. Guillaume
    June 18, 2010 at 9:29 am

    Hello Jean-Francois,

    First of all, congrats for your atmosphere framework! I am using the meteor servlet and it is very useful and easy to use.

    I checked your jquery.atmosphere.js code (I did not test it) and I noticed that the activeX iframe technique explained here is not used for IE.

    Do you plan to add it in this plugin ?


  3. June 18, 2010 at 10:41 am

    Salut Guillaume,

    Thanks! IE works with both technique, e.g long-polling and http streaming with the sample described here. What makes you think it will not works (or what should be improved)? Let’s continue the discussion on users@atmosphere.dev.java.net if you can. Thanks for the feedback!!!

    — Jeanfrancois

  4. Alexander
    June 24, 2010 at 11:33 am

    Bonjour Jean-Francois.

    I tried to make it through the (downloadable) demonstration war, but failed – as the jquery subdirectory isn’t complete (some files are missing). So I set up the project by hand and installed 0.6 components into maven repo, enabled comet on GF v2 (which I am using) and finally managed to subscribe to a topic!

    So far so good! But when I publish a message, my glassfish would say:

    at org.apache.coyote.tomcat5.CoyoteRequest.setAttribute(CoyoteRequest.java:1806)
    at org.apache.coyote.tomcat5.CoyoteRequestFacade.setAttribute(CoyoteRequestFacade.java:581)
    at org.atmosphere.cpr.DefaultBroadcaster.push(DefaultBroadcaster.java:287)
    at org.atmosphere.cpr.DefaultBroadcaster.push(DefaultBroadcaster.java:260)
    at org.atmosphere.cpr.DefaultBroadcaster$1.run(DefaultBroadcaster.java:209)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)

    What’ up? Can you help me?

    Best regards,


    • June 24, 2010 at 2:08 pm


      Can you try the following war file. I suspect the .war linked in the blog was broken on v2.

      * http://is.gd/d254B

      I’ve just tested with GlassFish v2 and it works for me.


  5. June 30, 2010 at 4:22 am

    nice script

  6. July 7, 2010 at 11:59 am

    Thanks for the cool project. I have been able to integrate it in my app but the WebSocket never worked for me under Jetty 8M0. I’ve been testing the provided sample since 0.6.0-SNAPSHOT until today and it never worked using the socket transport in Chrome 5, Chromium 6 or Safari. Any ideas why?

    • July 7, 2010 at 1:59 pm

      Hum that’s strange. The sample are tested against Jetty 8 M0 with Chrome 5 and Safari 5. Have you tried 0.6-SNAPSHOT or 0.6 final? 0.6.0-SNAPSHOT is very old and wasn’t updated as we switched to 0.6-SNAPSHOT.

      Are you seeing exception on the client or server side log? If you can, let’s continue the discussion users@atmosphere.dev.java.net so we can help making the sample working. Thanks!

  7. September 8, 2010 at 1:16 pm

    wow great!

  8. alfred
    November 11, 2010 at 5:30 am

    Very good :P. But how about flash and json-p just like socket.io has?

    • November 11, 2010 at 1:21 pm


      for flash: http://is.gd/gd7d0

      JasonP is something I will look at for the Atmosphere 0.8 timeframe. Any contribution welcomed!!


      — Jeanfrancois

  9. Jack Parker
    November 23, 2010 at 9:41 pm

    FYI, the links for JQuery Plugin on the Atmosphere main page appear to be broken.

    I was able to find downloads at:

    But I’m unsure which is the actual “Atmosphere JQuery PlugIn”.

  10. Jack Parker
    November 23, 2010 at 9:59 pm

    Ok, I find jquery.atmosphere.js in the .war file; Thanks.

  11. venkatesh
    February 9, 2011 at 2:59 pm

    In this example, where the server URL is specified.
    Please let me know as soon as possible.


    • February 9, 2011 at 3:01 pm

      In the subscribe() method, you set the server url there.

      — Jeanfrancois

      • October 31, 2011 at 7:21 am

        In this example, where the server URL is specified.
        Please let me know as soon as possible.


  12. Ivan Memruk
    March 8, 2011 at 7:35 pm

    sorry for posting it here Jeanfrancois, but there’s a problem with the jQuery plugin.
    it seems to honor the maxRequest limitation for long-polling connections, so after a while they just stop re-requesting.
    have a look around line 120 in jquery.atmosphere.js

    • March 11, 2011 at 9:19 pm

      OK will be fixed next release. Thanks!

      • maurice
        June 22, 2011 at 5:35 pm

        A question: even with the hugely enhanced scalability, we might still hit scenarios where clustering is needed.
        is websocket reverse proxy friendly ? I have read it is not

  13. Mahender
    March 17, 2011 at 11:05 am

    Hello Jean-Francois,

    As I mentioned in the email sometime back, you said you’ll address cross domain issue in the 0.8 release. so, Are you addressing the cross domain issue in the 0.8 release? please try to address it.

    You guys are doing great Job.


  14. May 7, 2011 at 3:41 pm

    Just wanted to say that Atmosphere and the JQuery plugin rocks, we use them in several of our projects and are really thankful for the great work!

    Keep Atmosphere evolving, it’s a great idea!

    • Thomas Pham
      May 21, 2011 at 11:27 am

      Dominique Guinard :
      Just wanted to say that Atmosphere and the JQuery plugin rocks, we use them in several of our projects and are really thankful for the great work!
      Keep Atmosphere evolving, it’s a great idea!

      Hello Misterdom,

      I agree ! Atmosphere rocks ! I’m using it for a while and Jfarcand and their team are doing a great work ! merci et bravo !

  15. kiRach
    June 14, 2011 at 10:31 am


    How I must to configure Glassfish 3.1 to deploy this example properly? Enable grizzly support, enable websocket support or anything else?

    Thank you.

    • June 28, 2011 at 9:04 pm

      Just enabled Comet and Websocket. Google or go to Stackoverflow to find how (well documented there).


  16. maurice
    June 22, 2011 at 5:41 pm

    maurice :
    A question: even with the hugely enhanced scalability, we might still hit scenarios where clustering is needed.
    is websocket reverse proxy friendly ? I have read it is not

    Actually, here is stated.

    here :

    Apparently it has to do with the spec of Websockets implemented. Which version of the websocket specs. is implemented in Atmosphere ? I need it to emit near real time notifications for thousands of users, so I need to work for HAproxy, for example.

    In any case, impressive work Monsieur Arcand! 🙂 Merci beaucoup!

    • June 28, 2011 at 9:03 pm

      Atmosphere use what’s implemented under the hood by the container. Currently GlassFish 3.1 and Jetty 7/8 are supported WebSocket server 🙂 Thanks!

  17. July 5, 2011 at 1:20 pm

    Hi every one, at start i would like to apalogise for my english. I have a question about atmosphere. We developing application where user have to be notify about new messages (message is for single user, not all of them) in real time. Something like messages on facebook. I readed Atmosphere Framework White Paper, but i dont know if could change brodcatster path.

  18. July 9, 2011 at 4:42 pm


    First off, let me clarify that I am not a Java developer. However, I’m interested in the fallback to Comet of this plugin. However, as for my application, I would only need the client side and would appreciate to know how to make it work with my ejabberd server (a XMPP server written in Erlang).

    • July 9, 2011 at 5:59 pm


      the fallback will works between Websocket and Comet for sure, but the plugin expect some “script” from the server as it use it own protocol. I can explain how the protocol works, but it may be a little bit more works for you to implement it.


  19. August 11, 2011 at 5:38 pm

    I am curious to know about peoples experience. Is anyones using atmostphere on the server side ( if so which app server ) and also the jquery plugin in production ?.

    Also a search for ‘atmosphere’ results in 0 hits at http://plugins.jquery.com/ 🙂

  20. starkingwx
    August 24, 2011 at 7:31 am

    I’m using jquery.atmosphere.js in IE9, and I find that the callback function set in the $.atmosphere.subscribe() seems not invoked.
    The connection with web server has been established and I can see the response of the subscribe in IE9 developer tool.
    Have you ever encountered the same problem?

  21. August 30, 2011 at 3:31 pm

    Hi Jeanfrancois,

    I have troubles with using of your examples. Because I use PrimeFaces and can’t use Jersey! Please remove this line


    from the method protected boolean detectSupportedFramework(ServletConfig sc) in AtmosphereServlet.java. This line doesn’t allow to use Jersey. The second reason to remove this line is the fact that PrimeFaces doesn’t use Atmosphere anymore (and doesn’t have Handler for that) in upcoming releases.

    Thanks a lot in advance!

  22. August 30, 2011 at 6:47 pm

    Hi, Thanks for a great framework at first!

    I didn’t understand why have you removed my prev. comment. I just wanted to tell you very polite that this code in AtmosphereServlet

    // If Primefaces is detected, never start Jersey.
    // TODO: Remove this hack once properly implemented in PrimeFaces
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    try {
    return false;
    } catch (Throwable ignored) {

    makes impossible to use Atmosphere, Jersey and PrimeFaces (at least in 2.2.1 vers.) I’m using this combination and had to overwrite AtmosphereServlet in order to use Jersey (Jersey environment got not instantiated). Any better suggestions are welcome.

    I allow me to report yet another issue (sorry). JQuery based sample (checked out from Github) doesn’t work if you start maven jetty:run (unpackaged war, but running jetty:run-war is ok I think). The reason is missing config. parameters in web.xml. I post these here.

    <param-value>… your package here … </param-value>

    Many thanks for your attention.

  23. Max
    September 30, 2011 at 3:38 pm

    Hi, impressive.
    But I did’t understand if the jQuery plugin works only with atmosphere-jersey or with other modules as well (atmosphere-runtime). Could you clarify?

    • October 6, 2011 at 11:07 pm


      The PlugIn works with any Atmosphere’s modules.


      — Jeanfrancois

  24. Mick
    October 19, 2011 at 7:38 am

    I follow your sample for my application. I Use atmosphere 0.7.2, Chrome, your plugin jquery and Jetty 7.1, but when it seems that websocket is never user.
    When I look at my javascript console, I always see :
    “Websocket failed. Downgrading to Comet and resending ”
    Have you ever seen this ?

    • October 19, 2011 at 3:16 pm

      Salut, 0.7.2 only support Jetty 7.1.x … update to 0.8.0-RC1 or RC2 and all Jetty version will works. Thanks!

      • Mick
        October 24, 2011 at 9:44 am

        Thanks for your answer.
        I already use Jetty 7.1 (more precisely 7.1.6.v20100715) and Chrome but I see this message and my application use Comet instead of WebSocket. I tested 0.8.0-RC1 but I have the same behavior. I didn’t test with 0.8.0-RC2, where can I get it ?
        Maybe it’s related, but I see this message in my logs :
        “[ERROR] Unexpected state. ContainerResponse cannot be null. The connection hasn’t been suspended yet”

        I don’t know if this is important because everything works fine anyway.

      • October 24, 2011 at 11:07 am

        Mick, take a look at:


        Let me know how it goes. I did test using Jetty 7.1.6.

        — Jeanfrancois

  25. kk
    October 21, 2011 at 6:51 pm

    Jean, cool project.. it works perfectly for me in Tomcat and j2ee preview.. every time it is using streaming,…. but when I use glassfish.. it fails with “8080WebSocket is closed before the connection is established.”. Let me know if I am missing some config

    • October 21, 2011 at 7:12 pm

      GlassFish isn’t up to date with WebSocket and that’s why it fail (the issue is with GlassFish). Go to their mailling list, I think you can patch Glassfish to make it work until their next release.


      — Jeanfrancois

  26. spring-user
    November 9, 2011 at 1:55 pm

    What does it mean: Broadcaster [id] doesn’t have any associated resource ?

    • November 9, 2011 at 3:07 pm

      I need more information, but is sound like there is no longer connection suspended when broadcast#broadcast gets invoked.

  27. March 14, 2012 at 11:51 pm

    Atmosphere is great, thanks for sharing it!

    While playing with it I noticed the following issue and would like to have your impression of it. In its most simple format, the code does the following:

    1. Page loads and registers for pubsub
    2. A jquery Ajax POST is placed to the server (JBoss 7.1)
    3. Anytime later, when a button is pressed another jquery Ajax call is placed to the server and ends-up broadcasting a message.
    4. The Atmosphere jquery API receives the message and calls the callback method

    The problem is that the Atmosphere API upon receiving the message somehow resubmits the previous Ajax POST.

    • March 15, 2012 at 7:51 pm

      Daaaa!!! Atmosphere works just fine.

      Forget about this… the post method was on:

      $(‘#item’).ajaxComplete( function() {

      $.ajax… // Post method


      So, every-time any other ajax calls completes, including atmosphere calls, the post method was being called once again.

  28. Elangovan S
    March 21, 2012 at 3:59 am

    Hi Jeanfrancois, I have built a prototype using Atmosphere framework. I have been trying to couple of different sample projects, one with atmosphere-pubsub-xmpp and another with atmosphere-jquery-pubsub.

    I use Chrome browser 17.0.963.79. When I select “autodetect” the transport, it fallback onto Http streaming protocol.

    Browser Log shows:
    Invoking 1 callbacks
    response.state: messageReceived
    response.transport: streaming
    response.status: 200

    So I have few questions:

    1) I need to work with WebSocket. Do I need to something different at the server side to make WebSocket as my transport?

    2) How do I use ws:// protocol using Atmosphere?

    3) Are there any support for wss:// in Atmosphere?

    Thanks. appreciate your help.

  29. August 10, 2012 at 8:24 am

    Hi, the white paper link (https://atmosphere.dev.java.net/atmosphere_whitepaper.pdf ) is broken.

  30. August 10, 2012 at 8:42 am

    I have downloaded and deployed war (atmosphere-jquery-pubsub-1.1-20120728.221337-3.war) in Tomcat 7.0.29 and when I click on publish my firebug shows “The requested resource (/atmosphere-jquery-pubsub-1.1-20120728.221337-3pubsub/myTopic) is not available”. I choose transport as autodetect. This seems to be happening for both Firefox and Chrome. Is there anything else which needs to be done for Tomcat ?

  31. August 20, 2012 at 7:05 pm

    Very cool read, thanks for sharing!

  32. Sushant
    December 18, 2012 at 9:54 am

    I just wanted to know how to specify specific topic while using @ManagedService annotation. For example, if I want to subscribe to “/chat/”, then using ManagedService how to go forward.
    @ManagedService(path = “/chat/”). The is a variable I need to pass from js.

    Thanks for you help.

    • Sushant
      December 18, 2012 at 9:56 am

      Sorry, it seems the special characters are not allowed in this forum..
      I’m just re specifying my question:
      I just wanted to know how to specify specific topic while using @ManagedService annotation. For example, if I want to subscribe to “/chat/username”, then using ManagedService how to go forward.
      @ManagedService(path = “/chat/username”). The username is a variable I need to pass from js.

    • December 18, 2012 at 1:13 pm

      Please post your question on the mailing list

  33. March 29, 2013 at 2:03 pm

    Wow that was odd. I just wrote an incredibly
    long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing
    all that over again. Regardless, just wanted to say fantastic blog!

  1. June 24, 2010 at 8:53 pm
  2. July 2, 2010 at 2:51 pm
  3. July 9, 2010 at 9:23 pm
  4. July 20, 2010 at 5:50 am
  5. October 1, 2010 at 4:06 am
  6. October 7, 2010 at 2:15 am
  7. October 25, 2010 at 11:58 pm
  8. November 8, 2010 at 10:06 pm
  9. November 12, 2010 at 12:57 am
  10. February 3, 2011 at 9:42 am
  11. May 7, 2011 at 3:59 pm
  12. June 29, 2011 at 12:30 am
  13. November 7, 2011 at 5:15 pm
  14. February 19, 2012 at 10:16 am
  15. February 29, 2012 at 3:34 am
  16. March 2, 2012 at 3:05 am
  17. May 28, 2012 at 11:32 pm
  18. June 5, 2012 at 12:57 pm
  19. September 24, 2012 at 11:07 pm
  20. February 28, 2015 at 9:19 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: