Ajax Dojo Comet Tutorial

EDIT: This tutorial is for an old version of dojo / comet, and it will not work in a recent version!

Markus Holzmann, an intern at Profactor of my fellow colleague Philipp Hartl, had the opportunity to experiment with Ajax during his job. He wrote a tutorial about how to push events from the server to the client. For example, display popup messages on all browsers at the same time (see screencast in full resolution here):





Read on how Markus did this:

Cometd Hello World

I’ve read Chris Bucchere’s Say Hello World to Comet and built an application based on this using a more current version of Jetty (version 6.1.5) which I embedded into a Tomcat v5.5 Server. For the developing I used Eclipse 3.2.

Start your Engines

At first you have to get the server running. As I mentioned I embedded Jetty into a Tomcat server. Therefore you have configure the libraries:

  1. Add the packages org.mortbay.cometd and dojox.cometd to your source folder and delete the client package in the org.mortbay.cometd package.
  2. Add jetty-util-6.1.5.jar, jetty-6.1.5.jar and servlet-api-2.5-6.1.5.jar to your build path.
  3. Copy the jetty-util-6.1.5.jar file into the /lib folder in the WEB-INF directory.

Replace the existing servlets in your web.xml – file in the WEB-INF – folder with the following servlets:

<servlet>
  <servlet-name>cometd</servlet-name>
  <servlet-class>org.mortbay.cometd.continuation.ContinuationCometdServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>cometd</servlet-name>
  <url-pattern>/cometd/*</url-pattern>
 </servlet-mapping>

For the project I used the dojo toolkit (version 0.4.3) which has an integrated COMETd class that makes it easy to build comet projects. Download it and add it to your WebContent folder.

When you’ve done all this, the hardest piece of work for this program is already done.

Hack the Code

Now you can implement the code for the client side: You need a HTML file with a button on it. The code for this looks like this (download):

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

      cometd.init({}, "cometd");

      cometd.subscribe("/hello/world", false, "publishHandler");

      publishHandler = function(msg) {
        alert(msg.data.test);
      }
    </script>
  </head>
  <body>
    <input type="button"
       onclick="cometd.publish('/hello/world', { test: 'hello world' } )"
       value="Click Me!">
  </body>
</html>

Line by line, the above bold code works like this:

  1. In the line
    <script type="text/javascript" src="../dojo.js"></script>

    you integrate the dojo toolkit into the project.

  2. To activate the cometd class of dojo:
    dojo.require("dojo.io.cometd");
  3. Connect the server with the client:
    cometd.init({}, "cometd");
  4. Here we say what to do when there is a subscribe event:
    cometd.subscribe("/hello/world", false, "publishHandler");
  5. Last but not least, the publishHandler function serves as the callback function, which uses alert to show a simple message box:
    publishHandler = function(msg) {
      alert(msg.data.test);
    }

Give it a Try

When you load the HTML file now, you can click on the button and an alert box saying hello world will appear:

The reason for this is that when you click the code

cometd.publish('/hello/world', { test: 'hello world' } )

is executed which publishes a text on the channel with the id /hello/world.

The funny thing is that this is able to run on any number of browsers. Everytime when a client clicks the button, on all browsers that view this page the alert box is shown. (See screencast above).

Pushing Data from Server to Client

You can also add serverside code to trigger an event. I wrote a JSP file with the following code:

<%@page import="java.util.*"%>
<%@page import="dojox.cometd.*" %>
<%
Bayeux b = (Bayeux)getServletContext().getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);
Channel c = b.getChannel("/hello/world",false);

Map<String,Object> message = new HashMap<String,Object>();
message.put("test", "jsp: hello world");

c.publish(b.newClient("server_user",null),message, "new server message");
%>

When this page is loaded, an alert popup appears at the page saying jsp: hello world.

That’s it. Happy hacking!

26 Responses to “Ajax Dojo Comet Tutorial”

  1. Ajax Dojo Comet Beginner Tutorial &laquo; Lean Austria on August 21st, 2007 9:05 pm

    [...] 21. August, 2007 During the last month our intern Markus helped us tracking brand new AJAX technology. He investigated some application scenarios. As a byproduct he wrote a small Ajax Dojo Comet Tutorial. Martin Ankerl provided his programming related blog for publishing. Thanx Markus and Martin! [...]

  2. Roy van Rijn on August 25th, 2007 9:38 pm

    Very nice, I think Comet-type applications really have a lot of potential. I’ve heard the G-Talk application inside Gmail.com uses a Comet-connection for messaging, works like charm.

    The problem is getting the webservers to adopt the idea. We really need to get a standard way of doing open-connections. Time for JEE6?

  3. Roy van Rijn on August 27th, 2007 5:39 pm

    The only problem with Comet is that you keep the connections open for a elanged time. This could cause serious problems with performance when you have multible users. Keeping the connections open also has downsides caching etc on the browser of the end-user.

    The real next big thing ™ will probably be offline-clients, something like Web Start or Adobe Apollo.

  4. Martin Ankerl on August 29th, 2007 8:16 am

    Im not so sure about offline clients. I think the next big thing will be something like Erlang, programming languages designed for concurrent development, e.g. when you use Erlang for a webserver it should not be such a problem to keep a very large number of connections open. The Apache vs. Yaws benchmark looks interesting: http://www.sics.se/~joe/apachevsyaws.html

  5. Dylan Schiemann &#187; Blog Archive &#187; cometd tutorial on September 14th, 2007 4:24 pm

    [...] There&#8217;s an easy to follow Cometd tutorial available that shows how to get up and running with the Jetty version of Cometd. The examples use Dojo version 0.4.3, but the syntax changes necessary to make this work with Dojo 0.9 are straightforward. [...]

  6. comet on October 8th, 2007 8:54 am

    I am struggling with tomcat comet api, but im not able to do it…

  7. tatlar on October 29th, 2007 10:19 pm

    I have installed Jetty and am trying to get this example to work. The cometd examples that ship with Jetty work fine (chat and echo), however, this application does not seem to work. I keep getting the 404 error that the following file does not exist.

    http://www.myserver.com:8080/cometd/examples/dojo/dojo/io/cometd.js

    Any ideas?

    Thx in advance.

  8. benny on November 6th, 2007 5:49 pm

    Hi Martin,
    I have some problems to config this project:
    How did you embedded the jetty into the tomcat?
    “Add the packages org.mortbay.cometd” , what is the full path of ‘ org.mortbay.cometd’.
    thanks benny

  9. Martin Ankerl on November 7th, 2007 8:05 am

    Hi tatlar & benny, sorry but I cannot help you here. This article was written by a student, not me, and he is not here any more :-(

  10. Ethem Yuksel on November 8th, 2007 6:53 pm

    I have successfully installed the stuff into my workspace and run it.But when i debug it, i realized that a server request has been sent by the waiting clients after receiving message.What is the difference between asynchronous polling and comet in that case?Nothing should be sent to the server after first subscribing.
    Regards…

  11. Bamdad on December 24th, 2007 6:13 pm

    Hi,can we use PHP as comet server?

  12. Koen Tielens on February 20th, 2008 9:13 pm

    How to run Jetty under Tomcat?

    Take the jetty-6.1.7\webapps\cometd.war file and drop it in the Tomcat 6 Webapps directory -> The web.xml file under WEB-INF gives a lot of info.

    This just works!

  13. Gustavo on February 27th, 2008 7:40 am

    I configured my workspace and made that the Client side run fine.

    But i couln’t make that server side code run. Some idea?

  14. erkulas on May 11th, 2008 3:12 pm

    I played with this a little bit. Have’nt got it working fully yet but … .

    benny – org.mortbay.cometd can be found in jetty source distribution in a folder “./jetty-6.1.9_src/contrib/cometd/bayeux/src/main/java/org/mortbay/…” and in “./jetty-6.1.9_src/contrib/cometd/api/src/main/java/dojox/cometd”

    tatlar – this tutorial uses old dojo release. In current realease (1.1) cometd is in different location. Hence the code is a bit different:
    —————————————–
    dojo.require(“dojox.cometd”);
    dojox.cometd.init({}, “cometd”);
    dojox.cometd.subscribe(“/hello/world”, false, “publishHandler”);
    —————————————–

    Now I have next JS error with dojo “this.url.match is not a function. dojo.js (line 136)” . If anybody has a clue about this I would appreciate it.

  15. Kalaiselvi on May 14th, 2008 8:38 am

    My client side is running successfully but i can’t make my server side code run.

    Can anyone help please…

  16. eli on May 16th, 2008 2:11 pm

    I also get this JS error with dojo “this.url.match is not a function”.

  17. Marc on June 23rd, 2008 3:52 pm

    I have developed a small non-blocking Java server which can handle this type of high socket concurrency and serve async responses!

    http://rupy.googlecode.com

    Check it out!

  18. iGeek » Comet: El Ajax inverso on July 15th, 2008 9:17 pm

    [...] en wikipedia (ES) Despues de Ajax, Comet Ajax Dojo Comet Tutorial by Martin Ankerl How to implement COMET with PHP [Zeitoun.net] Comet with PHP Comet paso a paso: pizarra [...]

  19. Hale on July 21st, 2008 3:05 pm

    Hello, I try to realize this example, but it doesn’t work. Nothing happens when I click on the Button. I put an alert into the code after ” cometd.init({}, “cometd”); ” and it isn’t shown on the screen. What means “cometd” inside the breakets. And concerning the code in the web.xml:

    org.mortbay.cometd.continuation.ContinuationCometdServlet

    is it a path to the ContinuationCometdServlet or what do I have to write. Hope anyone can help me… Thank’s

  20. Maxime on August 12th, 2008 2:39 pm

    Hello,

    For my internship, I have to work on a comet implementation (started by a former student) that uses the cometd API and a tomcat server (with the Tapestry framework). What has been done until now works pretty fine : the long polling request enables the server to send back a response to the client when it wishes.

    However I noticed the following : during the long polling, if the client makes requests to the server, they will use other sockets than the one opened for the long polling. In short, it builds up another connection per new request.
    Another thing, when the server pushes data back to the client, it uses the response to the long polling request. That may be the correct way for it to work, but it implies that the maintained connection ends (since a response is sent back) and that the client has to start again a new long polling request.All this causes the corresponding sockets to close and to open again.

    So my question is the following …. well, there are two actually :
    - Can the client use the connection built for the long polling in order to sent data to the server, instead of having to build a new temporary connection just for that new request ?
    - Can the server send back data without closing the connection ?

    I spent some time analysing packets with wireshark but i’m quite new to comet so I’m sorry if my questions appear obvious, or completely dumb.
    I thank anyone that could give me some information on this.

    Thank you.
    Maxime – France

  21. Integration Patterns : ESME on October 26th, 2008 10:06 am

    [...] messages based on tag-based filters. An integration via javascript-based scripts (for example, dojo) would allow use in most browser-based [...]

  22. Sally on November 30th, 2008 4:08 pm

    Hi, I’m trying to get this example to work, and I’m having trouble. I have successfully installed tomcat and jetty, but I’m not sure which WEB-INF to put the jar file into and which web.xml file to modify – there are about 20 different WEB-INF locations and about 7 different web.xml files on my computer. I got dojo up and running, but without the comet enabled server, when I click on the click me button, nothing happens.

    Thanks,
    Sally

  23. Shared Tutorials » Blog Archive » Ajax Dojo Comet Tutorial on January 11th, 2009 8:59 pm

    [...] Ajax Dojo Comet Tutorial [...]

  24. ESME Mention in Keynote at “Open Source Meets Business” Conference : ESME on February 8th, 2009 10:05 am

    [...] at “Open Source Meets Business” (OSMB) conference. Take a look at Mark’s blog about his presentation (slides are here). The slides are interesting, because they describe the [...]

  25. Using Server Push (aka Reverse AJAX) « When IE meets SE… on March 3rd, 2009 1:51 am

    [...] 1. Web 2.0 Techs – Comet (Reverse Ajax, Server-side Push) 2. Direct Web Remoting + Reverse AJAX 3. Ajax Dojo Comet Tutorial [...]

  26. Nick on March 13th, 2009 6:55 am

    I know this is an old thread, but I found this via google and it led me into a few hours of frustration, so I thought I’d post an update.

    I’ve posted at http://www.dojotoolkit.org/forum/dojox-dojox/dojox-support/hello-world-cometd#comment-22834 with why the url.match function generates an error, and roughly how to fix it. This tutorial is for an _old_ version of dojo and _will not work_ as it stands with today’s release.

    Sally: your wep application project should only have one WEB-INF folder. If you don’t know which WEB-INF folder you should put resources into, perhaps you should return to basic J2EE tutorials for your platform of choice? I’m using Eclipse and Glassfish, and my GlassfishTest project in Eclipse has a GlassfishTest/WebContent/WEB-INF folder, in which there is a ‘lib’ folder, in which I put my cometd-api, cometd-bayeaux, jetty-util and so on jar files. (the jetty one seems necessary for a reason I’ve yet to fully figure out, it seems out of place as I’m not deploying to Jetty!)

    Other than the use of an obsolete dojo api, a very useful tutorial :)

Leave a Reply