I had difficulty getting started with these tools, so I thought I'd blog my minimal setup. This is all derived from the cometd demo who's war you can find inside the Jetty 6 webapp directory, and who's code you can find inside the contrib/cometd directory of the Jetty 6 source download.
First of all you need to be able to run Jetty (and debug it). I recommend the Run Jetty Run plugin for Eclipse.
Next you need to populate your web.xml for your webapp: (it's quite possible that you don't need all these init params)The GameServlet is pretty much boiler plate:<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>comet2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>org.mortbay.jetty.servlet.ManagedAttributes</param-name>
<param-value>org.cometd.bayeux,dojox.cometd.bayeux</param-value>
</context-param>
<servlet>
<servlet-name>game</servlet-name>
<servlet-class>
org.mortbay.cometd.continuation.ContinuationCometdServlet</servlet-class>
<init-param>
<param-name>timeout</param-name>
<param-value>120000</param-value>
</init-param>
<init-param>
<param-name>interval</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>maxInterval</param-name>
<param-value>10000</param-value>
</init-param>
<init-param>
<param-name>multiFrameInterval</param-name>
<param-value>2000</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>directDeliver</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>refsThreshold</param-name>
<param-value>10</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>game</servlet-name>
<url-pattern>/game/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>gameServlet</servlet-name>
<servlet-class>server.GameServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
</web-app>The GameService pairs paths to method names. You can call the package server;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.cometd.Bayeux;
import org.mortbay.cometd.ext.AcknowledgedMessagesExtension;
import org.mortbay.cometd.ext.TimesyncExtension;
public class GameServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
((HttpServletResponse)res).sendError(503);
}
@Override
public void init() throws ServletException {
super.init();
Bayeux bayeux=(Bayeux)getServletContext().getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);
new GameService(bayeux);
bayeux.addExtension(new TimesyncExtension());
bayeux.addExtension(new AcknowledgedMessagesExtension());
}
}send() method to send messages to clients. Mine looks like this:Finally, and perhaps most importantly (as this was the part that confused me the most), here's the JavaScript to talk to the comet service:package server;
import java.util.Map;
import org.cometd.Bayeux;
import org.cometd.Client;
import org.mortbay.cometd.BayeuxService;
public class GameService extends BayeuxService {
private GameState state = new GameState();
public GameService(Bayeux bayeux) {
super(bayeux, "game");
subscribe("/game/join", "join");
subscribe("/game/event", "event");
}
public void join(final Client joiner, final String channelName, Map<String, Object> data, final String messageId) {
send(joiner, "/game/state", state.getData(), null)
}
public void event(final Client joiner, final String channelName, Map<String, Object> data, final String messageId) {
// TODO
}
}Note that var _connected = false;
function _metaConnect(message)
{
var wasConnected = _connected;
_connected = message.successful;
if (_connected && !wasConnected)
{
$.cometd.startBatch();
$.cometd.subscribe('/game/state', this, receive);
$.cometd.publish('/game/join', {});
$.cometd.endBatch();
}
}
function join()
{
$.cometd.addListener('/meta/connect', this, _metaConnect);
var cometURL = document.location.protocol + '//' + document.location.hostname + ':' + document.location.port + '/c2/game';
$.cometd.init(cometURL);
}
function send(data) {
$.cometd.publish('/game/event', data);
}
function receive(message)
{
// handle message.data content
}
join();/c2 is the context name of my webapp in Jetty.
One last point, I used the same includes in my index.html as the cometd chat example did:Let me know if you get up to something with comet.<script type="text/javascript" src="jquery/json2.js"></script>
<script type="text/javascript" src="jquery/jquery.js"></script>
<script type="text/javascript" src="jquery/jquery.cometd.js"></script>
Paris Clojure Talk
-
I had a terrific time spreading the word about Clojure tonight, followed by
some fun and spirited discussions over dinner. People are intrigued by
Clojur...
1 day ago

9 comments:
Hi,
This is a great start for me I have been looking for jquery implementation of cometd. But was not able to run the example. I tried the steps that you have mentioned but not able to run the example successfully. Can you please elaborate.
Thanks,
-P
Of course. Can you provide any diagnostic information?
I was able to make it work. Thanks a lot for the great info that you have provided.
Hi,
How are you handling multiple tabs or browser window instances? Also, if you just force-kill a connected browser, do you get notified of the dropped player? I'm having problems with getting either of those two issues to work!
Hi Mark,
I've not put time into this since so I don't have the answers to your questions. I'd be interested in hearing what your up to or what solutions to come up with.
Cheers,
Merlyn
Hey yeah so I wanted to basically make a game as well. I've looked at so many (comet) ways of doing it. Seems like Bayeux with Jetty is pretty robust. Problems with many implementations are that multiple tabs in the browser screw things up, force kills of the browsers, stuff like that. The Cometd project is probably the best I've found. The only other promising project is Ajax Push Engine, but it's brand new and we'll see how quickly it matures.
Hi .I have a code to run. To run this program I need some libraries that you used in your own code. I want to know if you can mail these libraries to me. The list is hear:
org.cometd.Client;
org.cometd.Message;
org.cometd.MessageListener;
Hi again!. my email : nakhaie.1365@gmail.com
Thanks
Hi ss,
I'm pretty sure you can download all the code you need to run cometd from their website. I certainly didn't author any of the org.cometd classes.
Post a Comment