<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ed&#039;s World</title>
	<atom:link href="http://www.jellard.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jellard.co.uk</link>
	<description>Bringing data into real life in a meaningful way</description>
	<lastBuildDate>Fri, 16 Dec 2011 11:46:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Publishing to CometD/Bayeux</title>
		<link>http://www.jellard.co.uk/2011/12/publishing-to-cometdbayeux/</link>
		<comments>http://www.jellard.co.uk/2011/12/publishing-to-cometdbayeux/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 11:43:54 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[bayeux]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[jetty]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=306</guid>
		<description><![CDATA[After following one of my two previous blog posts, you should be in a state ready to pub/sub to/from your web pages.  Here&#8217;s a tiny bit of code that shows how you can push messages:


Thread t = new Thread(){
	int count = 0;
	@Override
	public void run() {
		while (true) {
			Mutable msg = bayeux.newMessage();
			msg.setChannel("/test");
			HashMap map = new HashMap();
			map.put("key1", [...]]]></description>
			<content:encoded><![CDATA[<p>After following one of my two previous blog posts, you should be in a state ready to pub/sub to/from your web pages.  Here&#8217;s a tiny bit of code that shows how you can push messages:</p>
<p><code>
<pre>
Thread t = new Thread(){
	int count = 0;
	@Override
	public void run() {
		while (true) {
			Mutable msg = bayeux.newMessage();
			msg.setChannel("/test");
			HashMap<String, String> map = new HashMap<String, String>();
			map.put("key1", count + "");
			msg.setData(map);

			ServerChannel c = bayeux.getChannel("/test");
			if (c != null) {
				c.publish(null, msg);
			}
			count++;
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
};
t.start();</pre>
<p></code></p>
<p>I put that in the init() call of BayeuxInitialiser.  Now when you subscribe to /test, you will get a message with an ever increasing value.</p>
<p>Very easy, very powerful.  Would make a nice bridge between MQTT and the web, especially as it doesn&#8217;t rely on websockets etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/12/publishing-to-cometdbayeux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSGi, Jetty, CometD, Bayeux and Dojo</title>
		<link>http://www.jellard.co.uk/2011/12/osgi-jetty-cometd-bayeux-and-dojo/</link>
		<comments>http://www.jellard.co.uk/2011/12/osgi-jetty-cometd-bayeux-and-dojo/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 16:32:47 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[bayeux]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[osgi]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=293</guid>
		<description><![CDATA[How many keywords can I stuff into that title!!  I succeeded to get Jetty, CometD and Dojo working together, without OSGi in the last blog post.  However, moving that into an OSGi environment was sadly not as easy as it should have been, but I got there!  This post should help you [...]]]></description>
			<content:encoded><![CDATA[<p>How many keywords can I stuff into that title!!  I succeeded to get Jetty, CometD and Dojo working together, without OSGi in the <a href="http://www.jellard.co.uk/2011/12/dojo-comet-and-jetty/">last blog post</a>.  However, moving that into an OSGi environment was sadly not as easy as it should have been, but I got there!  This post should help you get things up and running &#8211; there are bits I understand, and bits I don&#8217;t!!  It is as cut down as I could make it.  Here goes:</p>
<p>In eclipse, make yourself a new Plugin Project, mine&#8217;s called com.jellard.comet, choosing the Equinox OSGi framework.  Edit MANIFEST.MF to look like below:</p>
<p><img src="http://www.jellard.co.uk/wp-content/uploads/2011/12/Screen-Shot-2011-12-15-at-15.17.27.png" alt="" title="Manifest for OSGi" width="453" height="263" class="alignnone size-full wp-image-294" /></p>
<p>Add this to the MANIFEST.MF as well:<br />
<code>Web-ContextPath: /comettest</code></p>
<p>Put these files in your project, and add them to the build path: cometd-java-server-2.3.1.jar, bayeux-api-2.3.1.jar, cometd-java-common-2.3.1.jar</p>
<p>Copy this file into a new class, com.jellard.comet.BayeuxInitialiser:</p>
<p><code>
<pre>package com.jellard.comet;

import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerChannel;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.DefaultSecurityPolicy;

public class BayeuxInitialiser extends GenericServlet
{
	private static final long serialVersionUID = 4696913071422149884L;

	public void init() throws ServletException
    {
        BayeuxServer bayeux = (BayeuxServer)getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
        bayeux.setSecurityPolicy(new DefaultSecurityPolicy(){

			@Override
			public boolean canCreate(BayeuxServer server,
					ServerSession session, String channelId,
					ServerMessage message) {
				return true;
			}

			@Override
			public boolean canHandshake(BayeuxServer server,
					ServerSession session, ServerMessage message) {
				return true;
			}

			@Override
			public boolean canPublish(BayeuxServer server,
					ServerSession session, ServerChannel channel,
					ServerMessage message) {
				return true;
			}

			@Override
			public boolean canSubscribe(BayeuxServer server,
					ServerSession session, ServerChannel channel,
					ServerMessage message) {
				return true;
			}

        });
        new HelloService(bayeux);
    }

    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
    {
        throw new ServletException();
    }
}</pre>
<p></code></p>
<p>Make a new class, com.jellard.comet.HelloService, and paste this in:<br />
<code>
<pre>package com.jellard.comet;

import java.util.HashMap;
import java.util.Map;

import org.cometd.bayeux.Message;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.AbstractService;

public class HelloService extends AbstractService
{
    public HelloService(BayeuxServer bayeux)
    {
        super(bayeux, "hello");
        addService("/service/hello", "processHello");
    }

    public void processHello(final ServerSession remote, Message message)
    {
        Map<String, Object> input = message.getDataAsMap();
        String name = (String)input.get("name");

        Map<String, Object> output = new HashMap<String, Object>();
        output.put("greeting", "Hello, " + name);
        remote.deliver(getServerSession(), "/hello", output, null);

        Thread t = new Thread(){
        	int count = 0;
			@Override
			public void run() {
				while (true) {
					remote.deliver(getServerSession(), "/reply", count + "", null);
					System.out.println(count);
					count++;
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

        };
        t.start();
    }
}</pre>
<p></code></p>
<p>Create folders ~/jetty/etc/ and place this file in, as jetty.xml:<br />
<code>
<pre>&lt;?xml version="1.0"?>
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

&lt;!-- =============================================================== -->
&lt;!-- Configure the Jetty Server                                      -->
&lt;!--                                                                 -->
&lt;!-- Documentation of this file format can be found at:              -->
&lt;!-- http://docs.codehaus.org/display/JETTY/jetty.xml                -->
&lt;!--                                                                 -->
&lt;!-- =============================================================== -->

&lt;Configure id="Server" class="org.eclipse.jetty.server.Server">

    &lt;!-- =========================================================== -->
    &lt;!-- Set connectors                                              -->
    &lt;!-- =========================================================== -->

    &lt;Call name="addConnector">
      &lt;Arg>
          &lt;New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            &lt;Set name="port">&lt;SystemProperty name="jetty.port" default="8080"/>&lt;/Set>
          &lt;/New>
      &lt;/Arg>
    &lt;/Call>

    &lt;!-- =========================================================== -->
    &lt;!-- Set handler Collection Structure                            -->
    &lt;!-- =========================================================== -->

    &lt;Set name="handler">
      &lt;New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        &lt;Set name="handlers">
         &lt;Array type="org.eclipse.jetty.server.Handler">
           &lt;Item>
				&lt;New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">

			&lt;/New>
           &lt;/Item>
           &lt;Item>
             &lt;New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
           &lt;/Item>
           &lt;Item>
             &lt;New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
           &lt;/Item>
         &lt;/Array>
        &lt;/Set>
      &lt;/New>
    &lt;/Set>
    &lt;!-- =========================================================== -->
    &lt;!-- Configure the deployment manager                            -->
    &lt;!--                                                             -->
    &lt;!-- Sets up 2 monitored dir app providers that are configured   -->
    &lt;!-- to behave in a similaraly to the legacy ContextDeployer     -->
    &lt;!-- and WebAppDeployer from previous versions of Jetty.         -->
    &lt;!-- =========================================================== -->
    &lt;Call name="addBean">
      &lt;Arg>
        &lt;New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
          &lt;Set name="contexts">
            &lt;Ref id="Contexts" />
          &lt;/Set>
          &lt;Call name="setContextAttribute">
            &lt;Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern&lt;/Arg>
            &lt;Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$&lt;/Arg>
          &lt;/Call>
          &lt;!-- Providers of OSGi Apps -->
          &lt;Call name="addAppProvider">
            &lt;Arg>
              &lt;New class="org.eclipse.jetty.osgi.boot.OSGiAppProvider">
              &lt;!--
                &lt;Set name="defaultsDescriptor">&lt;Property name="jetty.home" default="."/>/etc/webdefault.xml&lt;/Set>
              -->
                &lt;Set name="scanInterval">5&lt;/Set>
                &lt;Set name="contextXmlDir">&lt;Property name="jetty.home" default="." />/contexts&lt;/Set>
                &lt;!-- comma separated list of bundle symbolic names that
                    contain custom tag libraries (*.tld files)
                    if those bundles don't exist or can't be loaded no errors or warning will be issued!
                    this default value is to plug the tld files of the reference implementation of JSF -->
                &lt;Set name="tldBundles">&lt;Property name="org.eclipse.jetty.osgi.tldsbundles"
                     default="javax.faces.jsf-impl" />&lt;/Set>
              &lt;/New>
            &lt;/Arg>
          &lt;/Call>

        &lt;/New>
      &lt;/Arg>
    &lt;/Call>

    &lt;!-- =========================================================== -->
    &lt;!-- extra options                                               -->
    &lt;!-- =========================================================== -->
    &lt;Set name="stopAtShutdown">true&lt;/Set>
    &lt;Set name="sendServerVersion">true&lt;/Set>
    &lt;Set name="sendDateHeader">true&lt;/Set>
    &lt;Set name="gracefulShutdown">1000&lt;/Set>

&lt;/Configure>
</pre>
<p></code></p>
<p>Create a XML file, WEB-INF/web.xml, in your project:<br />
<code>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
	&lt;servlet>
		&lt;servlet-name>cometd&lt;/servlet-name>
		&lt;servlet-class>org.cometd.server.CometdServlet&lt;/servlet-class>
		&lt;load-on-startup>1&lt;/load-on-startup>
	&lt;/servlet>
	&lt;servlet-mapping>
		&lt;servlet-name>cometd&lt;/servlet-name>
		&lt;url-pattern>/cometd/*&lt;/url-pattern>
	&lt;/servlet-mapping>
	&lt;servlet>
		&lt;servlet-name>initializer&lt;/servlet-name>
		&lt;servlet-class>com.jellard.comet.BayeuxInitialiser&lt;/servlet-class>
		&lt;load-on-startup>2&lt;/load-on-startup>
	&lt;/servlet>
	&lt;filter>
		&lt;filter-name>cross-origin&lt;/filter-name>
		&lt;filter-class>org.eclipse.jetty.servlets.CrossOriginFilter&lt;/filter-class>
	&lt;/filter>
	&lt;filter-mapping>
		&lt;filter-name>cross-origin&lt;/filter-name>
		&lt;url-pattern>/cometd/*&lt;/url-pattern>
	&lt;/filter-mapping>
&lt;/web-app>
</pre>
<p></code></p>
<p>Create a html folder in the root of your project.  In there, create a js/dojo folder, and extract a build of dojo into there (so you will have a html/dojo/dojox folder, for example).</p>
<p>Also in the html folder, make a file, comet.html, and paste in this:<br />
<code>
<pre>
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html>
&lt;head>
    &lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    &lt;script type="text/javascript" src="js/dojo/dojo/dojo.js">&lt;/script>
    &lt;script type="text/javascript">
        dojo.require("dojox.cometd");
        dojo.addOnLoad(function() {
            // Disconnect when the page unloads
            dojo.addOnUnload(function() {
               dojox.cometd.disconnect(true);
            });

            var cometURL = "/comettest/cometd";
            dojox.cometd.init(cometURL);
        });
        function subscribe() {
        	dojox.cometd.subscribe("/*", console, "log");
        }
        function publish() {
        	dojox.cometd.publish('/service/hello', { name: 'World' })
        }
    &lt;/script>
&lt;/head>
&lt;body>
    &lt;input type="button" onclick="subscribe()" value="1. Subscribe" />
    &lt;input type="button" onclick="publish();" value="2. Publish" />
&lt;/body>
&lt;/html>
</pre>
<p></code></p>
<p>Right-click your project, Run, Run As&#8230; and make a new configuration under OSGi Framework.  Select the following bundles, and anything else they require (I ended up with 55 selected!)<br />
<img src="http://www.jellard.co.uk/wp-content/uploads/2011/12/Screen-Shot-2011-12-15-at-16.05.50.png" alt="" title="Bundles" width="373" height="234" class="alignnone size-full wp-image-296" /></p>
<p>In the arguments tab, you need to add this to your VM args:<br />
<code>-Djetty.home=/Users/ed/jetty</code> (if your home dir is /Users/ed)</p>
<p>Run the OSGi framework, and point your browser to http://localhost:8080/comettest/html/comet.html</p>
<p>Open up developer tools/firefox, and you should see a pending request.  Click the subscribe and publish button, and as if by magic, every 5 seconds, you should see an object appear in your console.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/12/osgi-jetty-cometd-bayeux-and-dojo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dojo, Comet and Jetty</title>
		<link>http://www.jellard.co.uk/2011/12/dojo-comet-and-jetty/</link>
		<comments>http://www.jellard.co.uk/2011/12/dojo-comet-and-jetty/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 12:55:01 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[jetty]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=282</guid>
		<description><![CDATA[There&#8217;s not a great deal of up to date documentation of how to get dojo and cometd working with the Bayeux protocol.  This quick blog post should get you up and running, and is based off the &#8220;Primer&#8221; sample code that you can get here (but you don&#8217;t need it for this): http://cometd.org/documentation/howtos/primer
The following [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s not a great deal of up to date documentation of how to get dojo and cometd working with the Bayeux protocol.  This quick blog post should get you up and running, and is based off the &#8220;Primer&#8221; sample code that you can get here (but you don&#8217;t need it for this): http://cometd.org/documentation/howtos/primer</p>
<p>The following code will show you how to set everything up and then publish a message from the webpage.  This will kick off a thread in Jetty that publishes an ever-increasing number every 5 seconds that will be shown on screen.</p>
<p>Prereqs:<br />
Jetty 8.x server runtime setup and installed in eclipse (well documented elsewhere)<br />
Dojo 1.7</p>
<p>Create a Dynamic Web Project in eclipse, pointing it at Jetty.</p>
<p>Add to your build path:<br />
bayeux-api-2.3.1.jar<br />
cometd-java-common-2.3.1.jar<br />
cometd-java-server-2.3.1.jar</p>
<p>Create a GenericServlet, calling it test.BayeuxInitialiser, paste in this:<br />
<code>
<pre>/*
 * Copyright (c) 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package test;

import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerChannel;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.DefaultSecurityPolicy;

public class BayeuxInitialiser extends GenericServlet
{
	private static final long serialVersionUID = -9089442901563633963L;

	public void init() throws ServletException
    {
        BayeuxServer bayeux = (BayeuxServer)getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
        bayeux.setSecurityPolicy(new DefaultSecurityPolicy(){

			@Override
			public boolean canCreate(BayeuxServer server,
					ServerSession session, String channelId,
					ServerMessage message) {
				return true;
			}

			@Override
			public boolean canHandshake(BayeuxServer server,
					ServerSession session, ServerMessage message) {
				return true;
			}

			@Override
			public boolean canPublish(BayeuxServer server,
					ServerSession session, ServerChannel channel,
					ServerMessage message) {
				return true;
			}

			@Override
			public boolean canSubscribe(BayeuxServer server,
					ServerSession session, ServerChannel channel,
					ServerMessage message) {
				return true;
			}

        });
        new HelloService(bayeux);
    }

    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
    {
        throw new ServletException();
    }
}</pre>
<p></code></p>
<p>Create a test.HelloService class, and paste in this:<br />
<code>
<pre>/*
 * Copyright (c) 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package test;

import java.util.Map;
import java.util.HashMap;

import org.cometd.bayeux.Message;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.AbstractService;

public class HelloService extends AbstractService
{
    public HelloService(BayeuxServer bayeux)
    {
        super(bayeux, "hello");
        addService("/service/hello", "processHello");
        System.out.println("New HelloService");
    }

    public void processHello(final ServerSession remote, Message message)
    {
        Map<String, Object> input = message.getDataAsMap();
        String name = (String)input.get("name");
        Map<String, Object> output = new HashMap<String, Object>();
        output.put("greeting", "Hello, " + name);
        remote.deliver(getServerSession(), "/hello", output, null);

        Thread t = new Thread(){
        	int count = 0;
			@Override
			public void run() {
				while (true) {
					remote.deliver(getServerSession(), "/reply", count + "", null);
					System.out.println(count);
					count++;
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

        };
        t.start();
    }
}</pre>
<p></code></p>
<p>Now, in your WebContent directory:</p>
<p>Unzip dojo into js/dojo (so you will have js/dojo/dojo/* js/dojo/dijit/* etc.)</p>
<p>Create index.jsp:<br />
<code>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html>
&lt;head>
    &lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    &lt;script type="text/javascript" src="js/dojo/dojo/dojo.js">&lt;/script>
    &lt;script type="text/javascript">
        dojo.require("dojox.cometd");
        dojo.addOnLoad(function() {
            // Disconnect when the page unloads
            dojo.addOnUnload(function() {
               dojox.cometd.disconnect(true);
            });

            var cometURL = "cometd";
            dojox.cometd.init(cometURL);
        });
        function subscribe() {
        	dojox.cometd.subscribe("/*", console, "log");
        }
        function publish() {
        	dojox.cometd.publish('/service/hello', { name: 'World' })
        }
    &lt;/script>
&lt;/head>
&lt;body>
    &lt;input type="button" onclick="subscribe()" value="1. Subscribe" />
    &lt;input type="button" onclick="publish();" value="2. Publish" />
&lt;/body>
&lt;/html>
</pre>
<p></code></p>
<p>Replace web.xml with this:<br />
<code>
<pre>

&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    &lt;servlet>
        &lt;servlet-name>cometd&lt;/servlet-name>
        &lt;servlet-class>org.cometd.server.CometdServlet&lt;/servlet-class>
        &lt;load-on-startup>1&lt;/load-on-startup>
    &lt;/servlet>
    &lt;servlet-mapping>

        &lt;servlet-name>cometd&lt;/servlet-name>
        &lt;url-pattern>/cometd/*&lt;/url-pattern>
    &lt;/servlet-mapping>

    &lt;servlet>
        &lt;servlet-name>initializer&lt;/servlet-name>
        &lt;servlet-class>test.BayeuxInitialiser&lt;/servlet-class>

        &lt;load-on-startup>2&lt;/load-on-startup>
    &lt;/servlet>

    &lt;filter>
        &lt;filter-name>cross-origin&lt;/filter-name>
        &lt;filter-class>org.eclipse.jetty.servlets.CrossOriginFilter&lt;/filter-class>
    &lt;/filter>
    &lt;filter-mapping>

        &lt;filter-name>cross-origin&lt;/filter-name>
        &lt;url-pattern>/cometd/*&lt;/url-pattern>
    &lt;/filter-mapping>

&lt;/web-app>
</pre>
<p></code></p>
<p>Now point your browser to index.jsp, click the subscribe button, and click the publish button.  You should see messages appear on the screen and in your console.</p>
<p>Hope this helps someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/12/dojo-comet-and-jetty/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Streaming from linux to ipad</title>
		<link>http://www.jellard.co.uk/2011/10/streaming-from-linux-to-ipad/</link>
		<comments>http://www.jellard.co.uk/2011/10/streaming-from-linux-to-ipad/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 21:17:13 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=279</guid>
		<description><![CDATA[I&#8217;ve taken the plunge and bought an iPad &#8211; very different experience to android, and so far, I still prefer androids &#8211; they&#8217;re more transparent.  Didn&#8217;t like having to immediately install itunes (which needs windows/mac) to turn the iPad on, then didn&#8217;t like having to fill in a credit card number to register an [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve taken the plunge and bought an iPad &#8211; very different experience to android, and so far, I still prefer androids &#8211; they&#8217;re more transparent.  Didn&#8217;t like having to immediately install itunes (which needs windows/mac) to turn the iPad on, then didn&#8217;t like having to fill in a credit card number to register an account, and then didn&#8217;t like the fact that you can&#8217;t try out apps that cost (you get 15mins on android to uninstall and get a refund, no questions asked).</p>
<p>Anyway, I wanted to be able to:<br />
<strong>Stream MythTV to iPad</strong><br />
<strong>Stream music to iPad</strong></p>
<p>MythTV to iPad &#8211; really cool, using AirVideo (£1.99) and an AirVideo server that transcodes your recordings in realtime on-demand on your linux server, and spouts them out for the app on the iPad to read.  Instructions here: http://wiki.birth-online.de/know-how/hardware/apple-iphone/airvideo-server-linux &#8211; except you need to download the JAR from here: http://www.inmethod.com/forum/posts/list/1856.page</p>
<p>Music to iPad, via &#8220;Music Player Daemon&#8221; (MPD): mpd is a daemon that can play music on local speakers, to an icecast server, and as a http stream.  You can control it via a variety of plugins, inc a firefox one, bitMPC on androids, and MPoD/MPaD on i-devices.  If you have &#8220;lame&#8221; setup, add this to /etc/mpd.conf:</p>
<p><code>audio_output {<br />
        type            "httpd"<br />
        name            "Jukebox"<br />
        encoder         "lame"                  # optional, vorbis or lame<br />
        port            "8001"<br />
        quality         "6.0"                   # do not define if bitrate is defined<br />
#       bitrate         "192"                   # do not define if quality is defined<br />
        format          "44100:16:2"<br />
}<br />
</code></p>
<p>Then download FStream and whack in http://IPADDRESS:8001 &#8211; tada &#8211; it works!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/10/streaming-from-linux-to-ipad/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dojo &#8211; checking every AJAX request and error handling</title>
		<link>http://www.jellard.co.uk/2011/08/dojo-checking-every-ajax-request-and-error-handling/</link>
		<comments>http://www.jellard.co.uk/2011/08/dojo-checking-every-ajax-request-and-error-handling/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 10:05:07 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[dojo]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=272</guid>
		<description><![CDATA[I want to check every AJAX request for a &#8220;is logged out&#8221; flag.  I also want to do something nice for every AJAX error, globally (in this case, I am just going to make a dialog showing the stacktrace from tomcat).
I could do something in every load: and error:, but this does it globally:
Error [...]]]></description>
			<content:encoded><![CDATA[<p>I want to check every AJAX request for a &#8220;is logged out&#8221; flag.  I also want to do something nice for every AJAX error, globally (in this case, I am just going to make a dialog showing the stacktrace from tomcat).</p>
<p>I could do something in every load: and error:, but this does it globally:</p>
<p>Error handling (assumes something is subscribed to the errors  topic that displays a dialog, or whatever):<br />
<code><br />
(function(){<br />
&nbsp;&nbsp;&nbsp;var oldxhr = dojo.xhr;<br />
&nbsp;&nbsp;&nbsp;dojo.xhr = function(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return oldxhr.apply(dojo, arguments).addErrback(function(e, v){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dojo.publish("errors", [{text:e.responseText}]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;&nbsp;};<br />
})();<br />
</code></p>
<p>Checking all JSON (assumes something has subscribed to the checklogin topic to do the logic):<br />
<code><br />
dojo.contentHandlers.json = function(xhr) {<br />
&nbsp;&nbsp;&nbsp;var json = dojo.fromJson(xhr.responseText || null);<br />
&nbsp;&nbsp;&nbsp;dojo.publish("checklogin", [{j:json}]);<br />
&nbsp;&nbsp;&nbsp;return json;<br />
}<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/08/dojo-checking-every-ajax-request-and-error-handling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing an Acer Revo with Ubuntu &amp; MythTV</title>
		<link>http://www.jellard.co.uk/2011/02/installing-an-acer-revo-with-ubuntu-mythtv/</link>
		<comments>http://www.jellard.co.uk/2011/02/installing-an-acer-revo-with-ubuntu-mythtv/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 16:02:04 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=261</guid>
		<description><![CDATA[This post is not intended to be interesting, just a list of useful steps/links for setting up an Acer Revo with Ubuntu and MythTV (and is probably already out of date)
I have two TV cards &#8211; a Hauppage WinTV NOVA TD with Diversity (dual tuner freeview) and a TeVii S660 Freesat receiver (primarily for HD).
Installing
Downloaded [...]]]></description>
			<content:encoded><![CDATA[<p>This post is not intended to be interesting, just a list of useful steps/links for setting up an Acer Revo with Ubuntu and MythTV (and is probably already out of date)</p>
<p>I have two TV cards &#8211; a Hauppage WinTV NOVA TD with Diversity (dual tuner freeview) and a TeVii S660 Freesat receiver (primarily for HD).</p>
<p><strong>Installing</strong><br />
Downloaded the latest Ubuntu ISO (10.10) and used existing Ubuntu to turn a USB disk into a startup disk.  Worked a treat.</p>
<p><strong>Fed up with sudo password&#8230;</strong><br />
sudo vi /etc/sudoers, and change the line:<br />
%admin ALL=(ALL) ALL<br />
to<br />
%admin ALL=NOPASSWD:ALL<br />
This gives me sudo access with no need for a password.</p>
<p><strong>Non-free drivers</strong><br />
System > Administration > Additional drivers<br />
Installed both the nvidia and DVB drivers.</p>
<p><strong>Installing packages</strong><br />
System > Adminstration > Synaptic Package Manager<br />
Search for mythtv, mythweb, mythvideo and install them all.<br />
I also grabbed phpmyadmin for managing the mysql database.</p>
<p><strong>TeVii S660</strong><br />
http://ubuntuforums.org/showpost.php?p=9927773&#038;postcount=32 &#8211; that has a link to a modified driver that works on Ubuntu 10.10.  Unzip the zip, and then execute run &#8220;bash README&#8221; which executes all the commands in the README file.  Turn off the machine (must turn it off, not restart it), wait a few seconds, then turn it on.</p>
<p><strong>Consistent USB Device numbers</strong><br />
Depending on all things random, a device that reports as /dev/dvb/adapter0 now may end up as /dev/dvb/adapter1 on the next reboot (assuming you have dual tuners/multiple cards).  I found udev rules didn&#8217;t work &#8211; it&#8217;d link two new adapters to the second adapter each time.  However, creating /etc/modprobe.d/dvb.conf and putting &#8220;options dvb_usb_dib0700 adapter_nr=5,6&#8243; means that the freeview tuners will always be adapter5 and adapter6, leaving the freesat tuner as adapter0 (by default).</p>
<p><strong>MythTV</strong><br />
First, the system taskbar doesn&#8217;t vanish when running mythtv in fullscreen.  To fix this &#8211; System > Pref > Appearance > Visual Effect = None</p>
<p>Run mythtv-setup.  If it can&#8217;t connect to database, the password can be found in ~mythtv/.mythtv/mysql.txt</p>
<p><strong>grano.la</strong><br />
Grano.la is a beautifully simple way to save money by scaling CPU appropriately &#8211; http://grano.la/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/02/installing-an-acer-revo-with-ubuntu-mythtv/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Perl Serial Comms on Ubuntu 10.10</title>
		<link>http://www.jellard.co.uk/2011/02/perl-serial-comms-on-ubuntu-10-10/</link>
		<comments>http://www.jellard.co.uk/2011/02/perl-serial-comms-on-ubuntu-10-10/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 16:01:34 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=267</guid>
		<description><![CDATA[Thanks to @ceejay, here&#8217;s some code to set up serial parameters and read from the serial device.  Bizarrely the usual method stopped working after an update.
#!/usr/bin/perl
use strict;
use warnings;
use Device::SerialPort;
my $serport="/dev/ttyUSB0";
my $dev = tie (*SERIAL, 'Device::SerialPort', $serport) &#124;&#124; die "Can't tie: $!";
$dev->baudrate(4800);
$dev->databits(8);
$dev->parity("none");
$dev->stopbits(1);
#wait for device to exist
while (1) {
    my $val = ;
 [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to @ceejay, here&#8217;s some code to set up serial parameters and read from the serial device.  Bizarrely the usual method stopped working after an update.<br />
<code>#!/usr/bin/perl<br />
use strict;<br />
use warnings;<br />
use Device::SerialPort;</p>
<p>my $serport="/dev/ttyUSB0";</p>
<p>my $dev = tie (*SERIAL, 'Device::SerialPort', $serport) || die "Can't tie: $!";</p>
<p>$dev->baudrate(4800);<br />
$dev->databits(8);<br />
$dev->parity("none");<br />
$dev->stopbits(1);</p>
<p>#wait for device to exist<br />
while (1) {<br />
    my $val = <SERIAL>;<br />
    last if $val;<br />
}</p>
<p>while (1) {<br />
    my $val = <SERIAL>;<br />
    next unless $val;<br />
    chomp $val;<br />
    print $val . "\n";<br />
    #sleep 1;<br />
}<br />
# die if port closes/goes away</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2011/02/perl-serial-comms-on-ubuntu-10-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to calculate the average angle of bearings</title>
		<link>http://www.jellard.co.uk/2010/08/how-to-calculate-the-average-angle-of-bearings/</link>
		<comments>http://www.jellard.co.uk/2010/08/how-to-calculate-the-average-angle-of-bearings/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 16:03:05 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=251</guid>
		<description><![CDATA[This is going to be a tediously dull post, but given the amount of faffing I did, I don&#8217;t want to forget it!
Firstly, this is mostly not my maths &#8211; this is thanks to @helenbowyer, @bluerhinos and a parent of a scout who saw a link to my site on @rmappleby&#8217;s blog and then saw [...]]]></description>
			<content:encoded><![CDATA[<p>This is going to be a tediously dull post, but given the amount of faffing I did, I don&#8217;t want to forget it!</p>
<p>Firstly, this is mostly not my maths &#8211; this is thanks to @helenbowyer, @bluerhinos and a parent of a scout who saw a link to my site on @rmappleby&#8217;s blog and then saw my tweet asking for help!</p>
<p>The problem is what happens when you cross the 0/360 boundary &#8211; how to average 5 degrees and 355 degrees to get 0 degrees.  A &#8220;mean&#8221; would give 180 degrees &#8211; oops!</p>
<p>The answer is trigonometry, treating the angles as vectors.</p>
<p>First get the SIN of the angle, and divide by the COS of it.  Then take the &#8220;ATAN2&#8243; of it to get the final result.  Tada!</p>
<p>For my application, I am putting the last 40 values into an ArrayList and calculating a weighted average (in Utilities.weightedAverage()) &#8211; you can replace this with any averaging function.  Here&#8217;s the Java:</p>
<pre>
sinTotals.add(Math.sin(angleInRadians));
cosTotals.add(Math.cos(angleInRadians));

if (sinTotals.size() > 40) {
	sinTotals.remove(0);
	cosTotals.remove(0);
}
double sinAverage = Utilities.weightedAverage(sinTotals);
double cosAverage = Utilities.weightedAverage(cosTotals);

double direction =
     (Math.toDegrees(Math.atan2(sinAverage, cosAverage)) + 360) % 360;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2010/08/how-to-calculate-the-average-angle-of-bearings/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Developing RSA plugins using Eclipse</title>
		<link>http://www.jellard.co.uk/2010/05/developing-rsa-plugins-using-eclipse/</link>
		<comments>http://www.jellard.co.uk/2010/05/developing-rsa-plugins-using-eclipse/#comments</comments>
		<pubDate>Fri, 14 May 2010 14:56:53 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[RSA]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=241</guid>
		<description><![CDATA[If you&#8217;re developing plugins for RSA, you&#8217;ll probably have one RSA open and a runtime RSA, both eating huge amounts of memory.  To reduce the memory footprint, I&#8217;m using Eclipse to develop, but still launching a runtime RSA.
To do this, install RSA and eclipse (separately), then in your eclipse:
Install the JRE:
1. Windows > Preferences [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re developing plugins for RSA, you&#8217;ll probably have one RSA open and a runtime RSA, both eating huge amounts of memory.  To reduce the memory footprint, I&#8217;m using Eclipse to develop, but still launching a runtime RSA.</p>
<p>To do this, install RSA and eclipse (separately), then in your eclipse:</p>
<p><strong>Install the JRE:</strong><br />
1. Windows > Preferences > Java > Installed JREs<br />
2. Add c:\Program Files\IBM\SDP\jdk\jre<br />
3. Tick its tick-box</p>
<p><strong>Set the Target Platform:</strong><br />
1. Windows > Preferences > Plugin-in Development > Target Platform<br />
2. Browse for c:\Program Files\IBM\SDP<br />
3. Tick &#8220;Build target platform based on the target&#8217;s installed plugins&#8221;<br />
4. Click &#8220;Reload&#8221;</p>
<p><strong>Running as RSA</strong><br />
1. Run > Run Configurations<br />
2. Change the Run as product to: com.ibm.rational.rsa4ws.product.v75.ide (or equivalent)</p>
<p>Tada!  I&#8217;ve found I get far less out of memory errors and things are generally quicker.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2010/05/developing-rsa-plugins-using-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wild Camping and Night Photography by Torchlight</title>
		<link>http://www.jellard.co.uk/2010/04/wild-camping-night-photography-by-torchlight/</link>
		<comments>http://www.jellard.co.uk/2010/04/wild-camping-night-photography-by-torchlight/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 19:33:21 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[camping]]></category>
		<category><![CDATA[night]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[scouts]]></category>

		<guid isPermaLink="false">http://www.jellard.co.uk/?p=211</guid>
		<description><![CDATA[On the 17th April I set off to the Black Mountains for a weekend solo hike, wild-camping overnight, to gain more experience for the &#8220;Scout Terrain 1 Assessment&#8221; and &#8220;Walking Group Leader Assessment&#8221;.

Day 1 was a 25km route (horizontally), scarily that doesn&#8217;t include 1.1km ascent and 800m descent &#8211; very knackering, but I did rescue [...]]]></description>
			<content:encoded><![CDATA[<p>On the 17th April I set off to the Black Mountains for a weekend solo hike, wild-camping overnight, to gain more experience for the &#8220;Scout Terrain 1 Assessment&#8221; and &#8220;Walking Group Leader Assessment&#8221;.</p>
<p><img src="/wp-content/uploads/2010/04/Panorama.jpg" /></p>
<p>Day 1 was a 25km route (horizontally), scarily that doesn&#8217;t include 1.1km ascent and 800m descent &#8211; very knackering, but I did rescue a stray dog on route!</p>
<p>After eating my home-made boil in the bags and waiting for it to get dark enough, I put my camera on my jumper on a rock (there was no way I was going to carry a 3kg tripod around the place), and these were the (edited) results:</p>
<p><img src="/wp-content/uploads/2010/04/MiniWaterfall.jpg" /></p>
<p><img src="/wp-content/uploads/2010/04/TorchLitTree.jpg" /></p>
<p><img src="/wp-content/uploads/2010/04/TorchLitTreeStarStreaks.jpg" style="float: right; width: 300px; margin-left: 5px;" /> For those that care, the waterfall image was taken first, with an exposure of 30s at F9, ISO 100.</p>
<p>The tree was taken 20mins later after much experimenting, with an exposure of 4 minutes, F9, ISO 100.  This meant there was long enough for the stars to streak across the sky.  I felt this distracted from the photo, so removed them &#8211; you can see them in the original out-of-the-camera image on the right (there were even more of them after tweaking the brightness levels, but you get the idea).  I didn&#8217;t have the patience to enable the noise reduction function on the camera &#8211; the one where it takes the photo, then takes another photo of black for the same length of time &#8211; in hindsight, I wish I had, but hey!</p>
<p>Both images involved painting the area that I wanted to show up with a super-bright LED head-torch.  With the waterfall image, I set the exposure to 30s, and quickly walked above the waterfall to light the area around the top, then quickly came back to light the actual waterfall.  The tree shot meant using a (tempermental) shutter-release cable (£6 from ebay, so can&#8217;t expect much more), and sitting behind the camera moving the torch evenly over the tree.</p>
<p>So that was fun.  I went to bed and woke up in the morning feeling sunburnt and knackered.  Day 2&#8217;s route was a mere 16km, this time descending a total of 820m and ascending 435m.</p>
<p>Really can&#8217;t complain waking up here:</p>
<p><img src="/wp-content/uploads/2010/04/TentOut.jpg" style="float: left;" /> <img src="/wp-content/uploads/2010/04/Tent.jpg" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jellard.co.uk/2010/04/wild-camping-night-photography-by-torchlight/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

