Archive

Archive for February 2, 2007

gCometd: Introducing the Cometd framework and its Bayeux protocol support in Grizzly

The Cometd framework and its Bayeux protocol is now supported starting with Grizzly 1.0.11 and GlassFish 9.1 b35. In this first blog, I will talk about the gCometd implementation, how to enable it and describe a DOJO cometd enabled example.

cometd.jpg

The Cometd framework is defined as:

Cometd is a scalable HTTP-based event routing bus that uses a push technology pattern
known as Comet. The term 'Comet' was coined by Alex Russell in his post 
'Comet: Low Latency Data for the Browser'. The letter d is for 'Daemon', as described 
by Answers.com, Daemon is a program or process that sits idly in the background 
until it is invoked to perform its task. Cometd consists of a protocol spec called 
Bayeux,javacript libraries (dojo toolkit), and an event server.

I don’t want to go over the details of what is the Bayeux protocol, as they already exists excellent descriptions of it here, here and here. But in short (from Alex Russel description):

Bayeux is a JSON-based protocol for clients to register interest in events 
and for servers to deliver them in a more timely fashion than Ajax-based polling
 allows. The goals of the Bayeux spec so far have been to:

    * make event delivery fast
    * keep it simple
    * provide extension points in the protocol

What I find interesting with Cometd and Bayeux is the fact that if an application is build using only DOJO (or Ajax component), the application can be deployed in any server that supports the Bayeux protocol. This looks like very promising!. Since Grizzly already supports Comet via its Asynchronous Request Processing(ARP) extension, I’ve decided to read the spec and try to see if it was possible to implements it. Well, I know it was possible since Jonas Jacobi and John Fallows did an extremely popular talk at the last Javapolis using Grizzly ARP. I didn’t see their implementation and decided to design one I can use with GlassFish allowing JSF, JSP and Servlet to use cometd, and without by using the Grizzly tiny WebServer allowing only AJAX/DOJO component to use cometd. I’ve called the implementation gCometd.

Before starting, I’ve shared the idea of adding native support for the Bayeux protocol with Takai Naoto (the man behind JRuby on Grizzly (newly called gRuby ;-)). By the time I told him, he also comes with an implementation. Wow! kudo for the Bayeux spec folks because it seems not too difficult to implement! The final result is a merge of the two implementations. Can’t wait to see gCometd in action? The next couple of paragraphs will describe how to enable it.

Enabling gCometd in Grizzly

First, download Grizzly 1.0.11 (and up) from here. Next, just do:

 % java \
-Dcom.sun.grizzly.adapterClass=com.sun.grizzly.cometd.standalone.CometdAdapter \
-Dcom.sun.enterprise.web.connector.grizzly.enableCometSupport=true \
-jar grizzly-1.0.11.jar <port> <cometd folder>

port: The port on which Grizzly will listen.
comed folder: The folder from which file will be serviced.

That’s it. This is really useful when developing DOJO cometd application as it starts extremely fast. If you aren’t using JSF/JSP/Servlet, this is the implementation you want to use!. Event better, I will soon show how to debug a DOJO/cometd application using the Netbeans Phobos module. Et oui, you read it correctly: using the Phobos module (which under the hood uses this Grizzly), you will be able to debug your DOJO/JavaScript application with the Netbeans debugger!

Enabling gCometd in GlassFish

First, download GlassFish b35 from here. Install GlassFish and then follow the complete instruction described here.

You just need to add the bold line in domain.xml:

        <http-listener acceptor-threads="1" address="0.0.0.0" 
           blocking-enabled="false" default-virtual-server="server"
           enabled="true" family="inet" id="http-listener-1" port="8080"
           security-enabled="false" server-name="" xpowered-by="true">
                <property name="cometSupport" value="true"/>
        </http-listener>

Next, add to your application web.xml the following:

    <servlet>
        <servlet-name>Grizzly Cometd Servlet</servlet-name>
        <servlet-class>
            com.sun.grizzly.cometd.servlet.CometdServlet
        </servlet-class>
        <init-param>
            <description>
                expirationDelay is the long delay before a long polled request 
                is resumed. Default is 60000.
            </description>
            <param-name>expirationDelay</param-name>
            <param-value>60000</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Grizzly Cometd Servlet</servlet-name>
        <url-pattern>/cometd/*</url-pattern>
    </servlet-mapping>

Package your war and deploy it. Now every requests sent to your war’s context-path/cometd will be serviced by the gCometd runtime.

DOJO cometd example.

To see the gCometd in action, you can download a sample here. This sample is an adapted Chat application available in Jetty, written by Greg Wilkins. Greg Wilkins is a member of the Cometd specs and the creator of Jetty. Jetty was the first cometd implementation and I’ve decided to adapt its cometd example for the purpose of this blog.

For Grizzly, just unzip the war file under the cometd folder. For GlassFish, just deploy the application. Then start your browser and point to the context-root of the sample (“/index.html” for Grizzly, “cometd/” for GlassFish). An excellent tool to use to see what DOJO’s Cometd client is sending to gCometd is Firebug. I strongly recommend you install it. It really help understanding what is Bayeux! Under the hood, the DOJO cometd component does (a brief overview):

  • When index.html is loaded, DOJO does:

    <script type="text/javascript"> cometd.init({}, "/cometd-example/cometd"); </script>

    This initiate a handshake with the gCometd runtime (using Bayeux)

  • Next, when you enter a user name, DOJO client will exchange message with gCometd. The interesting part here is one of the DOJO connection will be polled, waiting for web event (push from the server). This is achieved by doing in a JavaScript function:
           cometd.subscribe("/chat/demo", false, room, "_chat");
           cometd.publish("/chat/demo", { user: room._username, join: true, chat : room._username+" has joined"});

  • Every time a message is typed, the browser will execute:
    cometd.publish("/chat/demo", { user: room._username, chat: text});

    On the gCometd side, the message will be pushed back to all cometd clients that have subscribed to the chat channel using a long polled connection.

  • Finally, to leave the chat, the browser will send:
    cometd.unsubscribe("/chat/demo", false, room, "_chat");

OK enough wording…just try it :-). In the upcoming weeks, I will start a series of blogs trying to give more details on how to write a cometd application. I’m also investigating how to make the gCometd implementation container agnostic, so it can be used in other Java container that support Comet/Continuation/Long polling. This way I can write my gCometd application and use it in Jezzly. But until them, just try it and give feedbacksssss!

_uacct = “UA-3111670-1″;
urchinTracker();

technorati:

Categories: Uncategorized
Follow

Get every new post delivered to your Inbox.

Join 50 other followers