<?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"
	>

<channel>
	<title>Comet Daily</title>
	<atom:link href="http://cometdaily.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cometdaily.com</link>
	<description>Information about Comet techniques.</description>
	<pubDate>Sun, 07 Mar 2010 16:32:33 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>&#8220;Hello World&#8221; for Flex AMF with Lightstreamer</title>
		<link>http://cometdaily.com/2010/03/07/hello-world-for-flex-amf-with-lightstreamer/</link>
		<comments>http://cometdaily.com/2010/03/07/hello-world-for-flex-amf-with-lightstreamer/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 16:32:33 +0000</pubDate>
		<dc:creator>Alessandro Alinone</dc:creator>
		
		<category><![CDATA[articles]]></category>

		<category><![CDATA[AMF]]></category>

		<category><![CDATA[BlazeDS]]></category>

		<category><![CDATA[flex]]></category>

		<category><![CDATA[LCDS]]></category>

		<category><![CDATA[Lightstreamer]]></category>

		<category><![CDATA[Push]]></category>

		<category><![CDATA[Single Dealer Platform]]></category>

		<category><![CDATA[Streaming]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=484</guid>
		<description><![CDATA[In this fourth installment of the "Hello World with Lightstreamer" series, we will focus on a new feature that was released with Lightstreamer Server version 3.6: Action Message Format (AMF) support for Flex applications.]]></description>
			<content:encoded><![CDATA[<p>In this fourth installment of the &#8220;Hello World with Lightstreamer&#8221; series, we will focus on a new feature that was <a href="http://cometdaily.com/2010/02/22/lightstreamer-36-released/">released</a> with <a href="http://www.lightstreamer.com/download.htm">Lightstreamer Server version 3.6</a>: <strong>Action Message Format (AMF)</strong> support for Flex applications.</p>
<p>First, a quick recap of the previous installments:</p>
<ol>
<li><a title="Hello World with Lightstreamer" rel="bookmark" href="http://cometdaily.com/2008/02/12/%e2%80%9chello-world%e2%80%9d-with-lightstreamer/">&#8220;Hello World&#8221; with Lightstreamer</a>: An introduction to Lightstreamer&#8217;s data model, Web Client API, and Java Data Adapters API.</li>
<li><a title="Hello World for .NET with Lightstreamer" rel="bookmark" href="http://cometdaily.com/2008/04/14/hello-world-for-net-with-lightstreamer/">&#8220;Hello World&#8221;<br />
for .NET with Lightstreamer</a>: The .NET API version of the Data  Adapter used in the &#8220;Hello World&#8221; application, showing both a C# and a Visual Basic port.</li>
<li><a title="Hello World for Sockets with Lightstreamer" rel="bookmark" href="http://cometdaily.com/2008/07/29/hello-world-for-sockets-with-lightstreamer/">&#8220;Hello World&#8221; for Sockets with Lightstreamer</a>: The TCP-socket-based version of the  Data  Adapter, suitable for implementation in other languages (PHP, Python, Perl, etc).</li>
</ol>
<p>Basically, Lightstreamer Server can be seen as a &#8220;technology hub&#8221; for data push, where you can mix different technologies on the client-side and on the server-side to exchange real-time messages.</p>
<p><img src="http://cometdaily.com/wp-content/uploads/2010/03/technology-hub1.png" alt="Lightstreamer Hub" title="technology-hub1" width="500" height="253" class="aligncenter size-full wp-image-490" /></p>
<p>In this article, we will delve into the &#8220;Flex on the client-side, Java on the server-side&#8221; scenario.</p>
<p>In particular, Simone Fabiano will show you how to push binary ActionScript objects directly to your Flex application in real-time, using AMF. <a href="http://en.wikipedia.org/wiki/Action_Message_Format">Action Message Format</a> is used for serializing binary ActionScript objects in order to transmit them over the wire.</p>
<p>As you may recall form the <a href="http://cometdaily.com/2008/02/12/%e2%80%9chello-world%e2%80%9d-with-lightstreamer/">first installment</a>, Lightstreamer data push model is based on items made up of fields. A client can subscribe to many items, each with its own schema (a set of fields). Each field is usually a text string with an arbitrary length (from a few characters to large data structures, perhaps based on XML, JSON, etc.). With this new Lightstreamer feature, you can now put a full AMF object into any field and have it pushed from the server to the client in real binary format (with no re-encondings).</p>
<p>The Flex Client library for Lightstreamer has been used for one of the <strong>major dealing platforms</strong> in the finance field and has undergone many cycles of improvements to make it completely production resilient. We were asked to add native support for AMF objects to improve the performance when streaming complex data structures. So now you can push both text-based items and object-based items to the same Flex application.</p>
<p>When approaching the Lightstreamer <strong>data model</strong>, it is important to choose the right trade-off between using <em>fine-grained fields</em> and <em>coarse objects</em>. You could map each individual atomic piece of information to a Lightstreamer field, thus using many fields and items, or you could map all your data to a single field of a single item. This applies to both text-based fields (where you can encode coarse objects via JSON, XML, etc.) and object-based fields (via AMF). Usually, going for fine-grained fields is better, because you let Lightstreamer know more about your data structure, so that it will be able to apply optimization mechanisms, like conflation and delta delivery. On the other hand, if you go for huge opaque objects, Lightstreamer will be used more as a blind pipe. But in both cases, you will still benefit from other features, like bandwidth allocation and dynamic throttling. All intermediate scenarios are possible too.</p>
<p>In the tutorial below, Simone will use a single field containing an AMF object derived from a JavaBean. To encode a JavaBean as an AMF object, several ready-made libraries exist. Here we will leverage BlazeDS.</p>
<h2>AMF Lightstreamer Tutorial</h2>
<p><em>by Simone Fabiano, Software Engineer at Lightstreamer</em></p>
<p><img class="alignright size-full wp-image-489" title="mone_real3" src="http://cometdaily.com/wp-content/uploads/2010/03/mone_real3.jpg" alt="Simone Fabiano" width="119" height="90" />Alessandro asked me to write a simple &#8220;Hello World&#8221; example to show how to use AMF with our new Flex client library (<a href="http://www.lightstreamer.com/docs/client_flashflexas_asdoc/index.html">docs</a>). We will create a JavaBean on the server-side and then use it on the client-side.</p>
<p>For this tutorial, I&#8217;m assuming you have already read the <a href="http://cometdaily.com/2008/02/12/%E2%80%9Chello-world%E2%80%9D-with-lightstreamer/" target="_blank">Basic Hello World</a> example, or that you are already familiar with Lightstreamer concepts.</p>
<p>On the client, the result of this tutorial will be quite similar to the one obtained with the original Hello World by Alessandro, but in Flex: we&#8217;ll get a string alternating some different values (<em>Hello AMF World</em>) and a timestamp. On the server-side, data will be encapsulated into a <strong>JavaBean</strong> containing a <code>String</code> and a <code>Date</code> instance. This bean will be translated into a byte array and then injected into the Lightstreamer kernel as a single field, instead of being spread over different fields as simple strings (as the original adapter does). Here lies the power of AMF, as you will be able to push even complex JavaBeans to your Flex clients with ease.</p>
<h2>Gather Stuff</h2>
<ul>
<li>First of all you&#8217;ll need a browser, a Flash player, and a JDK: hopefully you already have those <img src='http://cometdaily.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>You&#8217;ll need <strong>Lightstreamer Server 3.6 (Presto or Vivace)</strong> and <strong>Lightstreamer Flex Client 2.0</strong>. You can <a href="http://www.lightstreamer.com/download.htm" target="_blank">download them from the Lightstreamer web site</a>.</li>
<li>You&#8217;ll have to compile a Flex application, so you&#8217;ll need either the <a href="http://www.adobe.com/mena/products/flex/" target="_blank">Flex Builder</a> or the <a href="http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK" target="_blank">Flex SDK</a> (the example works with Flex 3 and Flex 4; use Flex 4 only if you&#8217;re going to use it with the Flex Builder, otherwise you may have problems with the <code>mxmlc</code process we're going to use).</li>
<li>The conversion from Java beans to an AMF-compatible byte array is performed by a couple of the BlazeDS libraries. <a href="http://opensource.adobe.com/wiki/display/blazeds/Release+Builds" target="_blank">Download BlazeDS</a> (binary distribution) and extract <code>flex-messaging-common.jar</code> and <code>flex-messaging-core.jar</code> from it (the downloaded zip contains a .war file, open it with an archive manager and locate the needed libraries under &#8220;WEB-INF/lib/&#8221;).</li>
</ul>
<h2>Let&#8217;s Code the Front-End(s)</h2>
<p>The front-end of our application will be a simple <code>.mxml</code> file compiled into a <code>.swf</code>. Open your text editor and start writing a <code>mxml</code> file (notice the <code>creationComplete</code> event):</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:Application</span> <span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">&quot;http://www.adobe.com/2006/mxml&quot;</span>
   <span style="color: #000066;">creationComplete</span>=<span style="color: #ff0000;">&quot;init()&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></pre></div></div>

<p>Then add a <code>TextArea</code> instance (<code>myTextArea</code>), where we&#8217;ll put the updates:</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:TextArea</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;693&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;56&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;myTextArea&quot;</span>
   <span style="color: #000066;">fontSize</span>=<span style="color: #ff0000;">&quot;25&quot;</span> <span style="color: #000066;">fontWeight</span>=<span style="color: #ff0000;">&quot;bold&quot;</span> <span style="color: #000066;">text</span>=<span style="color: #ff0000;">&quot;loading...&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></pre></div></div>

<p>Now to Actionscript&#8230; We need an <code>init</code> method to initialize our client and subscribe to our table. We&#8217;ll also configure a <code>DateFormatter</code> instance to print nice-looking dates.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
  dateFormatter.<span style="color: #006600;">formatString</span> = <span style="color: #ff0000;">&quot;MM/DD/YY J:NN:SS&quot;</span>; 
&nbsp;
  <span style="color: #000000; font-weight: bold;">var</span> cInfo:ConnectionInfo = <span style="color: #000000; font-weight: bold;">new</span> ConnectionInfo<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
  cInfo.<span style="color: #006600;">server</span> = <span style="color: #ff0000;">&quot;localhost&quot;</span>;
  cInfo.<span style="color: #006600;">adapterSet</span> = <span style="color: #ff0000;">&quot;AMFHELLOWORLD&quot;</span>;
&nbsp;
  <span style="color: #000000; font-weight: bold;">var</span> client:LSClient = <span style="color: #000000; font-weight: bold;">new</span> LSClient<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #000000; font-weight: bold;">var</span> nonVisualTable:NonVisualTable =
     <span style="color: #000000; font-weight: bold;">new</span> NonVisualTable<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;greetings&quot;</span><span style="color: #66cc66;">&#93;</span>,<span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;AMF_field&quot;</span><span style="color: #66cc66;">&#93;</span>,<span style="color: #ff0000;">&quot;MERGE&quot;</span>,<span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
  nonVisualTable.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>
    NonVisualItemUpdateEvent.<span style="color: #006600;">NON_VISUAL_ITEM_UPDATE</span>,onChange<span style="color: #66cc66;">&#41;</span>;
  client.<span style="color: #006600;">subscribeTable</span><span style="color: #66cc66;">&#40;</span>nonVisualTable<span style="color: #66cc66;">&#41;</span>;
&nbsp;
  client.<span style="color: #006600;">openConnection</span><span style="color: #66cc66;">&#40;</span>cInfo<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The <code>ConnectionInfo</code> instance defines how we connect to the server and the adapter set that will handle our requests. In this case we&#8217;ll deploy our application on tje Lightstreamer internal web server so the server has to be set to &#8220;localhost&#8221;. The adapter set in use will be called &#8220;AMFHELLOWORLD&#8221;.</p>
<p>The <code>LSClient</code> instance is the core of the Lightstreamer Flex client library. It handles the connection to the server and the subscription/unsubscription of tables.</p>
<p>The <code>NonVisualTable</code> represents the subscription we&#8217;re going to make. It is a mono-item (&#8221;greetings&#8221;) and mono-field (&#8221;AMF_field&#8221;) <em>MERGE subscription</em>. The fourth parameter in the constructors tells the server that we&#8217;re looking for binary data, namely AMF.</p>
<p>Next, we need the <code>onChange</code> callback to handle the updates and show them on screen. We&#8217;ll just extract the single field and, since it&#8217;s a <code>Bean</code>, expand it, format the date an put everything on the <code>TextArea</code> previously created:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> onChange<span style="color: #66cc66;">&#40;</span>evt:NonVisualItemUpdateEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>evt.<span style="color: #006600;">isFieldChanged</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;AMF_field&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> obj:<span style="color: #66cc66;">*</span> = evt.<span style="color: #006600;">getFieldValue</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;AMF_field&quot;</span><span style="color: #66cc66;">&#41;</span>;
    myTextArea.<span style="color: #0066CC;">text</span> = dateFormatter.<span style="color: #006600;">format</span><span style="color: #66cc66;">&#40;</span>obj.<span style="color: #006600;">now</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #ff0000;">&quot; &quot;</span> + obj.<span style="color: #006600;">hello</span>;
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p><a href='http://cometdaily.com/wp-content/uploads/2010/03/amfhelloworld.mxml'>Download the complete source of the Flex client</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
</pre></td><td class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:Application</span> <span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">&quot;http://www.adobe.com/2006/mxml&quot;</span> 
  <span style="color: #000066;">creationComplete</span>=<span style="color: #ff0000;">&quot;init()&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:TextArea</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;693&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;56&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;myTextArea&quot;</span> 
    <span style="color: #000066;">fontSize</span>=<span style="color: #ff0000;">&quot;25&quot;</span> <span style="color: #000066;">fontWeight</span>=<span style="color: #ff0000;">&quot;bold&quot;</span> <span style="color: #000066;">text</span>=<span style="color: #ff0000;">&quot;loading...&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:Script<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #339933;">&lt;![CDATA[</span>
<span style="color: #339933;">    import mx.formatters.DateFormatter;</span>
<span style="color: #339933;">    import com.lightstreamer.as_client.ConnectionInfo;</span>
<span style="color: #339933;">    import com.lightstreamer.as_client.LSClient;</span>
<span style="color: #339933;">    import com.lightstreamer.as_client.NonVisualTable;</span>
<span style="color: #339933;">    import com.lightstreamer.as_client.events.NonVisualItemUpdateEvent;</span>
&nbsp;
<span style="color: #339933;">    public var dateFormatter:DateFormatter = new DateFormatter();</span>
&nbsp;
<span style="color: #339933;">    public function init():void {</span>
<span style="color: #339933;">      dateFormatter.formatString = &quot;MM/DD/YY J:NN:SS&quot;; </span>
&nbsp;
<span style="color: #339933;">      var cInfo:ConnectionInfo = new ConnectionInfo();</span>
<span style="color: #339933;">      cInfo.server = &quot;localhost&quot;;</span>
<span style="color: #339933;">      cInfo.adapterSet = &quot;AMFHELLOWORLD&quot;;</span>
&nbsp;
<span style="color: #339933;">      var client:LSClient = new LSClient();</span>
&nbsp;
<span style="color: #339933;">      var nonVisualTable:NonVisualTable = </span>
<span style="color: #339933;">        new NonVisualTable([&quot;greetings&quot;],</span>
<span style="color: #339933;">         [&quot;AMF_field&quot;],&quot;MERGE&quot;,true);</span>
<span style="color: #339933;">      nonVisualTable.addEventListener(</span>
<span style="color: #339933;">        NonVisualItemUpdateEvent.NON_VISUAL_ITEM_UPDATE,</span>
<span style="color: #339933;">        onChange);</span>
<span style="color: #339933;">      client.subscribeTable(nonVisualTable);</span>
&nbsp;
<span style="color: #339933;">      client.openConnection(cInfo);</span>
<span style="color: #339933;">    }</span>
&nbsp;
<span style="color: #339933;">    public function onChange(evt:NonVisualItemUpdateEvent):void {</span>
<span style="color: #339933;">      if (evt.isFieldChanged(&quot;AMF_field&quot;)) {</span>
<span style="color: #339933;">        var obj:* = evt.getFieldValue(&quot;AMF_field&quot;);</span>
<span style="color: #339933;">        myTextArea.text = </span>
<span style="color: #339933;">          dateFormatter.format(obj.now) + &quot; &quot; + obj.hello;</span>
<span style="color: #339933;">      }</span>
<span style="color: #339933;">    }    </span>
&nbsp;
<span style="color: #339933;">  ]]&gt;</span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:Script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:Application<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></td></tr></table></div>

<p>If you prefer a <code>DataGrid</code> in place of the TextArea, don&#8217;t worry, the substitution is really easy. First we replace the TextArea with a DataGrid (<code>myDataGrid</code>) with two columns. Each column is associated to a property of the bean sent by the server, so &#8220;AMF_field&#8221; represents the entire bean (the field of our subscription) and &#8220;AMF_field.hello&#8221; represents the &#8220;hello&#8221; property of the bean. We add a <code>labelFunction</code> to one of the columns so that we&#8217;ll be able to format the received date.</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:DataGrid</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;479&quot;</span> <span style="color: #000066;">x</span>=<span style="color: #ff0000;">&quot;447.5&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;91&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;helloView&quot;</span> <span style="color: #000066;">y</span>=<span style="color: #ff0000;">&quot;12&quot;</span> <span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:columns<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:DataGridColumn</span> <span style="color: #000066;">dataField</span>=<span style="color: #ff0000;">&quot;AMF_field.now&quot;</span> 
      <span style="color: #000066;">headerText</span>=<span style="color: #ff0000;">&quot;Time&quot;</span> <span style="color: #000066;">labelFunction</span>=<span style="color: #ff0000;">&quot;formatDate&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:DataGridColumn</span> <span style="color: #000066;">dataField</span>=<span style="color: #ff0000;">&quot;AMF_field.hello&quot;</span> <span style="color: #000066;">headerText</span>=<span style="color: #ff0000;">&quot;Hello&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:columns<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:DataGrid<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>

<p>Then, we need something to be bound with the DataGrid. Luckily enough, our <code>VisualTable</code> class extends the <code><a href="http://livedocs.adobe.com/flex/3/langref/mx/collections/ArrayCollection.html">ArrayCollection</a></code> native class. so that it can be bound to a DataGrid to update the view automagically. We have to put our VisualTable in the global space so that we can declare the [Bindable] metadata on it.</p>

<div class="wp_syntax"><div class="code"><pre class="xml">[Bindable] public var myTable:VisualTable;</pre></div></div>

<p>Finally, we have to initialize this table. The code is very similar to the one used to initialize the NonVisualTable, but we don&#8217;t need to add any event handlers. Instead, we bind our VisualTable and the DataGrid assigning our Bindable VisualTable to the &#8220;dataProvider&#8221; property of the DataGrid.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript"><span style="color: #000000; font-weight: bold;">var</span> myTable:VisualTable =
  <span style="color: #000000; font-weight: bold;">new</span> VisualTable<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;greetings&quot;</span><span style="color: #66cc66;">&#93;</span>,<span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;AMF_field&quot;</span><span style="color: #66cc66;">&#93;</span>,<span style="color: #ff0000;">&quot;MERGE&quot;</span>,<span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
helloView.<span style="color: #006600;">dataProvider</span> = myTable;</pre></div></div>

<p><a href='http://cometdaily.com/wp-content/uploads/2010/03/amfhelloworld_datagrid.mxml'>Download the complete modified source of the Flex client</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
</pre></td><td class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:Application</span> <span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">&quot;http://www.adobe.com/2006/mxml&quot;</span> 
  <span style="color: #000066;">creationComplete</span>=<span style="color: #ff0000;">&quot;init()&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
&nbsp;
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:DataGrid</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;479&quot;</span> <span style="color: #000066;">x</span>=<span style="color: #ff0000;">&quot;447.5&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;91&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;helloView&quot;</span> <span style="color: #000066;">y</span>=<span style="color: #ff0000;">&quot;12&quot;</span> <span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:columns<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:DataGridColumn</span> <span style="color: #000066;">dataField</span>=<span style="color: #ff0000;">&quot;AMF_field.now&quot;</span> 
      <span style="color: #000066;">headerText</span>=<span style="color: #ff0000;">&quot;Time&quot;</span> <span style="color: #000066;">labelFunction</span>=<span style="color: #ff0000;">&quot;formatDate&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:DataGridColumn</span> <span style="color: #000066;">dataField</span>=<span style="color: #ff0000;">&quot;AMF_field.hello&quot;</span> <span style="color: #000066;">headerText</span>=<span style="color: #ff0000;">&quot;Hello&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:columns<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:DataGrid<span style="font-weight: bold; color: black;">&gt;</span></span></span>
&nbsp;
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mx:Script<span style="font-weight: bold; color: black;">&gt;</span></span></span> <span style="color: #339933;">&lt;![CDATA[</span>
<span style="color: #339933;">	import mx.formatters.DateFormatter;</span>
<span style="color: #339933;">	import com.lightstreamer.as_client.VisualTable;</span>
<span style="color: #339933;">	import com.lightstreamer.as_client.ConnectionInfo;</span>
<span style="color: #339933;">	import com.lightstreamer.as_client.LSClient;</span>
&nbsp;
<span style="color: #339933;">	public var dateFormatter:DateFormatter = new DateFormatter();</span>
&nbsp;
<span style="color: #339933;">	[Bindable]</span>
<span style="color: #339933;">	public var myTable:VisualTable;</span>
&nbsp;
<span style="color: #339933;">	public function init():void {</span>
<span style="color: #339933;">		dateFormatter.formatString = &quot;MM/DD/YY J:NN:SS&quot;; </span>
&nbsp;
<span style="color: #339933;">		var cInfo:ConnectionInfo = new ConnectionInfo();</span>
<span style="color: #339933;">		cInfo.server = &quot;localhost&quot;;</span>
<span style="color: #339933;">		cInfo.adapterSet = &quot;AMFHELLOWORLD&quot;;</span>
&nbsp;
<span style="color: #339933;">		var client:LSClient = new LSClient();</span>
&nbsp;
<span style="color: #339933;">		var myTable:VisualTable = </span>
<span style="color: #339933;">		  new VisualTable([&quot;greetings&quot;], </span>
<span style="color: #339933;">		    [&quot;AMF_field&quot;],&quot;MERGE&quot;,true);</span>
<span style="color: #339933;">		helloView.dataProvider = myTable;</span>
<span style="color: #339933;">		client.subscribeTable(myTable);</span>
&nbsp;
<span style="color: #339933;">		client.openConnection(cInfo);</span>
<span style="color: #339933;">	}</span>
&nbsp;
<span style="color: #339933;">	public function formatDate(item:Object,</span>
<span style="color: #339933;">          column:DataGridColumn):String {</span>
<span style="color: #339933;">		return dateFormatter.format(item.AMF_field.now);</span>
<span style="color: #339933;">	}</span>
<span style="color: #339933;"> ]]&gt;</span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:Script<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mx:Application<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></td></tr></table></div>

<p>The <code>mxml</code> file, as is, is quite useless, so, save it as &#8220;AMFHelloWorld.mxml&#8221; and compile it into a swf file using the Flex SDK:</p>

<div class="wp_syntax"><div class="code"><pre class="xml">FLEX_SDK_HOME/bin/mxmlc AMFHelloWorld.mxml 
  -output AMFHelloWorld.swf 
  -library-path+=
    LS_HOME/DOCS-SDKs/sdk_client_flash_flex(native_as)
    /lib/Lightstreamer_as_client.swc</pre></div></div>

<p>Note that if you&#8217;re using a 64-bit JVM you may have some issues running mxmlc; use a 32-bit JVM (mxmlc makes use of the JAVA_HOME environment variable to choose the JVM).</p>
<h2>Server-Side</h2>
<p>Now it&#8217;s time to write the adapter. We&#8217;ll reuse most of the code of the <a href="http://cometdaily.com/2008/02/12/%E2%80%9Chello-world%E2%80%9D-with-lightstreamer/">first Hello World</a>. We&#8217;ll add a static property and a static utility method to the class we&#8217;ve renamed into &#8220;AMFHelloWorld&#8221;.</p>

<div class="wp_syntax"><div class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> SerializationContext context <span style="color: #339933;">=</span> 
  SerializationContext.<span style="color: #006633;">getSerializationContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> toAMF<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> bean<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  <span style="color: #003399;">ByteArrayOutputStream</span> baos <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  Amf3Output output <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Amf3Output<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  output.<span style="color: #006633;">setOutputStream</span><span style="color: #009900;">&#40;</span>baos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    output.<span style="color: #006633;">writeObject</span><span style="color: #009900;">&#40;</span>bean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    output.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    output.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e1<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    e1.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">return</span> baos.<span style="color: #006633;">toByteArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <code>toAMF</code> method receives an <code>Object</code> instance and converts it into an <code>AMF byte array</code> using the <code>Amf3Output</code> class. You can find a list of the conversions performed to switch from Java to AMF in the <a href="http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/ActionMessageOutput.html#writeObject(java.lang.Object)">ActionMessageOutput class javadoc</a>.</p>
<p>In this case we&#8217;re going to use a Java bean. <em>Note that the AMF3Output class javadoc is currently not linked/listed on <a href="http://livedocs.adobe.com/blazeds/1/javadoc/overview-tree.html">BlazeDS classes list</a></em> (they forgot?). You can reach it anyway, at the <a href="http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/Amf3Output.html">logical directory</a>.</p>
<p>Once the conversion method is in place, we can add the bean we want to send to the clients. We will prepare a simple bean containing only two properties, a <code>String</code> and a <code>Date</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> HelloBean <span style="color: #000000; font-weight: bold;">implements</span> java.<span style="color: #006633;">io</span>.<span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 7965747352089964767L<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> hello<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> now<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> HelloBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getHello<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> hello<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setHello<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> hello<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">hello</span> <span style="color: #339933;">=</span> hello<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getNow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> now<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setNow<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> now<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">now</span> <span style="color: #339933;">=</span> now<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Finally, we will replace the <code>run</code> method of the <code>GreetingThread</code> inner class with a different implementation that handles our bean:</p>

<div class="wp_syntax"><div class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">int</span> c <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">Random</span> rand <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  HelloBean testBean <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HelloBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>go<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Map<span style="color: #339933;">&lt;</span>String,<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span> data <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashMap<span style="color: #339933;">&lt;</span>String,<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    testBean.<span style="color: #006633;">setHello</span><span style="color: #009900;">&#40;</span>c <span style="color: #339933;">%</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">?</span> <span style="color: #0000ff;">&quot;Hello&quot;</span> <span style="color: #339933;">:</span> c <span style="color: #339933;">%</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">?</span> <span style="color: #0000ff;">&quot;AMF&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;World&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    testBean.<span style="color: #006633;">setNow</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    data.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;AMF_field&quot;</span>, toAMF<span style="color: #009900;">&#40;</span>testBean<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    listener.<span style="color: #006633;">smartUpdate</span><span style="color: #009900;">&#40;</span>itemHandle, data, <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    c<span style="color: #339933;">++;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">Thread</span>.<span style="color: #006633;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span> <span style="color: #339933;">+</span> rand.<span style="color: #006633;">nextInt</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2000</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InterruptedException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see, there&#8217;s nothing extremely complicated here, we just convert the instance of our bean through the <code>toAMF</code> method and inject it in a <code>Map</code> as if it was a simple String. Then, in turn, the Map is injected into the Lightstreamer kernel to make its way to the clients.</p>
<p><a href='http://cometdaily.com/wp-content/uploads/2010/03/amfhelloworld.java'>Download the complete Java Adapter source</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
</pre></td><td class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.ByteArrayOutputStream</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.File</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Date</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.HashMap</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Map</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Random</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.lightstreamer.interfaces.data.DataProviderException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.lightstreamer.interfaces.data.FailureException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.lightstreamer.interfaces.data.ItemEventListener</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.lightstreamer.interfaces.data.SmartDataProvider</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.lightstreamer.interfaces.data.SubscriptionException</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">flex.messaging.io.SerializationContext</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">flex.messaging.io.amf.Amf3Output</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AMFHelloWorld <span style="color: #000000; font-weight: bold;">implements</span> SmartDataProvider <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> ItemEventListener listener<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">volatile</span> GreetingsThread gt<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #003399;">Map</span> params, <span style="color: #003399;">File</span> configDir<span style="color: #009900;">&#41;</span> 
    <span style="color: #000000; font-weight: bold;">throws</span> DataProviderException <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isSnapshotAvailable<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> itemName<span style="color: #009900;">&#41;</span> 
    <span style="color: #000000; font-weight: bold;">throws</span> SubscriptionException <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setListener<span style="color: #009900;">&#40;</span>ItemEventListener listener<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">listener</span> <span style="color: #339933;">=</span> listener<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> subscribe<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> itemName, 
    <span style="color: #003399;">Object</span> itemHandle, <span style="color: #000066; font-weight: bold;">boolean</span> needsIterator<span style="color: #009900;">&#41;</span> 
        <span style="color: #000000; font-weight: bold;">throws</span> SubscriptionException, FailureException <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>itemName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;greetings&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      gt <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GreetingsThread<span style="color: #009900;">&#40;</span>itemHandle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      gt.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> subscribe<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> itemName, 
    <span style="color: #000066; font-weight: bold;">boolean</span> needsIterator<span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> SubscriptionException, FailureException <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> unsubscribe<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> itemName<span style="color: #009900;">&#41;</span> 
    <span style="color: #000000; font-weight: bold;">throws</span> SubscriptionException,
        FailureException <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>itemName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;greetings&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> gt <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      gt.<span style="color: #006633;">go</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> SerializationContext context <span style="color: #339933;">=</span> 
    SerializationContext.<span style="color: #006633;">getSerializationContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> toAMF<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> bean<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #003399;">ByteArrayOutputStream</span> baos <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Amf3Output output <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Amf3Output<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    output.<span style="color: #006633;">setOutputStream</span><span style="color: #009900;">&#40;</span>baos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      output.<span style="color: #006633;">writeObject</span><span style="color: #009900;">&#40;</span>bean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      output.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      output.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e1<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      e1.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> baos.<span style="color: #006633;">toByteArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">class</span> GreetingsThread <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Thread</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> itemHandle<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">volatile</span> <span style="color: #000066; font-weight: bold;">boolean</span> go <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> GreetingsThread<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> itemHandle<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">itemHandle</span> <span style="color: #339933;">=</span> itemHandle<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">int</span> c <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #003399;">Random</span> rand <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      HelloBean testBean <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HelloBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>go<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        Map<span style="color: #339933;">&lt;</span>String,<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span> data <span style="color: #339933;">=</span> 
          <span style="color: #000000; font-weight: bold;">new</span> HashMap<span style="color: #339933;">&lt;</span>String,<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        testBean.<span style="color: #006633;">setHello</span><span style="color: #009900;">&#40;</span>c <span style="color: #339933;">%</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">?</span> 
          <span style="color: #0000ff;">&quot;Hello&quot;</span> <span style="color: #339933;">:</span> c <span style="color: #339933;">%</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">?</span> <span style="color: #0000ff;">&quot;AMF&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;World&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        testBean.<span style="color: #006633;">setNow</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        data.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;AMF_field&quot;</span>, toAMF<span style="color: #009900;">&#40;</span>testBean<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        listener.<span style="color: #006633;">smartUpdate</span><span style="color: #009900;">&#40;</span>itemHandle, data, <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        c<span style="color: #339933;">++;</span>
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">Thread</span>.<span style="color: #006633;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span> <span style="color: #339933;">+</span> rand.<span style="color: #006633;">nextInt</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2000</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InterruptedException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> HelloBean <span style="color: #000000; font-weight: bold;">implements</span> java.<span style="color: #006633;">io</span>.<span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 
    7965747352089964767L<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> hello<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> now<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> HelloBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getHello<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> hello<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setHello<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> hello<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">hello</span> <span style="color: #339933;">=</span> hello<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getNow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> now<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setNow<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> now<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">now</span> <span style="color: #339933;">=</span> now<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Deploy the Adapter</h2>
<p>Now just compile the .java file as you would compile any other java application. Remember to add to the classpath the &#8220;ls-adapter-interface.jar&#8221; file (from LS_HOME/DOCS-SDKs/sdk_adapter_java/lib), &#8220;flex-messaging-common.jar&#8221; and &#8220;flex-messaging-core.jar&#8221; (from BlazeDS). You will obtain three class files: <code>AMFHelloWorld.class</code>, <code>AMFHelloWorld$HelloBean.class</code> and <code>AMFHelloWorld$GreetingsThread.class</code>. Now create an &#8220;AMFHelloWorld&#8221; folder under &#8220;LS_HOME/adapters&#8221; and a &#8220;classes&#8221; folder inside it: put the .class files there.</p>
<p>Finally, create an <a href='http://cometdaily.com/wp-content/uploads/2010/03/adapters.xml'>adapters.xml file</a> under the LS_HOME/adapters/AMFHelloWorld folder:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;adapters_conf</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;AMFHELLOWORLD&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;metadata_provider<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;adapter_class<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      com.lightstreamer.adapters.metadata.LiteralBasedProvider
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/adapter_class<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/metadata_provider<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;data_provider<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;adapter_class<span style="font-weight: bold; color: black;">&gt;</span></span></span>AMFHelloWorld<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/adapter_class<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/data_provider<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/adapters_conf<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></td></tr></table></div>

<p>As anticipated, while assembling the client we&#8217;re going to use &#8220;AMFHELLOWORLD&#8221; as the adapter set name, while we&#8217;ll use the classic <code>LiteralBasedProvider</code> as our Metadata Adapter and our brand new <code>AMFHelloWorld</code> class as our Data Adapter.</p>
<h2>Deploy the Client</h2>
<p>The client is made up only by the compiled swf file, so grab that file and put it under the &#8220;LS_HOME/pages&#8221; folder, that&#8217;s all.</p>
<h2>Run!</h2>
<p>Start the Lightstreamer server and point your browser to:<br />
<a href="http://localhost:8080/AMFHelloWorld.swf">http://localhost:8080/AMFHelloWorld.swf</a><br />
Enjoy <img src='http://cometdaily.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Final Notes</h2>
<p>You&#8217;ve seen how to push Objects instead of Strings from a Lightstreamer server to a Flex client. You can exploit this technique to push complex data structures, but obviously, doing so you&#8217;ll lose some of the optimizations offered by Lightstreamer protocol. For example, the merging algorithm (of the MERGE mode) is applied to the entire bean instead of being applied to each single field, so that every time a property within the bean changes, the entire bean is pushed to the client, not only the changed value. As with anything regarding engineering you&#8217;ll have to choose the trade-off that optimizes properly for your application.</p>
<p>Please also consider that the Flex client library in this tutorial is not available with the Moderato version of Lightstreamer Server, so you may want to use a <a href="http://www.lightstreamer.com/downloadretail.htm">trial license</a> for Lightstreamer Presto/Vivace to experiment with it.</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F07%2Fhello-world-for-flex-amf-with-lightstreamer%2F&amp;title=%26%238220%3BHello+World%26%238221%3B+for+Flex+AMF+with+Lightstreamer" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2010/03/07/hello-world-for-flex-amf-with-lightstreamer/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Is WebSocket Chat Simple?</title>
		<link>http://cometdaily.com/2010/03/02/is-websocket-chat-simple/</link>
		<comments>http://cometdaily.com/2010/03/02/is-websocket-chat-simple/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 18:25:15 +0000</pubDate>
		<dc:creator>GregWilkins</dc:creator>
		
		<category><![CDATA[articles]]></category>

		<category><![CDATA[chat]]></category>

		<category><![CDATA[cometd]]></category>

		<category><![CDATA[cometd-jetty]]></category>

		<category><![CDATA[websocket]]></category>

		<category><![CDATA[websockets]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=483</guid>
		<description><![CDATA[The WebSocket protocol has been touted as a great leap forward for bidirectional web applications like chat, promising a new era of simple Comet applications.]]></description>
			<content:encoded><![CDATA[<p>The WebSocket protocol has been <a href="http://cometdaily.com/2008/07/04/html5-websocket/">touted</a> as a great leap forward for bidirectional web applications like chat, promising a new era of simple Comet applications. Unfortunately there is no such thing as a silver bullet and this blog will walk through a simple chat room to see where WebSocket does and does not help with Comet applications.  In a WebSocket world, there is even more need for frameworks like <a href="http://cometd.org">cometD</a>.</p>
<h2>Simple Chat</h2>
<p>Chat is the &quot;helloworld&quot; application of web-2.0 and a simple WebSocket chat room is included with the <a href="http://eclipse.org/jetty">jetty-7</a> which now <a href="http://blogs.webtide.com/gregw/entry/jetty_websocket_server">supports WebSockets</a>. The source of the simple chat can be seen in svn for the <a href="http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/test-jetty-webapp/src/main/webapp/ws/">client-side</a> and <a href="http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java">server-side</a>. The key part of the client-side is to establish a WebSocket connection:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">join<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._username<span style="color: #339933;">=</span><span style="color: #000066;">name</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> location <span style="color: #339933;">=</span> document.<span style="color: #006600;">location</span>.<span style="color: #006600;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006600;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http:'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'ws:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._ws<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">new</span> WebSocket<span style="color: #009900;">&#40;</span>location<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._ws.<span style="color: #006600;">onopen</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">this</span>._onopen<span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._ws.<span style="color: #006600;">onmessage</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">this</span>._onmessage<span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._ws.<span style="color: #006600;">onclose</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">this</span>._onclose<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>

<p>It is then possible for the client to send a chat message to the server:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">_send<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>user<span style="color: #339933;">,</span>message<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	user<span style="color: #339933;">=</span>user.<span style="color: #006600;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'_'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>._ws<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">this</span>._ws.<span style="color: #006600;">send</span><span style="color: #009900;">&#40;</span>user<span style="color: #339933;">+</span><span style="color: #3366CC;">':'</span><span style="color: #339933;">+</span>message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>

<p>and to receive a chat message from the server and to display it:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">_onmessage<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>m.<span style="color: #006600;">data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> c<span style="color: #339933;">=</span>m.<span style="color: #006600;">data</span>.<span style="color: #006600;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> from<span style="color: #339933;">=</span>m.<span style="color: #006600;">data</span>.<span style="color: #006600;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>c<span style="color: #009900;">&#41;</span>
			.<span style="color: #006600;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'&amp;lt;'</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006600;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&gt;'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> text<span style="color: #339933;">=</span>m.<span style="color: #006600;">data</span>.<span style="color: #006600;">substring</span><span style="color: #009900;">&#40;</span>c<span style="color: #CC0000;">+1</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006600;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'&amp;lt;'</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006600;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&gt;'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> chat<span style="color: #339933;">=</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'chat'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> spanFrom <span style="color: #339933;">=</span> document.<span style="color: #006600;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		spanFrom.<span style="color: #006600;">className</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'from'</span><span style="color: #339933;">;</span>
		spanFrom.<span style="color: #006600;">innerHTML</span><span style="color: #339933;">=</span>from<span style="color: #339933;">+</span><span style="color: #3366CC;">':&amp;nbsp;'</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> spanText <span style="color: #339933;">=</span> document.<span style="color: #006600;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		spanText.<span style="color: #006600;">className</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'text'</span><span style="color: #339933;">;</span>
		spanText.<span style="color: #006600;">innerHTML</span><span style="color: #339933;">=</span>text<span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> lineBreak <span style="color: #339933;">=</span> document.<span style="color: #006600;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'br'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		chat.<span style="color: #006600;">appendChild</span><span style="color: #009900;">&#40;</span>spanFrom<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		chat.<span style="color: #006600;">appendChild</span><span style="color: #009900;">&#40;</span>spanText<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		chat.<span style="color: #006600;">appendChild</span><span style="color: #009900;">&#40;</span>lineBreak<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		chat.<span style="color: #006600;">scrollTop</span> <span style="color: #339933;">=</span> chat.<span style="color: #006600;">scrollHeight</span> <span style="color: #339933;">-</span> chat.<span style="color: #006600;">clientHeight</span><span style="color: #339933;">;</span>   
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>

<p>For the server-side, we simply accept incoming connections as members:</p>

<div class="wp_syntax"><div class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onConnect<span style="color: #009900;">&#40;</span>Outbound outbound<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	_outbound<span style="color: #339933;">=</span>outbound<span style="color: #339933;">;</span>
	_members.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>and then for all messages received, we send them to all members:</p>

<div class="wp_syntax"><div class="code"><pre class="java"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onMessage<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span> frame, <span style="color: #003399;">String</span> data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>ChatWebSocket member <span style="color: #339933;">:</span> _members<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">try</span><span style="color: #009900;">&#123;</span>
			member._outbound.<span style="color: #006633;">sendMessage</span><span style="color: #009900;">&#40;</span>frame,data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			Log.<span style="color: #006633;">warn</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>So we are done, right?&nbsp; We have a working chat room - let&#8217;s deploy it and we&#8217;ll be the next Google GChat!! Unfortunately, reality is not that simple and this chat room is a long way short of the kinds of functionality that you expect from a chat room - even a simple one.</p>
<h2>Not So Simple Chat</h2>
<h3>On Close?</h3>
<p>With a chat room, the standard use-case is that once you establish your presence in the room and it remains until you explicitly leave the room. In the context of webchat, that means that you can send receive a chat message until you close the browser or navigate away from the page. Unfortunately the simple chat example does not implement this semantic because the WebSocket protocol allows for an idle timeout of the connection. So if nothing is said in the chat room for a short while then the WebSocket connection will be closed, either by the client, the server or even an intermediary. The application will be notified of this event by the <code>onClose</code> method being called.</p>
<p>So how should the chat room handle <code>onClose</code>? The obvious thing to do is for the client to simply call join again and open a new connection back to the server:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">_onclose<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._ws<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">join</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This indeed maintains the user&#8217;s presence in the chat room, but is far from an ideal solution since every few idle minutes the user will leave the room and rejoin. For the short period between connections, they will miss any messages sent and will not be able to send any chat themselves.</p>
<h3>Keep-Alives</h3>
<p>In order to maintain presence, the chat application can send keep-alive messages on the WebSocket to prevent it from being closed due to an idle timeout. However, the application has no idea at all about what the idle timeouts are, so it will have to pick some arbitrary frequent period (e.g. 30s) to send keep-alives and hope that is less than any idle timeout on the path (more or less as long-polling does now). <em>Ideally a future version of WebSocket will support timeout discovery, so it can either tell the application the period for keep-alive messages or it could even send the keep-alives on behalf of the application.</em></p>
<p>Unfortunately keep-alives don&#8217;t avoid the need for onClose to initiate new WebSockets, because the internet is not a perfect place and especially with wifi and mobile clients, sometimes connections just drop. It is a standard part of HTTP that if a connection closes while being used, the GET requests are retried on new connections, so users are mostly insulated from transient connection failures. A WebSocket chat room needs to work with the same assumption and even with keep-alives, it needs to be prepared to reopen a connection when <code>onClose</code> is called.</p>
<h3>Queues</h3>
<p>With keep-alives, the WebSocket chat connection should be mostly be a long-lived entity, with only the occasional reconnect due to transient network problems or server restarts. Occasional loss of presence might not be seen to be a problem, unless you&#8217;re the dude that just typed a long chat message on the tiny keyboard of your <a href="http://www.vodafone360.com">vodafone360</a> app or instead of chat you are playing on <a href="http://chess.com/livechess">chess.com</a> and you don&#8217;t want to abandon a game due to transient network issues. So for any reasonable level of quality of service, the application is going to need to &quot;pave over&quot; any small gaps in connectivity by providing some kind of message queue in both client and server. If a message is sent during the period of time that there is no WebSocket connection, it needs to be queued until such time as the new connection is established.</p>
<h3>Timeouts</h3>
<p>Unfortunately, some failures are not transient and sometimes a new connection will not be established. We can&#8217;t allow queues to grow forever and pretend that a user is present long after their connection is gone. Thus both ends of the chat application will also need timeouts and the user will not be seen to have left the chat room until they have no connection for the period of the timeout or until an explicit leaving message is received. </p>
<p><em>Ideally a future version of WebSocket will support an orderly close message so the application can distinguish between a network failure (and keep the user&#8217;s presence for a time) and an orderly close as the user leaves the page (and remove the user&#8217;s present).</em></p>
<h3>Message Retries </h3>
<p>Even with message queues, there is a race condition that makes it difficult to completely close the gaps between connections. If the <code>onClose</code> method is called very soon after a message is sent, then the application has no way to know if that close event happened before or after the message was delivered. If quality of service is important, then the application currently has no option but to have some kind of per message or periodic acknowledgment of message delivery. <em>Ideally a future version of WebSocket will support orderly close, so that delivery can be known for non-failed connections and a complication of acknowledgments can be avoided unless the highest quality of service is required.</em></p>
<h3>Backoff</h3>
<p>With <code>onClose</code> handling, keep-alives, message queues, timeouts and retries, we finally will have a chat room that can maintain a user&#8217;s presence while they remain on the web page. But unfortunately the chat room is still not complete, because it needs to handle errors and non-transient failures. Some of the circumstances that need to be avoided include:</p>
<ul>
<li>If the chat server is shut down, the client application is notified of this simply by a call to <code>onClose</code> rather than an <code>onOpen</code> call. In this case, <code>onClose</code> should not just reopen the connection as a 100% CPU busy loop with result. Instead the chat application has to infer that there was a connection problem and to at least pause a short while before trying again - potentially with a retry backoff algorithm to reduce retries over time. <em>Ideally a future version of WebSocket will allow more access to connection errors, as the handling of no-route-to-host may be entirely different to handling of a 401 unauthorized response from the server</em>.</li>
<li>If the user types a large chat message, then the WebSocket frame sent may exceed some resource level on the client, server or intermediary. Currently the WebSocket response to such resource issues is to simply close the connection. Unfortunately for the chat application, this may look like a transient network failure (coming after a successful <code>onOpen</code> call), so it may just reopen the connection and naively retry sending the message, which will again exceed the max message size and we can lather, rinse and repeat! Again it is important that any automatic retries performed by the application will be limited by a backoff timeout and/or max retries. <em>Ideally a future version of WebSocket will be able to send an error status as something distinct from a network failure or idle timeout, so the application will know not to retry errors</em>.</li>
</ul>
<h2>Does it have to be so hard?</h2>
<p>The above scenario is not the only way that a robust chat room could be developed. With some compromises on quality of service and some good user interface design, it would certainly be possible to build a chat room with less complex usage of a WebSocket. However, the design decisions represented by the above scenario are not unreasonable even for chat and certainly are applicable to applications needing a better QoS that most chat rooms.</p>
<p>What this blog illustrates is that there is no silver bullet and that WebSocket will not solve many of the complexities that need to be addressed when developing robust Comet web applications. Hopefully some features such as keep-alives, timeout negotiation, orderly close and error notification can be build into a future version of WebSocket, but it is not the role of WebSocket to provide the more advanced handling of queues, timeouts, reconnections, retries and backoffs. If you wish to have a high quality of service, then either your application or the framework that it uses will need to deal with these features.</p>
<h2>cometD with WebSocket</h2>
<p><a href="http://cometd.org">cometD</a> version 2 will soon be released with support for WebSocket as an alternative transport to the currently supported JSON long-polling and JSONP callback-polling. cometD supports all the features discussed in this blog and makes them available transparently to browsers with or without WebSocket support. We are hopeful that WebSocket usage will be able to give us even better throughput and latency for cometD than the already <a href="http://blogs.webtide.com/gregw/2008/01/07/1199704334432.html">impressive results</a> achieved with long-polling.</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F02%2Fis-websocket-chat-simple%2F&amp;title=Is+WebSocket+Chat+Simple%3F" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2010/03/02/is-websocket-chat-simple/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building a Better Stock Ticker</title>
		<link>http://cometdaily.com/2010/03/01/building-a-better-stock-ticker/</link>
		<comments>http://cometdaily.com/2010/03/01/building-a-better-stock-ticker/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 07:04:51 +0000</pubDate>
		<dc:creator>JerodVenema</dc:creator>
		
		<category><![CDATA[articles]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[frozen mountain]]></category>

		<category><![CDATA[stocks]]></category>

		<category><![CDATA[websync]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=482</guid>
		<description><![CDATA[One of the most common use-cases for Comet is the ubiquitous stock ticker demo.  Building a stock ticker that has useful functionality is a whole different matter...]]></description>
			<content:encoded><![CDATA[<p>One of the most common use-cases for Comet is the ubiquitous <a href="http://www.frozenmountain.com/libdemos/extjs_demo.aspx">stock ticker demo</a>. There are several reasons why this particular demo is so popular: it&#8217;s easy to understand why people want stock quotes in real-time, it&#8217;s obvious that changes are occurring (even without any user interaction), and at least for a simple demo, it&#8217;s fairly simple to implement.</p>
<p>Although building a demo is quite trivial, building a stock ticker that has useful functionality quickly raises a number of questions, many of which have been directed to me at <a href="http://www.frozenmountain.com">Frozen Mountain</a>. One question in particular has been directed to me multiple times, and is more of a design question: <em>what&#8217;s the best way to implement a stock ticker using Comet</em>?</p>
<p>Note: for the purposes of this article, I&#8217;m going to assume we&#8217;re working with a Comet server built on the <a href="http://svn.cometd.com/trunk/bayeux/bayeux.html">Bayeux protocol</a>, such as <a href="http://www.frozenmountain.com/websync">WebSync</a> or <a href="http://jetty.codehaus.org/jetty/">Jetty</a>).</p>
<h3>The Problem</h3>
<p>The &#8220;best way to implement a stock ticker&#8221; is rather ambiguous, so let&#8217;s take a moment and first define our scenario clearly so we know what the problem really entails.</p>
<p>Let&#8217;s work with a fairly common scenario. Assume each user has a &#8220;portfolio&#8221; of stocks, each stock containing between 10 and 50 points of data (such as min price, max price, current value, etc). Each user also had the ability to show or hide certain data points. Since we&#8217;re talking about 10-50 data points per stock, and we obviously want to avoid sending 5x the amount of necessary data, we want to send each user only the exact set of information they require.</p>
<h3>At First Glance</h3>
<p>If you just take this problem at face value without digging into the details, one approach jumps out pretty quickly. The data set is unique per user, so just send each user their own set of data! This approach would look something like this:</p>
<ul>
<li>Create a unique channel for the user</li>
<li>Build a custom &#8220;portfolio&#8221; object for each user</li>
<li>Change the serialization of that object to only include the properties selected by the user</li>
<li>For every user, when new data arrives, check to see if the new data matches the list of properties the user cares about, and if so, send it to them</li>
</ul>
<p>While this approach would (somewhat) work, it has a couple fairly notable disadvantages:</p>
<ul>
<li>State must be maintained for each user on the server, increasing memory usage substantially</li>
<li>A lot of additional checking needs to be done to determine if the data should be sent</li>
<li>The stock data gets tied directly to a specific user</li>
</ul>
<p>Our first disadvantage, maintaining state, can be resolved with more hardware and persistent storage. Obviously, if we can eliminate the need to maintain state for thousands of users, we reduce the application complexity, remove the need for persistent storage (in case of a soft application reset), and we&#8217;re going to need a lot less hardware. Pretty straightforward.</p>
<p>Our second disadvantage, additional data checking, is less important, but still a hassle. When the data is sent, it has to be checked to make sure it&#8217;s in the list of data this user cares about. If the sum total of the data is nothing, then the request doesn&#8217;t actually need to be sent at all. Not impossible by any stretch of the imagination, but annoying. And software should never be annoying.</p>
<p>Our third disadvantage with this approach, the tight coupling of data to individual users, is a little more interesting. Typically, to get data streaming, the data is published from a separate process - a windows service, linux/unix daemon, whatever. This process contains no information about the web users, and is just managing the data. That means we need to make an adjustment to either the process (to make it aware of the users by using a common storage mechanism, such as a database) or the web application (to make it pre-process the data, such as in WebSync&#8217;s &#8220;BeforePublish&#8221; event, and push the data to the individual users). Neither of these options sound like ideal, and both would still require the web application to be stateful.</p>
<p>So with all these issues, where does that leave us? If we analyze the problems with our &#8220;first glance&#8221; approach, it becomes obvious that the what we&#8217;re looking for is a solution that is both 1) stateless and 2) loosely coupled between the data and users.</p>
<p>Now that we&#8217;ve agreed on that&#8230;let&#8217;s locate that solution!</p>
<h3>Channel Mania</h3>
<p>Let&#8217;s re-state our problem a little, now that we&#8217;ve gotten a little more in-depth. Basically, we need to have a way for any user to be able to access live changes for any, all, or none of the data points. If we think about this in terms of the Bayeux protocol, what we&#8217;re really saying is that <em>each data point needs its own channel.</em></p>
<p>That means no more per-user channels, which in turn means our application can be stateless, which also implies that we can keep our publishing of data separate from our consuming of the data. Ok, interesting. Of course, this solution immediately raises some questions as well. </p>
<p>First, isn&#8217;t creating a channel for every data point a lot of extra overhead? Well, there are two places where we really have to care about overhead: the server process that&#8217;s managing all the messages and the size of the actual message itself. The message size can be easily managed by keeping channel length small, so that&#8217;s not a big problem. The server processing of the messages is actually a very interesting discussion&#8230;</p>
<p>While I can&#8217;t speak for certain about implementations of the Bayeux protocol other than <a href="http://www.frozenmountain.com/websync">WebSync</a>, I believe our implementation may be similar to many others in this particular aspect. WebSync makes using multiple channels a very efficient method of message distribution. In fact, WebSync only actually creates a channel when at least one user subscribes to it, and destroys it once the last subscription to that channel is gone. What that means is that publishing a message to 10,000 channels when users are only subscribed to 5 channels results in 9,995 messages immediately getting discarded, which is the fastest possible operation that can be performed. So we&#8217;re ok on server overhead too.</p>
<h3>Final Result</h3>
<p>Now we&#8217;ve answered our two main objections to this solution: we can keep message sizes small, and having lots and lots of channels is actually a very good thing for efficient message distribution. We&#8217;ve also noted that this solution allows us to reach our goals of statelessness and clean separation of tasks between the publishing and consuming of data. So, as a result, we end up with all kinds of channels, each of which might look something like:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #3366CC;">&quot;/ticker/GOOG/max&quot;</span>
<span style="color: #3366CC;">&quot;/ticker/GOOG/min&quot;</span>
<span style="color: #3366CC;">&quot;/ticker/GOOG/current&quot;</span></pre></div></div>

<p>So the only question that remains is how to actually subscribe to all these channels without creating a ton of additional requests? Well guess what - the Bayeux protocol accounts for this very scenario. When you make a subscribe request, you can subscribe to multiple channels in a single shot:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">client.<span style="color: #006600;">subscribe</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  channels<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;/ticker/GOOG/max&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;/ticker/GOOG/min&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;/ticker/GOOG/avg&quot;</span>
  <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
  onReceive<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// handle the incoming data...args.channel will describe the </span>
      <span style="color: #006600; font-style: italic;">// channel, so if we need to we can update specific table </span>
      <span style="color: #006600; font-style: italic;">// columns, rows, etc.</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Another interesting aspect of this approach is that it is highly extensible. We&#8217;re now able to work with 2D data (stocks => rows, data points => columns) but we can extend our approach out to 3D data with another path portion on the channel such as <code>"/ticker/GOOG/{date}/avg"</code>, and start displaying data in a cube instead of a table! </p>
<p>Man, now I want to make a 3D stock ticker&#8230;</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F03%2F01%2Fbuilding-a-better-stock-ticker%2F&amp;title=Building+a+Better+Stock+Ticker" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2010/03/01/building-a-better-stock-ticker/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lightstreamer 3.6 Released</title>
		<link>http://cometdaily.com/2010/02/22/lightstreamer-36-released/</link>
		<comments>http://cometdaily.com/2010/02/22/lightstreamer-36-released/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 14:17:04 +0000</pubDate>
		<dc:creator>Alessandro Alinone</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[Lightstreamer]]></category>

		<category><![CDATA[Release]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=480</guid>
		<description><![CDATA[Last week we released updated versions of all the Lightstreamer components (which include the server and the client libraries).]]></description>
			<content:encoded><![CDATA[<p>Last week we released updated versions of all the Lightstreamer components (which include the server and the client libraries).</p>
<p>We encourage all the Lightstreamer users to upgrade to the latest version, to take benefit of the many improvements and new features released.</p>
<p>I will summarize some of the major changes below.</p>
<p>Let&#8217;s start with brand new APIs. An official and broadly tested <strong>Silverlight </strong>client library is now available. A simple example, with full source code, is provided within the new SDK. It is <a href="http://www.lightstreamer.com/demos.htm#Silverlight_StockListDemo">visible online</a> too.</p>
<p>The <strong>Flex </strong>client library is now at version 2.0. It has undergone a lot of improvements from all perspectives (features, reliability, and performance), derived from on-the-field experience (Lightstreamer Flex has been adopted by a major financial trading application). The push of native objects encoded with<strong> Action Message Format (AMF)</strong> is now fully supported. If you have complex data structure to push, rather than tabular data, it may be easier and faster to directly process real-time ActionScript objects.</p>
<p>The new <strong>JavaScript </strong>client library, now at version 4.4, has been deeply refactored, to make it cleaner and lighter. The results are very good, with a new library that is actually smaller and faster. Many internal mechanisms have been improved, including the connection sharing system, the network protocol, and the namespace management. An efficient and reliable backward channel has been implemented, which makes it possible to push messages from the client to the server with advanced features, such as delivery notification and automatic batching.</p>
<p>Both the <strong>.NET</strong> and <strong>Java SE</strong> client libraries now support <em>Stream-Sense</em> (the ability to automatically switch between streaming and polling) and mocking interfaces.</p>
<p>The <strong>Lightstreamer Server version 3.6</strong> has a brand new threading model.  We have separated the management of external requests into subtasks related with request parsing, authentication, authorization/execution and subscription. Each subtask is then separated into lower level subtasks devoted to individual tables or items. Hence, compound client requests are now managed in parallel. Furthermore, all subscription requests to the Data Adapter are performed in parallel and asynchronously with respect to the client requests. On the network side, we have made NIO (the Java-based socket management mechanisms) even more scalable, by introducing multiple selectors.</p>
<p>As for the <strong>Adapter Remoting Infrastructure</strong>, now version 1.3, support for disconnected remote Metadata Adapters has been introduced, through the brand new <em>RobustNetworkedMetadataProvider</em>.</p>
<p>I suggest going through the detailed <a href="http://www.lightstreamer.com/share/Changelog.txt">release notes</a>, to learn about all of the enhancements.</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2010%2F02%2F22%2Flightstreamer-36-released%2F&amp;title=Lightstreamer+3.6+Released" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2010/02/22/lightstreamer-36-released/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Comet in Newspapers: The Spanish Lottery Experiment</title>
		<link>http://cometdaily.com/2009/12/22/comet-in-newspapers/</link>
		<comments>http://cometdaily.com/2009/12/22/comet-in-newspapers/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 04:53:21 +0000</pubDate>
		<dc:creator>Jose Maria Arranz</dc:creator>
		
		<category><![CDATA[articles]]></category>

		<category><![CDATA[ajax]]></category>

		<category><![CDATA[Comet]]></category>

		<category><![CDATA[long polling]]></category>

		<category><![CDATA[newspaper]]></category>

		<category><![CDATA[polling]]></category>

		<category><![CDATA[Spanish Christmas Lottery]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=441</guid>
		<description><![CDATA[On December 22nd, the popular Spanish Christmas Lottery took place.   This lottery is arranged by the Spanish Government and has a very long tradition in Spain, especially at Christmas when the rewards are the greatest. ]]></description>
			<content:encoded><![CDATA[<p>On December 22nd, the popular <a href="http://en.wikipedia.org/wiki/Spanish_Christmas_Lottery">Spanish Christmas Lottery</a> took place.   This lottery is arranged by the Spanish Government and has a very long tradition in Spain, especially at Christmas when the rewards are the greatest. </p>
<h3>The Spanish Lottery</h3>
<p>The best prize is big, but the probability to win this reward, &#8220;el Gordo&#8221; (&#8221;the biggest&#8221;), is disappointing, 1/165.750.000, if you just buy one ticket (&#8221;décimo&#8221;) for 20 euros (around $28 USD).</p>
<p>While I would prefer to waste this money in a casino game where the probability to win is not so low, it is very difficult to escape from this well established and popular tradition (beyond gambling).</p>
<p>The raffle is itself a show because nobody knows when the number with &#8220;el gordo&#8221; is going to be chosen from a hopper containing all of numbers because concurrently another hopper contains the prizes (containing the big ones and many small prizes).  Because many more numbers are taken out randomly with minor prizes, the show takes several hours.</p>
<p>An introduction to the Spanish gambling culture is not the objective of this article, the subject is of course Comet. </p>
<p>Several million people follow this Christmas special event over the radio, television and of course the Internet, especially online newspapers. Are these newspapers using a Comet technique to notify users in real-time when the best prizes are known? </p>
<h3>The Experiment</h3>
<p>I have watched the most important Spanish online newspapers (<a href="http://www.elpais.com">elpais.com</a>, <a href="http://www.elmundo.es">elmundo.es</a>, <a href="http://www.abc.es">abc.es</a>, <a href="http://www.20minutos.es">20minutos.es</a>, <a href="http://www.elperiodico.com">elperiodico.com</a>, <a href="http://www.cadenaser.com">cadenaser.com</a>) to check if the number with &#8220;el Gordo&#8221; is shown in real-time (listening to the radio is an effective way to know when this occurs). When it comes to technology, Spanish online newspapers are very advanced and have no reason to envy any other international newspaper.</p>
<p>In spite of this, the answer to the question is&#8230; NO!! </p>
<p>No newspaper was using any kind of Comet technology or even simple Ajax polling.  They all are using a typical full page reload using a timer or a refresh meta tag, typically with an interval of 10 – 15 minutes. This interval is too large and is definitively not real-time in this case. </p>
<p>When &#8220;el Gordo&#8221; was removed from the hopper, people listening to the radio, usually at work (yes, listening to the radio is usually tolerated this day), compulsively reloaded their preferred online newspaper to check the exact number, because this number, obviously, was not shown in their outdated web page. Consequence: some of these newspaper web sites were stalled for a while.</p>
<p><strong>Can Comet help the Spanish Gambling Culture?</strong></p>
<p>Do not take this question too seriously. This &#8220;experiment&#8221; is an excuse, based on a concrete and real example, to speculate about how Comet technologies can be introduced to online newspapers or similar web sites with expected, but unpredictable, spikes in traffic.</p>
<h3>Comet in Online Newspapers</h3>
<p>People like to keep open the main page of their preferred online newspaper to check any change. The main page of an online newspaper is usually (ever?) updated using a simple full page refresh with a JavaScript timer or a refresh meta tag directive.</p>
<p>Full reload of the newspaper&#8217;s main page is especially ugly for users and expensive for the server because it contains a substantial amounts of information. Reloading completely takes time, bandwidth and server resources to rebuild the web page because usually newspapers make use of template processors and sometimes querying databases, as with any typical web application. </p>
<p>Online newspapers are designed for the desktop using JavaScript and large screens. Usually there are alternative mobile versions, but most of them do not use JavaScript. </p>
<p>Excluding from this analysis mobile based versions, newspapers make some use of JavaScript and DHTML because web site designers know that virtually 100% of visitors are using modern browsers like Internet Explorer 6+, or those derived from Gecko (FireFox, Mozilla, Camino…) or WebKit (Safari, Chrome). All of these browsers of course have support for Ajax.</p>
<p>We know there are several non-Ajax techniques for Comet, like the forever page, <a href="http://cometdaily.com/2007/11/05/the-forever-frame-technique/">forever frame</a> or script tag long-polling. These techniques are not as clean as Ajax-based alternatives, so I will limit this analysis to Ajax polling and <a href="http://cometdaily.com/2007/11/15/the-long-polling-technique/">long-polling</a> techniques for this article.</p>
<p>Ajax polling and long-polling can improve the real-time experience of online newspaper readers without excluding users for technological reasons (users with very old browsers are in fact already excluded). </p>
<p>Before trying to add Comet to the news publishing world, one limitation is very important to take into consideration: because most online newspapers are free for users and financed by advertisements, we cannot expense much server power and memory per user because this revenue model only scales with million of readers with a very small cost per user. Web applications for online newspapers are basically stateless. Bandwidth is not a problem because any Comet technique used is a bandwidth saver and usually Comet is a power saver too, but this cannot be said for memory consumption with Comet connection usage.</p>
<p>Comet (Ajax polling or long polling) could be used on two levels:</p>
<ol>
<li>To provide an almost real-time updating service of something specific</li>
<li>As a replacement of the old-fashioned full page reload technique</li>
</ol>
<h3>Specific Real-Time Services Based on Comet</h3>
<p>The Spanish Christmas Lottery is a very good example of a specific service that could be done with Comet. This event is short in duration and occurs over a reasonably small time frame, so it is worth the effort to spend a bit more server power (it depends on the Comet technique used and the update interval). </p>
<p>For instance, using Ajax polling with an interval of one minute or less, the server can send to the client new reward numbers in almost real-time. The return of most of Ajax requests will be empty (almost no server power and bandwidth used) and will help to avoid the issue of compulsive user reload. What is more expensive: X requests with empty responses, or one request with a useless full page reload? It depends on X and how much a full page reload costs.</p>
<p>Long polling can be more bandwidth effective and can offer the user instant notification, but the server cost can increase because it needs more server resources (connections and memory).</p>
<p>Other similar use cases are notification events of breaking news or during sports games.</p>
<h4>The ItsNat Approach</h4>
<p>Using <a href="http://cometdaily.com/2008/10/07/server-centric-comet-with-itsnat/">ItsNat</a>, this can be easily achieved using an <a href=" http://www.innowhere.com:8080/itsnat/feashow_servlet?itsnat_doc_name=feashow.main&#038;feature=feashow.core.listeners.timers.ex">Ajax timer</a> (polling). </p>
<p>On the server, because the dynamic zone is small, most of the server DOM will be declared as static, cached as text (DOM serialized as markup) and shared between all users reducing to the minimum the server memory used per user (client page). ItsNat caching is very important because the memory used by a user must be very small to keep the business need of low small cost per user.</p>
<p>Another alternative is having a fully-static server-side DOM (hence fully cached and shared between users) and dynamic changes served from server as JavaScript code (calling ItsNatDocument.addCodeToSend(String)) to the client to render the dynamic zone usually with the help of a JavaScript framework. In spite of ItsNat, this case is a client-centric solution and ItsNat can be replaced with another technology on the server and toolkits like Dojo can provide Ajax polling.</p>
<h3>Replacing the Full Page Reload Technique with Comet</h3>
<p>This problem is, by far, more complex.</p>
<p>With Comet, the web page would change partially and only if necessary, avoiding full reloads, reducing server power and bandwidth. However, adding Comet may be analyzed with care because in this context one important piece of this puzzle is server memory. The web application of a newspaper is basically stateless, there is not very much personalization and all users usually see the same content. Adding too much state to the server can increment the server costs (as said before in a service financed with ads), that is to say the web application must remain mainly stateless.</p>
<p><strong>Investigating strategies:</strong></p>
<p>A) Client-centric Approach:</p>
<p>In this kind of problem a JavaScript framework with Comet capabilities like <a href="http://dojotoolkit.org/">Dojo</a> seems to shine because &#8220;the application&#8221; is brought to the client and only the strictly necessary user data lives in the server because the client is responsible to keep track of visual rendering and state. For instance the server can instruct the client using Comet (polling or long polling) to render new news, to change the ads showed and so on. </p>
<p>But in this case, what is the application? The main page of a newspaper is an interesting example of a highly flexible web application where data and visual appearance are changing frequently. Sometimes these changes are unpredictable when something very important occurs. </p>
<p>Partially updating this kind of page in an unpredictable &#8220;application&#8221; is hard to drive and code using JavaScript, because the client code may be outdated, and new code should be injected replacing the old code (the client needs to be &#8220;reprogrammed&#8221;). </p>
<p>Maybe the most effective action in this case is to notify the client for a full page reload (for instance sending a window.location.reload(true)). So the promise of no full reload is not fulfilled in all cases.</p>
<p>B) Server-centric Approach:</p>
<p>Usually Ajax based server-centric frameworks keep track of the visual state in the server, any change in data model is rendered and the client is updated accordingly. If any part of the web page can change, the page is fully dynamic and must be fully saved in the server. This visual state can use too much memory (maybe valid in any typical web application but not for a newspaper). ItsNat is no different because it uses DOM to save this state in server and in theory any part of the page can change (no caching). </p>
<p>Another problem: if any part of the web page can change, how do you modify the visual state within the server memory <em>programmatically</em> without discarding the current state? In theory ItsNat can fully change the page in server and in client with no reload, so an interesting approach would be to change the original file template and automatically update the DOM tree of the live page with changes. This is an interesting approach to investigate. </p>
<p>The easier solution in ItsNat is to update the file template in server accordingly, notify the server of this change and with a long-polling event, or when the client queries the server to detect any new change (Ajax polling), the server will send a window.location.reload(true) JavaScript instruction or similar to fully update the page. In this case the visual state in the server is almost useless because the page is fully reloaded when something important changes, and the partial update requisite is not fulfilled. So again the promise of no full page reload is not fulfilled. </p>
<h3>Conclusion</h3>
<p>A newspaper is not a typical predictable and fixed web application. Comet (Ajax polling or long-polling) can be used to partially update some concrete and predictable parts of the web page with client or server-centric strategies, and the cost per user may be acceptable. </p>
<p>If the visual structure of the page randomly changes the most effective strategy is a full reload because the &#8220;application&#8221; has changed and the visual state saved in server and in client is no longer valid and is very hard to update partially. In this case Comet (polling and maybe long-polling) can be used to detect when the page must be fully reloaded, saving significant bandwidth and server power, but the promise of partial rendering of any part of the page is not fulfilled, so typical Ajax approaches, both client and server-centric may be too inflexible and/or consume too much memory.</p>
<p>This article speculates about how to introduce Comet in the main page of online newspapers, this problem is relatively new and open to ideas and experiences. </p>
<p>What do you think?<br />
What kind of strategy would you choose?</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F22%2Fcomet-in-newspapers%2F&amp;title=Comet+in+Newspapers%3A+The+Spanish+Lottery+Experiment" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2009/12/22/comet-in-newspapers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Comet to Follow Server Threads Progression</title>
		<link>http://cometdaily.com/2009/12/21/comet-to-follow-server-threads-progression/</link>
		<comments>http://cometdaily.com/2009/12/21/comet-to-follow-server-threads-progression/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 07:48:50 +0000</pubDate>
		<dc:creator>Jose Maria Arranz</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[Comet]]></category>

		<category><![CDATA[CometNotifier]]></category>

		<category><![CDATA[ItsNat]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[threads]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=474</guid>
		<description><![CDATA[Joseph McCarthy from IBM Ireland has written a tutorial, "Using Comet for asynchronous user notification of autonomous server thread progression", about how to use polling and Comet (long-polling) in Java.]]></description>
			<content:encoded><![CDATA[<p>Joseph McCarthy from IBM Ireland has written a tutorial, <a href="http://www-10.lotus.com/ldd/portalwiki.nsf/dx/Using_Comet_for_asynchronous_user_notification_of_autonomous_server_thread_progression">&#8220;Using Comet for asynchronous user notification of autonomous server thread progression&#8221;</a> about how to use polling and Comet (long-polling) in Java with the <a href="http://www.itsnat.org">ItsNat</a> Java web framework to asynchronously notify end users through web the progression of an autonomous thread (not a web thread) executing a long task in parallel. This article is &#8220;inspired&#8221; on <a href="http://cometdaily.com/2009/03/25/itsnat-v06-released-comet-long-polling-now-event-based/">this musing</a> published here at Comet Daily and <a href="http://www.innowhere.com:8080/itsnat/feashow_servlet?itsnat_doc_name=feashow.main&#038;feature=feashow.core.listeners.cometNotifier.ex">this complete</a> example.</p>
<p>The problem selected is to calculate the PI number through <a href="http://en.wikipedia.org/wiki/Leibniz_formula_for_pi">Gregory-Leibniz</a> series. This calculation takes significant time if you want high precision.</p>
<p>The objective of the article is monitoring via the web this server thread with no user interaction, periodically obtaining the estimated value and of course asynchronously notifying to the end user when the calculation has finished. As a bonus, the user can start and stop the server thread through web buttons.</p>
<p>The article has two parts/approaches:</p>
<p>1) In the first part the &#8220;polling&#8221; technique is used (through the use of a meta refresh directive) alongside Ajax to query the thread state, conventional page navigation technology to start and stop the thread and global variables to hold the thread and calculation states. No specific web framework is used (just servlets and JSPs).</p>
<p>2) The second part uses Comet (long-polling) provided by the <a href="http://www.itsnat.org">ItsNat</a> framework. In this case the application is a <a href="http://www.uxmatters.com/mt/archives/2006/11/improving-user-workflows-with-single-page-user-interfaces.php">single page interface</a> and the thread is only attached to the user&#8217;s page. In this case a CometNotifier object provided by ItsNat is &#8220;attached&#8221; to the web page and to the calculator thread.</p>
<p>Note: the original article has an annoying visual problem, to read it I recommend using MSIE 6 (yes in this case a non-W3C CSS compliant browser is great) or Firefox disabling styles (View/Page Style/No Style).</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fcomet-to-follow-server-threads-progression%2F&amp;title=Comet+to+Follow+Server+Threads+Progression" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2009/12/21/comet-to-follow-server-threads-progression/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Jetty WebSocket Server</title>
		<link>http://cometdaily.com/2009/12/21/jetty-websocket-server/</link>
		<comments>http://cometdaily.com/2009/12/21/jetty-websocket-server/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 07:04:51 +0000</pubDate>
		<dc:creator>GregWilkins</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[Comet]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[jetty]]></category>

		<category><![CDATA[servlet]]></category>

		<category><![CDATA[websocket]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=475</guid>
		<description><![CDATA[Jetty's async IO architecture is ideally suited to providing a very scalable implementation of WebSocket that is well integrated with standard server-side java application environments.]]></description>
			<content:encoded><![CDATA[<p>WebSocket is an API and a Protocol that have come from the <a href="http://www.whatwg.org/">Whatwg</a> for the purposes of improving Comet support in the browser and on the network.  The API is now being <a href="http://dev.w3.org/html5/websockets/">standardized by the W3C</a> and the IETF is considering creating a <a href="http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol">WebSocket working group</a> to standardize the protocol.</p>
<p>I&#8217;m not a big fan of the WebSocket protocol, as evidenced by my <a href="http://blogs.webtide.com/gregw/entry/how_to_improve_websocket">blog on how to improve WebSocket</a>, <a href="http://bwtp.wikidot.com/main:rational">the BWTP proposal</a> and/or <a href="http://www.ietf.org/mail-archive/web/hybi/current/maillist.html">the IETF Hybi mailing list</a>.  But Chrome and Firefox will soon be supporting WebSocket, so WebSocket (for better or for worse) will soon be available in the wild.</p>
<p>So if you can&#8217;t beat them, join them.  Having failed to convince others to create a better protocol, I&#8217;m now determined for <a href="http://eclipse.org/jetty">Jetty</a> to provide the best implementation of the protocol and to become the server of choice for WebSocket Comet development, deployment ( and experimenting with improving the protocol).</p>
<p>Jetty&#8217;s async IO architecture is ideally suited to providing a very scalable implementation of WebSocket that is well integrated with standard server-side java application environments.   Thus Jetty-7.0.1 now includes a <a href="http://wiki.eclipse.org/Jetty/Feature#WebSocket">WebSocket server</a>. Feedback welcome!</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F21%2Fjetty-websocket-server%2F&amp;title=Jetty+WebSocket+Server" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2009/12/21/jetty-websocket-server/feed/</wfw:commentRss>
		</item>
		<item>
		<title>cometD 1.0.1 Released</title>
		<link>http://cometdaily.com/2009/12/18/cometd-101-released/</link>
		<comments>http://cometdaily.com/2009/12/18/cometd-101-released/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 16:58:34 +0000</pubDate>
		<dc:creator>DylanSchiemann</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[cometd]]></category>

		<category><![CDATA[dojo]]></category>

		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=479</guid>
		<description><![CDATA[cometD 1.0 was recently released with a great set of features, and includes Comet clients for Dojo and jQuery.]]></description>
			<content:encoded><![CDATA[<p>The cometD project recently reached the 1.0 milestone!</p>
<blockquote><p>
The CometD project ships the following libraries to develop comet web applications:</p>
<p>    * A JavaScript library, with bindings for the well known Dojo and jQuery toolkits<br />
    * A Java client library, to be used, for example, in rich Java clients such as Swing applications<br />
    * A Java server library, to be used to implement the logic behind you application
</p></blockquote>
<p>The Bayeux protocol is considered complete as well.  The Python and Perl versions of the cometD server are not yet production quality, and the project is seeking contributors to help get those servers improved.</p>
<p>Maven users will enjoy the simplicity of getting up and running:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ mvn archetype:generate -<span style="color: #007800;">DarchetypeCatalog=</span>http:<span style="color: #000000; font-weight: bold;">//</span>cometd.org
...
$ mvn <span style="color: #c20cb9; font-weight: bold;">install</span> jetty:run</pre></div></div>

<p>The <a href="http://blogs.webtide.com/sbordet/entry/cometd_1_0_released">cometD 1.0 announcement blog</a> has more details, and there&#8217;s also a lengthy article on <a href="http://blogs.webtide.com/gregw/entry/cometd_features_and_extensions">cometD features and extensions</a>.</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F18%2Fcometd-101-released%2F&amp;title=cometD+1.0.1+Released" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2009/12/18/cometd-101-released/feed/</wfw:commentRss>
		</item>
		<item>
		<title>APE (Ajax Push Engine) 1.0</title>
		<link>http://cometdaily.com/2009/12/12/ape-ajax-push-engine-10/</link>
		<comments>http://cometdaily.com/2009/12/12/ape-ajax-push-engine-10/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 03:13:08 +0000</pubDate>
		<dc:creator>DylanSchiemann</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[ape]]></category>

		<category><![CDATA[weeyla]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=478</guid>
		<description><![CDATA[Weeyla has released version 1.0 of APE (Ajax Push Engine), an open-source Comet server.]]></description>
			<content:encoded><![CDATA[<p>Weeyla has released <a href="http://www.ape-project.org/">version 1.0 of APE</a> (Ajax Push Engine), an open-source Comet server.  APE is available under a GPL license and was developed in C.</p>
<p>The project includes a server and a JavaScript framework that is a derivative of MooTools (though it of course works with Dojo, jQuery, and other JavaScript toolkits).  APE uses a pub/sub model with its own protocol, and states that it currently scales to more than 100,000 concurrent users.  It has some similarities to Orbited in its approach of many other protocols and TCPSockets.</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F12%2Fape-ajax-push-engine-10%2F&amp;title=APE+%28Ajax+Push+Engine%29+1.0" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2009/12/12/ape-ajax-push-engine-10/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mibbit Adding WebSocket Support</title>
		<link>http://cometdaily.com/2009/12/11/mibbit-adding-websocket-support/</link>
		<comments>http://cometdaily.com/2009/12/11/mibbit-adding-websocket-support/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 17:28:21 +0000</pubDate>
		<dc:creator>DylanSchiemann</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[mibbit]]></category>

		<category><![CDATA[websocket]]></category>

		<guid isPermaLink="false">http://cometdaily.com/?p=477</guid>
		<description><![CDATA[Mibbit recently conducted some WebSocket performance tests with promising results.]]></description>
			<content:encoded><![CDATA[<p>Mibbit is <a href="http://axod.blogspot.com/2009/12/websocket-some-numbers.html">enabling support for WebSocket after running some promising initial tests</a>.  Mibbit is being aggressive in adding WebSocket support as they have a much higher than normal percentage of Google Chrome users, which now implements WebSocket.</p>
<p>Probably the most interesting point from the performance tests was the conclusion that WebSocket does not yet address compression which can impact overall bandwidth sent across the wire, leading HTML5 lead Hixie to comment that if people want compression, it will be added to the next version as an option.</p>


<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fcometdaily.com%2F2009%2F12%2F11%2Fmibbit-adding-websocket-support%2F&amp;title=Mibbit+Adding+WebSocket+Support" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://cometdaily.com/2009/12/11/mibbit-adding-websocket-support/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
