Comet using Jetty and Dojo

The term comet was created by Alex Russell (dojo). There are several different implementations out there. Jetty, Tomcat and Glassfish (for instance) offer support for comet. The Dojo Toolkit provides the client side bits of it. I decided to play with comet, using Jetty and Dojo. I did download the latest, greatest Jetty (6.1.7). This distribution already contains the cometd APIs and a demo project (in $JETTY_HOME/contrib/cometd). The demo is easy to launch, just call

mvn jetty:run

and the nice maven2 plugin does the rest. The demo contains a simple chat and an echo example. I wasn’t interested in chatting🙂 or echo. Doing some google searches, I found this (outdated) comet demo blog. It does what I was looking for. Pushing data from the server to the client.

I created a very simple client HTML page:

<html>
  <head>
    <script type="text/javascript" src="pathToDojo.js"></script>
    <script type="text/javascript">
      dojo.require("dojox.cometd");
      dojo.require("dojox.cometd.timestamp");

      //a callback function
      function callback(msg)
      {
        alert(msg.data.payload);
      }
      //cometd servlet is registered at /cometd
      dojox.cometd.init("/cometd");
      //subscribe to message channel; add the callback
      dojox.cometd.subscribe("/ping",callback);

    </script>
  </head>
  <body>
A trivial comet client page
  </body>
</html>

What does this do? Not much. But enough:

  • registering the required JS files
  • defining a callback function
  • initialize the cometd, pointing to Jetty’s ContinuationCometdServlet URL
  • subscribing to a channel and register the callback function

The callback (callback()) is called, when ever the client receives a message, from the server.

On the server, I created a (simple) ServletFilter, to actually send a message to the “/ping” channel. Here is the doFilter() method:

public void doFilter(
  ServletRequest request,
  ServletResponse response,
  FilterChain chaing)
  throws IOException, ServletException
{

  Bayeux bayeux = (Bayeux) filterConfig.getServletContext()
    .getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);
  Channel channel = bayeux.getChannel("/ping", true);

  Client client = bayeux.newClient("client",null); 

  Map<String,Object> message = new HashMap<String,Object>();
  message.put("payload", new java.util.Date());

  channel.publish(client ,message, "messageId");
}

When ever the filter is called, It creates a message and publishes on the “/ping” channel.I tested the demo the following way:

  • opened the HTML file via IE (was served via jetty)
  • opened the HTML file via FF (was served via jetty)
  • opened the Filter URL from my iPod

What happened was this:

  1. doFilter() was executed and the message was published on the channel.
  2. both clients were notified and the callback was executed, which simple shows the “payload” in an JS alert().

This is a simple, but interesting demo.

Now I tried to queue multiple message after some seconds to the clients. I modified my server side code to have a simple loop:


for(int i = 0; i < 10; i++) { message.put("payload", new java.util.Date()); channel.publish(client ,message, "messageId"); try { Thread.sleep(5000); } catch (InterruptedException e) { ... } } ...[/sourcecode] Sure, that isn't the best way to push multiple message to the client, but it worked. By doing some more research, I noticed that Apache's ActiveMQ has ajax support. That would be a nice extended way to integrate a real messaging system to the comet way of doing things.

Please note, that I used the ServletFilter only to emulate a “message driven” architecture.

In a real application, usually your client get’s updated by an event, and not (only) b/c a Servlet(Filter) was executed.

I am sure, that using comet technology you can create pretty cool web 2.0 / mashup applications.

Howdy!

Posted in ajax, comet, dojo, java, jetty, web²
9 comments on “Comet using Jetty and Dojo
  1. […] Matthias Wessendorf Comet using Jetty and Dojo […]

  2. Bernd says:

    Why so complicated. I visited OOP this year and was surprised by a new webframework called seaside
    (http://www.seaside.st) and how easy they were able
    to build webapps and using Comet:
    (http://www.lukas-renggli.ch/blog/oop08-slides, contains a link to a video).

    We need more of these ideas in JSF.

    Bernd

  3. matthiaswessendorf says:

    Do you mean the smalltalk web-framework ? That is around since a while. I never really checked it (like many others, IMO).

    will check the video later.

  4. Conan says:

    Hi,

    I am newbie to Cometd. I tried to run your example but unfortunately it is unsuccessful. The problem comes with the line:
    Bayeux bayeux = (Bayeux) filterConfig.getServletContext()
    .getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);

    In this case, bayeux object is returned with NULL value. I guess the tough problem comming from the web configuration file. Indeed, I do not know how to set the value for the attribute named Bayeux.DOJOX_COMETD_BAYEUX. Do you have any idea?

    Thanks,
    Conan.

  5. spasham says:

    Do you have a war ball to look at the code?

  6. florin says:


    org.mortbay.jetty.servlet.ManagedAttributes
    org.cometd.bayeux,dojox.cometd.bayeux

  7. Hans says:

    Have you solved the problem? I’m using Jetty release 6.1.12 and keep getting the same error as Conan. (bayeux object is returned with NULL).

    I already got:

    org.mortbay.jetty.servlet.ManagedAttributes
    org.cometd.bayeux,dojox.cometd.bayeux

    in my web.xml

    Any clues?

  8. Umar says:

    Can I please get the complete server-side code for this example? I tried to put the doFilter method in simple servlet only to get errors.

    Please, can the world be perfect for once!

    • Ranga says:

      No the world cannot be perfect but I’ll start up a blog page with some code of a complete server that actually works with Embedded Jetty 6.1

      Thanks to Mathias Wissendorf for a good starting point.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: