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>
Apr 27, 2009
Getting Started With Cometd, Jetty, and jQuery
Posted
8:48 PM
9
comments
Labels: javascript, tools
Apr 25, 2009
Jetty and Cometd Documentation Woes
I've been trying to get going with Comet using Jetty and cometd-jquery. It's been an uphill battle. First off there's practically zero documentation for Cometd. I've been reverse engineering the chat example - a very poor source of documentation. I've finally gotten to a point where my JavaScript initiates a Bayeux connection. Great.
Now I want to debug my app that Jetty is hosting. That's been a very frustrating experience. Jetty 6 forks a JVM for each webapp, so none my standard approaches to debugging are working for me. Jetty documentation is again very weak and it's hard to differentiate which versions of Jetty documentation refers to.
Can anyone help me out?
Update: IntelliJ debugs Jetty 6 out of the box (with the Jetty Integration plugin). The IntelliJ run configuration uses -Xdebug -Xrunjdwp:transport... to start in debug. I guess these settings may work for Eclipse: -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y.
Update: Run Jetty Run for Eclipse works out of the box too.
Posted
1:17 PM
0
comments
Labels: javascript, tools
Apr 24, 2009
Leadership Philosophy
McKnight quoted in Leading Lean Software Development:
"Mistakes will be made. But if a person is essentially right, the mistakes he or she makes are not as serious in the long run as the mistakes management will make it if undertakes to tell those in authority exactly how they must do their jobs"
Posted
9:39 AM
0
comments
Labels: process
