tag:blogger.com,1999:blog-8406930530301959642024-03-12T19:13:21.719-07:00StreamHub Comet BlogA blog by the guys behind StreamHub Comet Server covering tutorials, news and articles about Comet, HTTP Push, Reverse Ajax and everything else in the streaming world.StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-840693053030195964.post-41052166423865904562011-01-01T09:42:00.000-08:002011-01-01T09:48:40.149-08:00New Community Edition License for 2011A new Community Edition License for 2011 has been released. This extends the Community license until 2012. Download below:<div><br /></div><div><ul><li><a href="http://www.stream-hub.com/downloads/2011communitylicense/license.txt">2011 Community License</a></li></ul></div><div><br /></div><div><div><b>Instructions for use</b></div><div><br /></div><div>Copy the license.txt to the folder where StreamHub server is started from - StreamHub reads the license file from its current working directory. If you have an existing license.txt in that directory we recommend you back this file up before overwriting it.</div></div><div><br /></div><div>Happy 2011 from all the StreamHub Team!!</div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-27410683783449250282010-12-04T06:43:00.000-08:002010-12-04T07:19:15.919-08:00HTML 5 Web Sockets arrives in StreamHub 2.2.9Some of you may have noticed HTML 5 Web Sockets sneaking into 2.2.x releases of StreamHub but now it's officially here. 2.2.9 brings full Web Sockets functionality for browsers that support it. Comet will still be supported for older browsers and those that don't yet support the latest HTML 5 standards. Detection of the most reliable connection-type is built-in, with transparent failover to Comet and Ajax Polling. This means you don't need to make any changes to your existing code to start using Web Sockets, StreamHub will automatically detect the best connection-type for you.<br /><br /><span style="font-weight:bold;">Current Web Sockets Support in Browsers</span><br /><br /><ul><li>Google Chrome</li><li>Apple Safari 5+</li><li>Firefox 4 Beta</li><li>Apple iOS 4.2+ for iPad & iPhone</li></ul><br /><b>What else is new in 2.2.9?</b><br /><br />2.2.9 has come a long way since the popular stable 2.0.x branch. So, here's a complete set of release notes for those looking to upgrade from 2.0.x.<br /><br /><ul><li>Fixed (2.2.9): Web Socket handshake intermittent issues</li><li>Fixed (2.2.8): Expensive debug string operation being performed on all log levels</li><li>Fixed (2.2.7): Firefox 3.x Comet reconnection bug when hitting 300k limit</li><li>Fixed (2.2.7): MAX_CLIENT_LIMIT was disconnecting most recent WebSocket client</li><li>(2.2.7): HTTP file handling improvements</li><li>(2.2.7): Logging improvements</li><li>(2.2.7): Upgrade to support secure Web Socket handshakes</li><li>(2.2.4): Performance improvements</li><li>(2.2.4): HTML5 Web Sockets support</li><li>(2.2.4): Ability to monitor number of connected clients via JMX</li><li>Fixed (2.2.4): Possible NPE in Dispatcher</li><li>(2.1.x-beta): Numerous performance improvements to the HTTP handling.</li><li>(2.1.x-beta): Transparent failover to polling connections where firewalls/proxies prevent full duplex streaming.</li><li>Fixed (2.1.x-beta): Ajax adapter was not reconnecting if no serverList was specified.</li><li>Fixed (2.1.x-beta): 'Stopping polling' log message appeared even when not using a polling connection type.</li><li>(2.1.x-beta): More control over HTTP headers for pages and comet content.</li></ul><br /><span style="font-weight:bold;">Important note when upgrading from 2.0.x</span><br /><br />If you migrate any existing Ajax SDK apps from 2.0.x to 2.1 or 2.2 you will need to change your connection URLs to incorporate the new streamhub context. For example, if previously you were using:<br /><br /><pre name="code" class="js:nogutter"><br />hub.connect("http://localhost:7979/");<br /></pre> <br /><br />You will now need to use:<br /><br /><pre name="code" class="js:nogutter"><br />hub.connect("http://localhost:7979/streamhub/");<br /></pre><br /><br /><span style="font-weight:bold;">Get the latest version</span><br /><br />Find the latest 2.1.12-beta available to download below aswell as links to the most up-to-date documentation and tutorials:<div><br /><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub HTML5 Web Sockets & Comet Server 2.2.9</a></li><li><a href="http://www.stream-hub.com/doc/2.2.9/javadoc/">Latest 2.2.9 Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.2.9/jsdoc/">Latest 2.2.9 AJAX SDK docs</a></li><li><a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax & Comet</a></li></ul><br />More coming soon, as usual, subscribe to this blog or follow us on twitter to keep up to date.<br /></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-63965168693243964892010-04-25T04:55:00.000-07:002010-04-25T05:38:19.933-07:00StreamHub 2.1.12 beta Release - Server Integration Is HereA brand new beta version of the <a href="http://www.stream-hub.com/">StreamHub Reverse Ajax & Comet Server</a> has been released today. The new 2.1 branch has been under development for months and has finally been released as a beta. The tagline for the 2.1 release is 'Server Integration'. Changes in the way StreamHub works now allow you to integrate Tomcat, Apache, JBoss, IIS or any other HTTP server with StreamHub, without comprimising on the highly-scalable streaming performance.<div><br /></div><div>Using configureable contexts, StreamHub can be configured to transparently serve content from any downstream server. The core StreamHub NIO engine can sit in front of one or more web servers and routes requests to either the internal Comet engine or to the web servers behind.</div><div><br /></div><div>To use this new feature, you'll need to setup a <span class="Apple-style-span" style="font-family:'courier new';">ForwardingHandler</span>:</div><div><div><br /><pre name="code" class="java:nogutter"><br />PushServer streamingServer = new NIOServer(80);<br />InetSocketAddress tomcatAddress = new InetSocketAddress(InetAddress.getLocalHost(), 8080);<br />streamingServer.addContext("/*", new ForwardingHandler(tomcatAddress));<br />streamingServer.start();<br /></pre><br /></div><br /><div>The example above will route any requests for <span class="Apple-style-span" style="font-family:'courier new';">http://myhost.com/</span> to a Tomcat instance running on port 8080 on the same host but the user will still see <span class="Apple-style-span" style="font-family:'courier new';">http://myhost.com/</span> in their browser. By default, any requests to the <span class="Apple-style-span" style="font-family:'courier new';">/streamhub/*</span> context will be routed to StreamHub's internal Comet engine. That means, if you migrate any existing Comet apps to 2.1 you will need to change your connection URLs. For example, if previously you were using:</div><div><br /><pre name="code" class="js:nogutter"><br />hub.connect("http://localhost:7979/");<br /></pre><br /></div><div>From 2.1 onwards you will need to use:</div><div><br /><pre name="code" class="js:nogutter"><br />hub.connect("http://localhost:7979/streamhub/");<br /></pre><br /></div><div>The default <span class="Apple-style-span" style="font-family:'courier new';">/*</span> context handler will use StreamHub's existing content handler, so you don't need to add a ForwardingHandler by default. The <span class="Apple-style-span" style="font-family:'courier new';">/*</span> context handler will also act as a catch-all handler. Potentially you can have as many handlers as you like, routing different contexts to different physical servers.</div><div><br /></div><div><b>What else is new in 2.1?</b></div><div><ul><li>Numerous performance improvements to the HTTP handling.</li><li>Transparent failover to polling connections where firewalls/proxies prevent full duplex streaming.</li><li>Fixed: Ajax adapter was not reconnecting if no <span class="Apple-style-span" style="font-family:'courier new';">serverList</span> was specified.</li><li>Fixed: 'Stopping polling' log message appeared even when not using a polling connection type.</li><li>More control over HTTP headers for pages and comet content.</li></ul><div><br /></div><div><b>Transparent failover to polling</b></div><div><b><br /></b></div><div>The StreamHub Ajax SDK always attempts to establish the best connection possible with the server. Where a true streaming connection cannot be established, normally because a proxy or firewall is attempting to read the entire connection before forwarding, StreamHub will now failover to a polling connection without interrupting the users experience.</div><div><br /></div><div><br /></div><div><b>HTTP header control</b></div><div><b><br /></b></div><div>Two new methods have been introduced to the <span class="Apple-style-span" style="font-family:'courier new';">PushServer</span> interface to give you more control over the HTTP headers that StreamHub sends out. StreamHub will send a different set of headers for synchronous requests (e.g. subscriptions), than those it will send out for asynchronous push requests (e.g. the streaming channel). You now can override or set your own default headers for both of these types of request.</div><div><br /></div><div>The example below, allows you to control the charset of data added to a <span class="Apple-style-span" style="font-family:'courier new';">JsonPayload</span>:</div><div><br /><pre name="code" class="js:nogutter"><br />server.setDefaultPushHeader("Content-Type", "text/html; charset=UTF-8");<br /></pre><br /></div><div><br /></div><div><div><b>Get the latest version</b></div><div><br /></div><div>Find the latest 2.1.12-beta available to download below aswell as links to the most up-to-date documentation and tutorials:</div><div><ul><li><a href="http://www.stream-hub.com/download-page.html?download=streamhub-2.1.12-beta.zip">Download StreamHub Reverse Ajax & Comet Server 2.1.12-beta</a></li><li><a href="http://www.stream-hub.com/doc/2.1.12-beta/javadoc/">Latest 2.1.12-beta Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.1.12-beta/jsdoc/">Latest 2.1.12-beta AJAX SDK docs</a></li><li><a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax & Comet</a></li></ul></div><div><br /></div><div>More coming soon, as usual, subscribe to this blog or <a href="http://twitter.com/streamhub">follow us on twitter</a> to keep up to date.</div></div><div><br /></div></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-49896210664751171992010-01-30T10:21:00.000-08:002010-01-30T13:38:52.396-08:00StreamHub Reverse Ajax Server 2.0.14 ReleasedA new version of the <a href="http://www.stream-hub.com/">StreamHub Reverse Ajax & Comet Server</a> has been released today. This version contains a critical fix for those running StreamHub server on Linux. A bug has been fixed where certain conditions can cause the CPU usage to be unusually high. The problem was caused by an interaction with the underlying syscalls in Linux and has now been fixed. The bug should not effect Windows users. Linux users are recommended to upgrade as soon as possible to version 2.0.14 or later. A full list of the changes in this release can be found below:<div><ul><li>Fixed - CPU thrashing on Linux.</li><li>Fixed - Minor bug when a single client is subscribed, a wayward unsubscribe by another client could remove them.</li><li>Release version now printed to StreamHub Server log files.</li><li>New experimental option in the Ajax SDK to use a polling connection type instead of streaming.</li></ul><div><div><b>Get the latest version</b></div><div><br /></div><div>Find the latest version available to download below aswell as links to the most up-to-date documentation and tutorials:</div><div><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub Reverse Ajax & Comet Server</a></li><li><a href="http://www.stream-hub.com/doc/2.0.14/javadoc/">Latest 2.0.14 Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.0.14/jsdoc/">Latest 2.0.14 AJAX SDK docs</a> - See <a href="http://www.stream-hub.com/doc/2.0.14/jsdoc/symbols/StreamHub.html#connect">StreamHub.connect(...)</a> for the new experimental <span class="Apple-style-span" style="font-family:'courier new';">connectionType</span> option.</li><li><a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax & Comet</a></li></ul></div><div><br /></div><div>More coming soon, as usual, subscribe to this blog or <a href="http://twitter.com/streamhub">follow us on twitter</a> to keep up to date.</div></div><div><br /></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-89596148182186865662010-01-01T12:07:00.000-08:002010-01-01T12:15:36.808-08:00Community Edition Licenses ExtendedIf you are getting this message when running the Community Edition:<div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">StreamHub not started: License has expired</span></div><div><br /></div><div>Then you may be using an old Community Edition License. To fix this problem, download the latest version (2.0.12 or greater), available from the <a href="http://www.stream-hub.com/download.html">StreamHub download page</a>. If you do not wish to upgrade from the version you are currently using, just copy the <span class="Apple-style-span" style="font-family:'courier new';">license.txt</span> file from the new version and overwrite your existing <span class="Apple-style-span" style="font-family:'courier new';">license.txt</span>. Because of changes to the licensing behaviour, this may not work with versions prior to 2.0.6. In this case, we suggest you upgrade to the latest version. Please use our <a href="http://groups.google.co.uk/group/streamhub-comet-server-community">StreamHub Comet Forum</a> if you experience any problems upgrading.</div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-90209336626135912342009-12-13T11:36:00.000-08:002009-12-13T11:45:57.965-08:00StreamHub Comet Server 2.0.11 ReleaseThis minor release of <a href="http://www.stream-hub.com/">StreamHub Reverse Ajax & Comet Server</a> brings with it a few bug fixes and full Unicode support. The major changes are listed below:<div><br /></div><div><ul><li>Unicode support for international charsets.</li><li>Fixes for the <a href="http://streamhub.blogspot.com/2009/11/streamhub-2010-released-new-demos.html">connection listener</a> in Firefox 2+ & 3+.</li></ul><div><span class="Apple-style-span" style=" color: rgb(51, 51, 51); line-height: 20px; font-size:13px;"><div><span class="Apple-style-span" style="font-size:130%;color:#000000;"><span class="Apple-style-span" style=" line-height: normal;font-size:16px;"><span class="Apple-style-span" style="color:#333333;"><span class="Apple-style-span" style=" line-height: 20px;font-size:-webkit-xxx-large;"><b><br /></b></span></span></span></span></div></span></div><div><b>Get the latest version</b></div><div><br /></div>Find the latest version available to download below aswell as links to the most up-to-date documentation and tutorials:<br /><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub Reverse Ajax & Comet Server</a></li><li><a href="http://www.stream-hub.com/doc/2.0.11/javadoc/">Latest Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.0.11/jsdoc/">Latest AJAX SDK docs</a></li><li><a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax & Comet</a></li></ul><p>More coming soon, as usual, subscribe to this blog or <a href="http://twitter.com/streamhub">follow us on twitter</a> to keep up to date.</p></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-52987390803699930982009-11-26T17:28:00.001-08:002009-11-27T09:41:58.464-08:00StreamHub 2.0.10 Released. New Demos & Connection Listener!<div style="text-align: left;">We've just released a new version of the StreamHub Reverse Ajax & Comet Server. We've added a whole bunch of new stuff, details below:</div><div><ul><li>New jQuery Grid Plugin Demos</li><li>New Example Fixed Income streaming data</li><li>New Ext-GWT Demo</li><li>Fix for the 'queue is full - disconnecting' loop bug</li><li>Clients who recently lost connection and are in the reconnection state now do not count towards the maximum user limit</li><li>StreamHub now distinguishes between deliberate user disconnects and clients losing connection in the logs</li><li>A connection listener has been added to the Ajax SDK</li></ul><div><b>Using the new Ajax SDK Connection Listener</b></div><div style="text-align: center;"><b><br /></b></div><div>To use the new connection listener, you'll first need to create your own custom listener code. For example, to alert everytime the connection goes up or down, add the following JavaScript to your host page:</div><div><pre name="code" class="js:nogutter"><br />var connectionListener = new StreamHub.ConnectionListener();<br />connectionListener.onConnectionEstablished = function () {<br /> alert("Connection up");<br />};<br />connectionListener.onConnectionLost = function () {<br /> alert("Connection down");<br />};<br /></pre></div><div><br /></div><div>Then, before you connect, just add your new connection listener:</div><div><pre name="code" class="js:nogutter"><br />var hub = new StreamHub();<br />hub.addConnectionListener(connectionListener);<br />// now connect as normal...<br /></pre></div><div><br /></div><div>You can add as many connection listeners as you like. The alerting example is pretty simple, you will probably want to do something more useful such as add a connection monitor on your page which is green when the connection is up and red when its down. Lets go ahead and add such a connection monitor to one of the examples which come with the StreamHub SDK. Navigate to the <span class="Apple-style-span" style="font-family:'courier new';">examples\StockDemo</span> directory of the SDK and edit the <span class="Apple-style-span" style="font-family:'courier new';">index.html</span> file. Add the following <span class="Apple-style-span" style="font-family:'courier new';">div</span> element just above the closing <span class="Apple-style-span" style="font-family:'courier new';">body</span> tag:</div><div><pre name="code" class="html:nogutter"><br /><div id="connectionMonitor" style="width: 120px; border: 1px black solid; background-color: yellow">Not connected</div><br /></pre></div><div><br /></div><div>Then change the code between the last <span class="Apple-style-span" style="font-family:'courier new';">script</span> tags to the following:</div><div><pre name="code" class="js:nogutter"><br />var connectionListener = new StreamHub.ConnectionListener();<br />connectionListener.onConnectionEstablished = function () {<br /> var connectionMonitor = document.getElementById('connectionMonitor');<br /> connectionMonitor.innerHTML = "Connected";<br /> connectionMonitor.style.backgroundColor = "green";<br />};<br />connectionListener.onConnectionLost = function () {<br /> var connectionMonitor = document.getElementById('connectionMonitor');<br /> connectionMonitor.innerHTML = "Disconnected";<br /> connectionMonitor.style.backgroundColor = "red";<br />};<br /><br />var hub = new StreamHub();<br />hub.addConnectionListener(connectionListener);<br />var sServerUrl = "http://localhost:7979/";<br />hub.connect(sServerUrl);<br />hub.subscribe("BA", priceChangeListener);<br />hub.subscribe("BAC", priceChangeListener);<br />hub.subscribe("C", priceChangeListener);<br />hub.subscribe("KO", priceChangeListener);<br />hub.subscribe("MCD", priceChangeListener);<br />hub.subscribe("WMT", priceChangeListener);<br /></pre><br /></div><div>Open the StockDemo at http://localhost:7979/StockDemo/index.html and you should see the connection monitor in action. See the screenshot below for an example of the finished item:</div><div><br /></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iuc0yuQCrFc/Sw84q_11JrI/AAAAAAAAACE/lJ5tqoRc8Dc/s1600/disconnectedImage.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 249px;" src="http://2.bp.blogspot.com/_iuc0yuQCrFc/Sw84q_11JrI/AAAAAAAAACE/lJ5tqoRc8Dc/s320/disconnectedImage.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5408603988838131378" /></a><br /></div><div><br /></div><div></div><div><b>New examples overview</b></div><div><br /></div><div>We've added three new examples to this version. Two show how to use the versatile jQuery Grid Plugin. The first just displays a simple grid of stock prices.</div><div><br /></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iuc0yuQCrFc/Sw84ie81CFI/AAAAAAAAAB8/tjNmEzxHnkM/s1600/comet-jquery-1.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 134px;" src="http://4.bp.blogspot.com/_iuc0yuQCrFc/Sw84ie81CFI/AAAAAAAAAB8/tjNmEzxHnkM/s320/comet-jquery-1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5408603842570160210" /></a></div><div><br /></div><div>The second uses the new example Fixed Income data. It shows how to use a larger grid, how to use a different theme and how to highlight rows using the 'ui-hover' class so the row highlight is tied to the jQuery UI theme.</div><div><br /></div><div><br /></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iuc0yuQCrFc/Sw84CzCDs3I/AAAAAAAAAB0/Zbe-6ZKPxyc/s1600/comet-jquery-2.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 118px;" src="http://4.bp.blogspot.com/_iuc0yuQCrFc/Sw84CzCDs3I/AAAAAAAAAB0/Zbe-6ZKPxyc/s320/comet-jquery-2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5408603298204988274" /></a></div><div><br /></div><div>The third new example uses Ext GWT to create a simple sortable grid with custom green/red formatters and the option to hide/show columns.</div><div><br /></div><div><br /></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iuc0yuQCrFc/Sw8409zVxQI/AAAAAAAAACM/RGFvskz_5NM/s1600/ext-gwt-comet.png" style="text-decoration: none;"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 125px;" src="http://2.bp.blogspot.com/_iuc0yuQCrFc/Sw8409zVxQI/AAAAAAAAACM/RGFvskz_5NM/s320/ext-gwt-comet.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5408604160089507074" /></a></div><div><br /></div><div>The full source code for the Ext GWT demo is available from the <a href="http://code.google.com/p/gwt-comet-streamhub/source/checkout">GWT Comet Adapter source website</a>. The main classes are <a href="http://code.google.com/p/gwt-comet-streamhub/source/browse/trunk/ExtGwtApp/src/com/demo/client/ExtGwtApp.java">ExtGwtApp.java</a> and <a href="http://code.google.com/p/gwt-comet-streamhub/source/browse/trunk/ExtGwtApp/src/com/demo/client/Stock.java">Stock.java</a>.</div><div><br /></div><div><b><br /></b></div><div><b>Get the latest version</b></div><div><br /></div>Find the latest version available to download below aswell as links to the most up-to-date documentation and tutorials:<br /><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub Reverse Ajax & Comet Server</a></li><li><a href="http://www.stream-hub.com/doc/2.0.10/javadoc/">Latest Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.0.10/jsdoc/">Latest AJAX SDK docs</a></li><li><a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax & Comet</a></li></ul><p>Enjoy! More demos are coming soon, subscribe to this blog or <a href="http://twitter.com/streamhub">follow us on twitter</a> to keep up to date.</p></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com2tag:blogger.com,1999:blog-840693053030195964.post-6163995696709682652009-10-29T17:24:00.000-07:002009-10-29T17:35:09.981-07:00StreamHub 2.0.9 Released. New YUI Comet Demo!<p>A new version of the core StreamHub server has been released. In this version we've added YUI integration, providing a new demo of how to integrate Comet & Reverse Ajax in to your YUI applications. Click the screenshot below to see the new demo in action:<br /></p><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.stream-hub.com/demo/YUIDemo/index.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 99px;" src="http://4.bp.blogspot.com/_iuc0yuQCrFc/SuozGf7qEZI/AAAAAAAAABU/lsjTY0pcnY8/s320/yui-comet-demo.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5398183290100912530" /></a><p><br />Grab the latest release and browse the API docs below:</p><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub Reverse Ajax & Comet Server</a></li><li><a href="http://www.stream-hub.com/doc/2.0.9/javadoc/">Latest Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.0.9/jsdoc/">Latest AJAX SDK docs</a></li><li><a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax & Comet</a></li></ul><p>Enjoy! More demos are coming soon, subscribe to this blog or <a href="http://twitter.com/streamhub">follow us on twitter</a> to keep up to date.<br /></p>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-19777308889090573342009-10-29T17:13:00.000-07:002009-10-29T17:23:43.509-07:00.NET Thick Client SDK 1.0.1.22 Maintenance ReleaseA new version of the .NET Thick Client SDK has been released. The language-neutral .NET Thick Client SDK allows you to connect rich .NET-based GUIs to the core StreamHub server using your preferred technology choice including WPF, C#, VB and C++. <br /><br />This maintenance releases brings the compatibility level down to .NET Framework 2.0 (previously requiring 2.0 SP2). The SDK is available to users of the Web and Enterprise editions of StreamHub (<a href="http://www.stream-hub.com/eval.html">request a free, no-obligation 60-day evaluation</a>). It provides an alternative desktop-based platform for server push applications, allowing clients to connect both over the web, via the Ajax SDK, or from their desktop via the Thick Client SDK. The Thick Client SDK is also available in Java.StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-82593185266333125902009-10-01T04:48:00.000-07:002009-10-01T11:23:25.299-07:00Getting Started with Reverse Ajax and CometIn this article I'll be covering what Reverse Ajax and Comet are, how to use them, and how to get up and running with an example in no time at all.<div><br /></div><div><b>Reverse Ajax and Comet</b></div><div><b><br /></b></div><div>Reverse Ajax and Comet are essentially the same thing - long-lived HTTP requests allowing your browser to receive real-time events from the server without refreshing the page or installing any plugins. Chances are you use Comet every day without even realizing it: GMail use it for displaying new e-mails as they're received, Facebook uses it for chat and friend updates, last.fm will be using it to show you what your friends are currently listening to, basically its pretty widespread in Web 2.0 land.</div><div><br /></div><div><b>Quick Overview of the Innards of Reverse Ajax and Comet</b></div><div><b><br /></b></div><div>Initially maligned as a 'hack' by some, Comet has since matured, turning itself into the protocol <i>du jour</i> for Web 2.0. Implemented under the covers via long-polling XMLHttpRequests, hidden iframes, Bayeux, or HTML 5 it all works over HTTP - either keeping a connection open to the server or polling the server for the most recent updates. Luckily there are plenty of servers around now that hide all the nitty gritty details away and wrap them up in a reliable publish/subscribe framework.</div><div><br /></div><div><b>Getting Started - 'Hello World' in Comet and Reverse Ajax</b></div><div><b><br /></b></div><div>The first example we'll be creating will be the obligatory 'Hello World!'. For this example grab yourself a copy of the free Community Edition of <a href="http://www.stream-hub.com/">StreamHub Reverse Ajax & Comet Server</a>. This will limit us to 20 users but that should be plenty for our purposes. If you need more, you can <a href="http://www.stream-hub.com/eval.html">request the free 60-day evaluation</a>. To get started, create a directory called <span class="Apple-style-span" style="font-family:'courier new';">CometTutorial</span> or similar, and create a new file <span class="Apple-style-span" style="font-family:'courier new';">helloworld.htm</span>l, containing the following HTML:</div><div><br /></div><div><br /><pre name="code" class="html:nogutter"><br /><head><br /><title>Hello World Comet Application</title><br /><script src="streamhub-min.js" type="text/javascript"></script><br /></head><br /><body><br /><h1>Hello World Comet Application</h1><br /><input type="button" value="Say hello" onclick="start()"><br /><div id="streamingData"></div><br /><script><br />function topicUpdated(sTopic, oData) {<br /> var newDiv = document.createElement("DIV");<br /> newDiv.innerHTML = "Update for topic '" + sTopic + "' Response: '" + oData.Response + "'";<br /> document.getElementById('streamingData').appendChild(newDiv);<br />}<br /><br />function start() {<br /> var hub = new StreamHub();<br /> hub.connect("http://localhost:7878/");<br /> hub.subscribe("HelloWorld", topicUpdated);<br />}<br /></script><br /></body><br /></html><br /></pre><br /></div><div><br /></div><div>All we've done here is create a simple HTML host page for our 'Hello World' app and added a bit of code to the onclick of the 'Say hello' button to connect to the Comet server and subscribe to a topic, 'Hello World'. Notice the <span class="Apple-style-span" style="font-family:'courier new';">topicUpdated</span> function is never called but instead passed into the <span class="Apple-style-span" style="font-family:'courier new';">subscribe</span> function. The StreamHub Ajax API will call the function every time a new update is received from the server. Inside the <span class="Apple-style-span" style="font-family:'courier new';">topicUpdated</span> function we create a new <span class="Apple-style-span" style="font-family:'courier new';">div</span> and append it to the page to show the contents of the new event from the server. With the client-side done, we'll now need to create the server-side.</div><div><br /></div><div>Create a new file called <span class="Apple-style-span" style="font-family:'courier new';">HelloWorld.java</span> containing the following code:</div><div><br /></div><div><br /><pre name="code" class="java:nogutter"><br />import java.io.File;<br />import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br />import com.streamhub.api.Client;<br />import com.streamhub.api.SubscriptionListener;<br />import com.streamhub.api.JsonPayload;<br /><br />public class HelloWorld implements SubscriptionListener {<br /><br />public static void main(String[] args) throws Exception {<br /> new HelloWorld();<br />}<br /><br />public HelloWorld() throws Exception {<br /> PushServer server = new NIOServer(7878);<br /> server.addStaticContent(new File("."));<br /> server.start();<br /> server.getSubscriptionManager().addSubscriptionListener(this);<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> server.stop();<br />}<br /><br />public void onSubscribe(String topic, Client client) {<br /> JsonPayload payload = new JsonPayload(topic);<br /> payload.addField("Response", "Hello World!");<br /> client.send(topic, payload);<br />}<br /><br />public void onUnSubscribe(String topic, Client client) {<br /> // no need to do anything here<br />}<br />}<br /></pre><br /></div><div><br /></div><div>In this bit of code we create a new PushServer, add the current directory as static content so we can serve up our helloworld.html page, and start 'er up. </div><div><br /></div><div><i>Its important to note at this point that for a production app you'll want to server your static files from a separate HTTP server such as Apache, IIS or Tomcat. StreamHub is engineered for highly-scalable Comet & Reverse Ajax and although it can serve your static content, its not the primary purpose. The most typical setup is to serve static content via your usual HTTP server from www.<domain>.com and real-time content via StreamHub from push.<domain>.com.</domain></domain></i></div><div><br /></div><div>The key part of the code is in the <span class="Apple-style-span" style="font-family:'courier new';">onSubscribe</span> function, here we reply to any subscription requests from the client by sending them a <span class="Apple-style-span" style="font-family:'courier new';">JsonPayload</span> containing our 'Hello World' message. Now we've created the server and client, we'll need to copy some files over from the StreamHub download and compile everything. If you haven't yet, download <a href="http://www.stream-hub.com/">StreamHub Reverse Ajax & Comet Server</a>, and extract the archive (there's a big download button on the website - you can't miss it). Inside the<span class="Apple-style-span" style="font-family:'courier new';"> streamhub-java-adapter-sdk</span> folder you should see something like this:</div><div><br /></div><div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_iuc0yuQCrFc/SsS0OAM4noI/AAAAAAAAAAs/JKKtkiNl58k/s1600-h/sdk-contents.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 146px;" src="http://3.bp.blogspot.com/_iuc0yuQCrFc/SsS0OAM4noI/AAAAAAAAAAs/JKKtkiNl58k/s320/sdk-contents.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5387629206907166338" /></a><br /></div><div><br /></div><div>Copy the <span class="Apple-style-span" style="font-family:'courier new';">conf</span> folder and the <span class="Apple-style-span" style="font-family:'courier new';">license.txt</span> file over to the same folder our HelloWorld app is located in. This will stop StreamHub moaning about licenses and logging when we start it up later. Now navigate into the <span class="Apple-style-span" style="font-family:'courier new';">examples/lib/jar</span> directory and copy over <span class="Apple-style-span" style="font-family:'courier new';">streamhub-2.0.8.jar</span>, <span class="Apple-style-span" style="font-family:'courier new';">log4j-1.2.14.jar</span> and <span class="Apple-style-span" style="font-family:'courier new';">json-20080701.jar</span> to the same place as before. While you're there, copy <span class="Apple-style-span" style="font-family:'courier new';">streamhub-min.js</span> from <span class="Apple-style-span" style="font-family:'courier new';">examples/lib/js</span>. You should end up with a folder which looks something like this:</div><div><br /></div><div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iuc0yuQCrFc/SsS10vLBdiI/AAAAAAAAAA0/mTabbIETSfg/s1600-h/hello-world-folder.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 106px;" src="http://2.bp.blogspot.com/_iuc0yuQCrFc/SsS10vLBdiI/AAAAAAAAAA0/mTabbIETSfg/s320/hello-world-folder.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5387630971862480418" /></a><br /></div><div><br /></div><div>Now to compile, you'll need Java 5 or greater, if you don't have it, get it <a href="http://java.sun.com/javase/downloads/index.jsp">here</a> (Download the latest Java SE Development Kit - JDK 6 at time of writing). To compile, open a command prompt in the HelloWorld directory and run:</div><br /><pre name="code" class="java:nogutter"><br />javac -cp streamhub-2.0.8.jar HelloWorld.java<br /></pre><br /><div>To start the server run (Windows):</div><br /><pre name="code" class="java:nogutter"><br />java -cp .;streamhub-2.0.8.jar;log4j-1.2.14.jar;json-20080701.jar HelloWorld<br /></pre><br /><div><br /></div><div>On Unix, you'll need to replace all ';' with ':':</div><br /><pre name="code" class="java:nogutter"><br />java -cp .:streamhub-2.0.8.jar:log4j-1.2.14.jar:json-20080701.jar HelloWorld<br /></pre><br /><div>Now open a browser to <span class="Apple-style-span" style="font-family:'courier new';">http://localhost:7878/helloworld.html</span> and click the 'Say hello' button to see it in action. You should see something like this (I clicked it a few times):</div><div><br /></div><div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iuc0yuQCrFc/SsS3xg7hKrI/AAAAAAAAAA8/vgVHk1jtlhA/s1600-h/hello-world-browser.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 142px;" src="http://2.bp.blogspot.com/_iuc0yuQCrFc/SsS3xg7hKrI/AAAAAAAAAA8/vgVHk1jtlhA/s320/hello-world-browser.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5387633115523001010" /></a><br /></div><div><br /></div><div>There we go! 'Hello World' for Reverse Ajax & Comet in a few lines of Java and JavaScript, no complicated configuration required. However, if you're like me, 'Hello World' is never enough and to be honest this simple app hardly shows off Comet - so lets create something a bit more exciting.</div><div><br /></div><div><b>Getting Advanced - Reverse Ajax & Comet Stock Ticker</b></div><div><br /></div><div>In this example, we're going to create a stock ticker table, a bit like the one on the StreamHub homepage. To start, create a file called <span class="Apple-style-span" style="font-family:'courier new';">stockticker.html</span> in the same folder as the HelloWorld example. Add the following HTML to this file:</div><div><br /></div><div><br /><pre name="code" class="html:nogutter"><br /><head><br /><title>Stock Ticker Comet Application</title><br /><script src="streamhub-min.js" type="text/javascript"></script><br /></head><br /><body><br /><h1>Stock Ticker Comet Application</h1><br /><input type="text" value="AAPL" id="stockSymbol"><br /><input type="button" value="Subscribe" onclick="subscribe()"><br /><br /><table id="tickerTable"><br /> <tr><th align="left" width="150">Symbol</th><th align="left" width="100">Last Price</th></tr><br /> <tr><td>GOOG</td><td id="GOOG_Price">-</td></tr><br /> <tr><td>MSFT</td><td id="MSFT_Price">-</td></tr><br /></table><br /><br /><script><br />function topicUpdated(sTopic, oData) {<br /> var priceDiv = document.getElementById(sTopic + "_Price");<br /> priceDiv.innerHTML = oData.Last;<br />}<br /><br />function subscribe() {<br /> var topic = document.getElementById('stockSymbol').value;<br /> var rowEl = document.createElement('tr');<br /> var symbolEl = document.createElement('td');<br /> symbolEl.innerHTML = topic;<br /> var priceEl = document.createElement('td');<br /> priceEl.id = topic + "_Price";<br /> rowEl.appendChild(symbolEl);<br /> rowEl.appendChild(priceEl);<br /> tickerTable.appendChild(rowEl);<br /> hub.subscribe(topic, topicUpdated);<br />}<br /><br />var tickerTable = document.getElementById('tickerTable');<br /><br />var hub = new StreamHub();<br />hub.connect("http://localhost:7878/");<br />hub.subscribe("GOOG", topicUpdated);<br />hub.subscribe("MSFT", topicUpdated);<br /></script><br /></body><br /></html><br /></pre><br /></div><div><br /></div><div>This is a little bit more complicated than the 'Hello World' example. Here, we define a table in the HTML markup and give two of the cells the IDs of <span class="Apple-style-span" style="font-family:'courier new';">GOOG_Price</span> and <span class="Apple-style-span" style="font-family:'courier new';">MSFT_Price</span>. We then subscribe to <span class="Apple-style-span" style="font-family:'courier new';">GOOG</span> and <span class="Apple-style-span" style="font-family:'courier new';">MSFT</span> passing in a <span class="Apple-style-span" style="font-family:'courier new';">topicUpdated</span> function as before. Now, in this <span class="Apple-style-span" style="font-family:'courier new';">topicUpdated</span>, we find an element prefixed by topic and ending in <span class="Apple-style-span" style="font-family:'courier new';">_Price</span>, so when we receive an update for topic <span class="Apple-style-span" style="font-family:'courier new';">GOOG</span>, the element with ID <span class="Apple-style-span" style="font-family:'courier new';">GOOG_Price</span> is updated with the latest price received from the server. Essentially whenever we receive an update from the server, the table is automatically updated with the new price. You'll notice we've added a textbox and a button to subscribe to a ticker symbol. This button calls the <span class="Apple-style-span" style="font-family:'courier new';">subscribe</span> function and dynamically adds a new row to the table and subscribes to the topic via the hub. Now onto the server-side code.</div><div><br /></div><div>Create a new file called StockTicker.java, this will provide random price events to our client. Insert the following code:</div><div><br /></div><div><br /><pre name="code" class="java:nogutter"><br />import java.io.File;<br />import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br />import com.streamhub.api.Client;<br />import com.streamhub.api.SubscriptionListener;<br />import com.streamhub.api.JsonPayload;<br />import java.util.Set;<br />import java.util.HashSet;<br />import java.util.Random;<br />import java.text.NumberFormat;<br />import java.text.DecimalFormat;<br /><br />public class StockTicker implements SubscriptionListener {<br />private final Random random = new Random();<br />private final NumberFormat priceFormatter = new DecimalFormat("0.00");<br /> private final Set symbols = new HashSet();<br /> private PushServer server;<br /><br /><br />public static void main(String[] args) throws Exception {<br /> new StockTicker();<br />}<br /><br />public StockTicker() throws Exception {<br /> server = new NIOServer(7878);<br /> server.addStaticContent(new File("."));<br /> server.start();<br /> server.getSubscriptionManager().addSubscriptionListener(this);<br /> new Thread(new RandomStockTicker()).start();<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> server.stop();<br />}<br /><br />public void onSubscribe(String topic, Client client) {<br /> JsonPayload payload = new JsonPayload(topic);<br /> payload.addField("Last", "0.00");<br /> client.send(topic, payload);<br /><br /> synchronized(symbols) {<br /> symbols.add(topic);<br /> }<br />}<br /><br />public void onUnSubscribe(String topic, Client client) {<br /> // no need to do anything here<br />}<br /><br />private class RandomStockTicker implements Runnable {<br /> public void run() {<br /> while(server.isStarted()) {<br /> try {<br /> Thread.sleep(1000);<br /> } catch (InterruptedException e) {}<br /><br /> synchronized(symbols) {<br /> for (String symbol : symbols) {<br /> double nextPrice = random.nextDouble() * 100.0;<br /> JsonPayload payload = new JsonPayload(symbol);<br /> payload.addField("Last", priceFormatter.format(nextPrice));<br /> server.publish(symbol, payload);<br /> }<br /> }<br /> }<br /> }<br />}<br />}<br /></pre><br /></div><div><br /></div><div>In the onSubscribe method we send a direct response to the client as we did in the 'Hello World' example, but we also add the client's subscription to a <span class="Apple-style-span" style="font-family:'courier new';">Set</span> (unique list) of symbols. You'll notice in the constructor we kicked off a new <span class="Apple-style-span" style="font-family:'courier new';">Thread</span> called <span class="Apple-style-span" style="font-family:'courier new';">RandomStockTicker</span>. The <span class="Apple-style-span" style="font-family:'courier new';">RandomStockTicker</span> simply loops through the list of symbols in the background and generates a random price for each one. It will continue to loop, sleeping for 1000ms between each burst of updates. Time to compile and run. </div><div><br /></div><div>You should have all the files you need from the 'Hello World' example, leaving your folder looking something like this:</div><div><br /></div><div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_iuc0yuQCrFc/SsTNJ6uzqkI/AAAAAAAAABE/dnN861CxkTw/s1600-h/stock-ticker-files.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 123px;" src="http://1.bp.blogspot.com/_iuc0yuQCrFc/SsTNJ6uzqkI/AAAAAAAAABE/dnN861CxkTw/s320/stock-ticker-files.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5387656624510052930" /></a><br /></div><div>To compile, run the following:</div><div><br /></div><div><br /><pre name="code" class="java:nogutter"><br />javac -cp streamhub-2.0.8.jar StockTicker.java<br /></pre><br /></div><div><br /></div><div>And to run (Windows):</div><div><br /></div><div><br /><pre name="code" class="java:nogutter"><br />java -cp .;streamhub-2.0.8.jar;log4j-1.2.14.jar;json-20080701.jar StockTicker<br /></pre><br /></div><div>On Unix:</div><div><br /></div><div><br /><pre name="code" class="java:nogutter"><br />java -cp .:streamhub-2.0.8.jar:log4j-1.2.14.jar:json-20080701.jar StockTicker<br /></pre><br /></div><div><br /></div><div>Now open up a browser to <span class="Apple-style-span" style="font-family:'courier new';">http://localhost:7878/stockticker.html</span> and check it out! Because we used the <span class="Apple-style-span" style="font-family:'courier new';">publish</span> method, the updates will be sent to all subscribed clients - so if you open up a few browsers you can see the same updates being delivered to multiple clients. Below I've opened it in Firefox, IE, Comet and Safari:</div><div><br /></div><div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_iuc0yuQCrFc/SsTPWjaIMNI/AAAAAAAAABM/cb828lBUIZU/s1600-h/cross-browser.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 235px;" src="http://1.bp.blogspot.com/_iuc0yuQCrFc/SsTPWjaIMNI/AAAAAAAAABM/cb828lBUIZU/s320/cross-browser.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5387659040610857170" /></a><br /></div><div><br /></div><div>That's it for now. If you'd like to take it further, try adding green and red highlighting to the prices depending on whether they've gone up or down (Tip: check out the <a href="http://docs.jquery.com/UI/Effects/Highlight">jQuery Highlight Effect</a>). If you're looking for a more trick table or grid with sorting/filtering etc.., try <a href="http://www.extjs.com/">ExtJS</a>, <a href="http://developer.yahoo.com/yui/">YUI</a> or the <a href="http://trirand.com/jqgrid/jqgrid.html">jQuery Grid Plugin</a>. Remember to subscribe to the blog for the latest tutorials, releases and news.</div><div><br /></div><div><br /></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com8tag:blogger.com,1999:blog-840693053030195964.post-24046335997852028472009-09-24T06:07:00.000-07:002009-09-24T06:18:28.470-07:00StreamHub Comet Server 2.0.7 Released - New Real-Time Chart DemoA new version of the<a href="http://www.stream-hub.com/"> StreamHub Push Server</a> has just been released. In this latest release, 2.0.7, we've added a new real-time chart demo, showing how to use the <a href="http://code.google.com/p/flot/">jQuery Flot Plugin</a> to update charts via Comet. The example makes use of excanvas in Internet Explorer to make it fully cross-browser compatible with Chrome, Safari, IE, Firefox et. al.<div><br /></div><div>Click the screenshot below to see it in action:<br /><br /></div><div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.stream-hub.com/demo/RealTimeChart/index.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 150px;" src="http://4.bp.blogspot.com/_iuc0yuQCrFc/SrtwraF1QvI/AAAAAAAAAAk/QIEfTv1lPvk/s320/real-time-chart-demo.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385021670492029682" /></a><br /></div><div>We think real-time charting through pure JavaScript is really exciting and are looking forward to producing a whole bunch of cool demos in future.</div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-11998217967359657562009-09-22T06:43:00.000-07:002009-09-22T06:57:55.662-07:00Comet in GWT with StreamHub - New ReleaseA new version of the <a href="http://code.google.com/p/gwt-comet-streamhub/">GWT Comet Adapter</a> has been released for <a href="http://www.stream-hub.com/">StreamHub Comet Server</a>. The adapter is a GWT module which when included in your project allows you to stream real-time data from StreamHub to your GWT apps. Click the screenshot below to see a demo of the adapter in action:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.stream-hub.com/demo/gwt-comet-visualization-api/stock-visualization-demo.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 111px;" src="http://2.bp.blogspot.com/_iuc0yuQCrFc/SrjW5HUjiVI/AAAAAAAAAAU/PZ41otnyzk0/s320/gwt-demo-screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5384289631227578706" /></a><br /><br />In this latest release full failover and reconnection support has been added. Using the new connect method, its now possible to configure 100% of the failover and reconnection options available in StreamHub. For example:<br /><pre name="code" class="java:nogutter"><br />StreamHubGWTAdapter streamhub = new StreamHubGWTAdapter();<br />List servers = new ArrayList();<br />servers.add("https://push1.stream-hub.com/");<br />servers.add("https://push2.stream-hub.com/");<br />servers.add("https://push3.stream-hub.com/");<br />FailoverParameters failoverParameters = new FailoverParameters(servers);<br />failoverParameters.setAlgorithm(FailoverAlgorithm.PRIORITY);<br />failoverParameters.setInitialReconnectDelayMillis(2000);<br />failoverParameters.setMaxReconnectDelayMillis(30000);<br />failoverParameters.setUseExponentialBackOff(true);<br />failoverParameters.setBackOffMultiplier(2.0);<br />failoverParameters.setMaxReconnectAttempts(20);<br />streamhub.connect(failoverParameters);<br /></pre><br />For full details of the API, you can <a href="http://www.stream-hub.com/doc/streamhub-gwt-adapter/1.0.3/javadoc/">browse the Javadoc online</a> or checkout the <a href="http://code.google.com/p/gwt-comet-streamhub/">projects homepage on Google Code</a>.StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com2tag:blogger.com,1999:blog-840693053030195964.post-22213913414491457612009-09-18T06:41:00.000-07:002009-09-18T06:48:51.336-07:00StreamHub Comet Works Great on Latest iPhone - No Plugins Required<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iuc0yuQCrFc/SrOPZU_5MjI/AAAAAAAAAAM/8x2uoIHV2Iw/s1600-h/iphone_pic.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 270px; height: 320px;" src="http://4.bp.blogspot.com/_iuc0yuQCrFc/SrOPZU_5MjI/AAAAAAAAAAM/8x2uoIHV2Iw/s320/iphone_pic.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5382803644934074930" /></a><br />We've just been trying out <a href="http://www.stream-hub.com/">StreamHub Comet</a> on the latest iPhone 3GS - it works really smoothly without installing anything, no plugins or Flash required, it works out the box. Try it yourself, just browse to the <a href="http://www.stream-hub.com/">StreamHub website on your iPhone</a> and check out the real-time Comet goodness.StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-6608137246691411872009-09-15T16:25:00.000-07:002009-09-15T18:11:04.855-07:00Configuring Failover and Reconnection with the StreamHub JavaScript API<div><b>Introduction</b></div><div><br /></div>The latest version of <a href="http://www.stream-hub.com/">StreamHub Comet Server</a> (2.0.6) includes the ability to configure failover and reconnection in the JavaScript API. This article covers the basics of configuring a StreamHub connection to use failover. Which scripts to include and how to get started with StreamHub are not covered in this article. If you're new to StreamHub I recommend you start with the <a href="http://streamhub.blogspot.com/2009/07/getting-started-with-streamhub-and.html">Getting Started Guide</a>.<div><br /></div><div><b>The New Connect Method</b></div><div><b><br /></b></div><div>The <span class="Apple-style-span" style="font-family:'courier new';">connect</span> method is now overloaded to take two types of argument, a string URL, or a JavaScript object with the failover configuration parameters. First of all, the new method is completely backwards compatible, so you will not need to change any code like below, which uses the old method of connecting:</div><br /><pre name="code" class="javascript:nogutter"><br />var hub = new StreamHub();<br />hub.connect("http://push.example.com/");</pre><br /><div>The above configures a connection with no failover, but it does have, by default, reconnection behaviour. The default reconnection behaviour is upon connection loss to attempt to reconnect to the URL every second until the connection is re-established. This provides a quick and seamless reconnection for when the server becomes reachable again. If this isn't what you need, you'll want to make use of the new connect method. The example below uses the exact same method, but this time we pass in an anonymous JavaScript object specifying different reconnection and failover behaviour:</div><br /><pre name="code" class="javascript:nogutter"><br />var hub = new StreamHub();<br />hub.connect({<br /> serverList: ["http://primary.example.com/",<br /> "http://secondary.example.com/"],<br /> failoverAlgorithm: "ordered",<br /> initialReconnectDelayMillis: 2000<br />});</pre><br /><div>Firstly, in the configuration object we specify a <span class="Apple-style-span" style="font-family:'courier new';">serverList</span> as an array of string URLs. This is a list of StreamHub servers to which a connection can be made. The first server in the list will always be the one which is connected to first. If the connection is the lost, the <span class="Apple-style-span" style="font-family:'courier new';">failoverAlgorithm</span> option specifies which server to try next. In this case, we use "ordered", which means proceed down the serverList in order, attempting to connect to each server in turn until a connection is successfully established. Finally, the <span class="Apple-style-span" style="font-family:'courier new';">initialReconnectDelayMillis</span> specifies how long to wait between each reconnection attempt. Here we specify 2000 ms (2 seconds). For reference, all of these configuration options and more are documented in the <a href="http://www.stream-hub.com/doc/2.0.6/jsdoc/symbols/StreamHub.html#connect">JSDOC for StreamHub.connect(config)</a>.</div><div><br /></div><div><b>Exponential BackOff and Limiting the Number of Reconnections</b></div><div><b><br /></b></div><div>Now for a more advanced example demonstrating exponential backoff, a feature you may have seen in some JMS implementations:</div><div><pre name="code" class="javascript:nogutter">var hub = new StreamHub();<br />hub.connect({<br /> serverList: ["https://push1.example.com/",<br /> "https://push2.example.com/",<br /> "https://push3.example.com/"],<br /> failoverAlgorithm: "ordered",<br /> initialReconnectDelayMillis: 1000,<br /> maxReconnectDelayMillis: 30000,<br /> useExponentialBackOff: true,<br /> backOffMultiplier: 2<br />});</pre></div><div>In the above example, we've introduced a <span class="Apple-style-span" style="font-family:'courier new';">backOffMultiplier</span> and a maximum reconnection delay. The back off feature allows you to increase the wait between each reconnection attempt over time, in this case by a multiple of 2. The best way to demonstrate how this works is with an example:</div><ol><br /><li>Client successfully connects to https://push1.example.com/</li><br /><li>Client loses connection</li><br /><li>Client waits 1000ms</li><br /><li>Client fails to reconnect to https://push2.example.com/</li><br /><li>Client waits 2000ms</li><br /><li>Client fails to reconnect to https://push3.example.com/</li><br /><li>Client waits 4000ms</li><br /><li>Client fails to reconnect to https://push1.example.com/</li><br /><li>...</li><br /></ol><div><span class="Apple-style-span" style="font-family:georgia;">This will continue until the wait time reaches 30000ms, since this is the <span class="Apple-style-span" style="font-family:'courier new';">maxReconnectDelayMillis</span> we specified. The reconnection attempts will still continue but with a wait time of 30000ms. To limit the number of reconnection attempts we must use the <span class="Apple-style-span" style="font-family:'courier new';">maxReconnectAttempts</span> option, this specifies a maximum number of reconnects to attempt before giving up:</span></div><pre name="code" class="javascript:nogutter"><br />var hub = new StreamHub();<br />hub.connect({<br /> serverList: ["https://push1.example.com/",<br /> "https://push2.example.com/",<br /> "https://push3.example.com/"],<br /> failoverAlgorithm: "ordered",<br /> initialReconnectDelayMillis: 1000,<br /> maxReconnectDelayMillis: 30000,<br /> maxReconnectAttempts: 30,<br /> useExponentialBackOff: true,<br /> backOffMultiplier: 2<br />});</pre><div>That's it, a quick overview of the reconnection and failover configuration available in the StreamHub JS API. As mentioned earlier in the article, for detailed coverage of all the options, refer to the <span class="Apple-style-span" style=" ;font-family:Georgia, serif;"><a href="http://www.stream-hub.com/doc/2.0.6/jsdoc/symbols/StreamHub.html#connect">JSDOC for StreamHub.connect(config)</a>.</span><div><span class="Apple-style-span" style="font-family:georgia;"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-family:georgia;"><br /></span></span></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-61312399852787053822009-09-15T15:31:00.000-07:002009-09-15T15:53:16.594-07:00StreamHub Push Server 2.0.6 Released<div>A new version of the core <a href="http://www.stream-hub.com/">StreamHub HTTP Push Server</a> has just been released. This is another minor release improving the quality, logging, and introducing a couple of new resilience and benchmarking features. There's a new mechanism for attaching timestamps to messages, comprehensive failover and reconnection configuration for the JavaScript API, and a general streamlining of the core server logging. Oh, and all utility Javascript classes have now been namespaced under StreamHub to avoid clashes.</div><div></div><div><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub 2.0.6 Community Edition</a></li><li><a href="http://www.stream-hub.com/eval.html">Start an Evaluation of the Enterprise Edition</a></li><li><a href="http://www.stream-hub.com/doc/2.0.6/javadoc/">View the latest Java Streaming Adapter Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.0.6/jsdoc/">View the latest Ajax Client JSDoc</a></li><li><a href="http://www.stream-hub.com/doc/streamhub-gwt-adapter/1.0.2/javadoc/">View the latest GWT Comet Client Javadoc</a></li></ul></div><div>As always you can find our getting starting guides here on the blog:</div><div></div><div><ul><li><a href="http://streamhub.blogspot.com/2009/07/getting-started-with-streamhub-and.html">Getting Started with StreamHub and Comet</a></li><li><a href="http://streamhub.blogspot.com/2009/07/tutorial-building-comet-chat.html">Tutorial: Building a Comet Chat Application with StreamHub</a></li></ul></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-59785025820513415242009-08-07T05:20:00.000-07:002009-09-01T12:45:06.056-07:00Loading the License and Log4J Configuration from an Alternative LocationThis article covers how to load the license and Log4J configuration from a non-default location in <a href="http://www.stream-hub.com/">StreamHub Push Server</a> version 2.0.3 or later.<div><br /></div><div><b>Default locations</b></div><div><br /></div><div>The default location for the license is a file called <span class="Apple-style-span" style="font-family:'courier new';">license.txt</span> in the current working directory or ".". The default location for the Log4J configuration is <span class="Apple-style-span" style="font-family:'courier new';">conf/log4j.xml</span> relative to the current working directory.</div><div><br /></div><div><b>Loading from a different location</b></div><div><br /></div><div>In order to load the license and Log4J configuration from a different location, we'll need to make use of a different constructor when instantiating the server. Looking at the <a href="http://www.stream-hub.com/doc/2.0.3/javadoc/">Javadoc</a>, we find this constructor:</div><div><div><pre name="code" class="java:nogutter"><br />public NIOServer(InetSocketAddress address,<br /> InetSocketAddress streamingAdapterAddress,<br /> URL licenseUrl,<br /> URL log4jConfigurationUrl)<br /></pre></div><div>This constructor allows us to specify a URL for the license and logging configuration. The Javadoc also tells us the types of URL we can specify:</div><div><br /></div><div><div><ul><li>File URLs e.g. <span class="Apple-style-span" style="font-family:'courier new';">file:///C:/licenses/license.txt</span></li><li>Remote URLs e.g. <span class="Apple-style-span" style="font-family:'courier new';">http://www.example.com/logging/log4j.xml</span></li><li>JAR URLs e.g. <span class="Apple-style-span" style="font-family:'courier new';">jar:file:///C:/lib/streamhub-license.jar!/license.txt</span> or <span class="Apple-style-span" style="font-family:'courier new';">jar:http://www.example.com/logging/streamhub-logging.jar!/log4j.xml</span></li><li>Classpath URLs via <span class="Apple-style-span" style="font-family:'courier new';">com.streamhub.util.UrlLoader</span> e.g. <span class="Apple-style-span" style="font-family:'courier new';">UrlLoader.load("classpath:/license.txt")</span>, or <span class="Apple-style-span" style="font-family:'courier new';">UrlLoader.load("classpath:/conf/log4j.xml")</span></li></ul><div>As an example, the below starts a server as normal on port 80, loading the license and logging configuration from the classpath. This assumes we have <span class="Apple-style-span" style="font-family:'courier new';">prod.license</span> and <span class="Apple-style-span" style="font-family:'courier new';">prod-logging.xml</span> available on the classpath, perhaps through another JAR.<br /><pre name="code" class="java:nogutter"><br />URL licenseUrl = UrlLoader.load("classpath:/prod.license");<br />URL loggingUrl = UrlLoader.load("classpath:/prod-logging.xml");<br />PushServer server = new NIOServer(new InetSocketAddress(80), null, licenseUrl, loggingUrl);<br /></pre></div><div>Note: we pass <span class="Apple-style-span" style="font-family:'courier new';">null</span> through as the second parameter to indicate we don't want to start a streaming adapter. Streaming adapters are used to push updates through the server from remote locations and aren't covered in this article. Also, note we make use of the <span class="Apple-style-span" style="font-family:'courier new';">com.streamhub.util.UrlLoader</span> to generate the URLs as classpath resources aren't supported by default in Java.</div><div><br /></div><div>The second example below loads the files from a remote location, this would usually be an internal location only visible to the server and not accessible by the outside world.</div><div><div><pre name="code" class="java:nogutter"><br />URL licenseUrl = new URL("http://staging1.example.com/streamhub/license-staging.txt");<br />URL loggingUrl = new URL("http://staging1.example.com/streamhub/log4j-staging.xml");<br />PushServer server = new NIOServer(new InetSocketAddress(80), null, licenseUrl, loggingUrl);<br /></pre></div><div>The final example loads the files locally from the filesystem:</div></div></div></div></div><div><div><div><div><div><div><pre name="code" class="java:nogutter"><br />URL licenseUrl = new URL("file:///C:/prod/license.txt");<br />URL loggingUrl = new URL("file:///C:/prod/log4j.xml");<br />PushServer server = new NIOServer(new InetSocketAddress(80), null, licenseUrl, loggingUrl);<br /></pre></div><div>That last example brings this tutorial to an end. We've covered the default locations of <span class="Apple-style-span" style="font-family:'courier new';">license.txt</span> and <span class="Apple-style-span" style="font-family:'courier new';">conf/log4j.xml</span> and how to override them by passing URL arguments to the four parameter constructor. For more detail on the various constructors available, refer to the<a href="http://www.stream-hub.com/doc/2.0.3/javadoc/"> Javadoc online</a>. More detail on the XML that goes in the Log4J configuration file can be found in the <a href="http://wiki.apache.org/logging-log4j/Log4jXmlFormat">Log4J XML Configuration Primer</a>.</div></div></div></div></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-91670853602670523372009-08-07T04:33:00.001-07:002009-08-07T07:10:36.248-07:00StreamHub Push Server 2.0.3 ReleasedA new version of the core <a href="http://www.stream-hub.com/">StreamHub Push Server</a> has just been released. This is a minor release to improve the quality, configurability and documentation. There's a new constructor for specifying alternate locations for the license and log4j configuration. (More info in <a href="http://streamhub.blogspot.com/2009/08/loading-license-and-log4j-configuration.html">this blog article</a>). And with this release we've consolidated and published all the documentation externally. Follow the links below for the latest developments:<div><br /></div><div><ul><li><a href="http://www.stream-hub.com/download.html">Download StreamHub 2.0.3 Community Edition</a></li><li><a href="http://www.stream-hub.com/doc/2.0.3/javadoc/">View the Java Streaming Adapter Javadoc</a></li><li><a href="http://www.stream-hub.com/doc/2.0.3/jsdoc/">View the Ajax Client JSDoc</a></li><li><a href="http://www.stream-hub.com/doc/streamhub-gwt-adapter/1.0.2/javadoc/">View the GWT Client Javadoc</a></li></ul><div>As always you can find our getting starting guides here on the blog:</div><div><br /></div><div><ul><li><a href="http://streamhub.blogspot.com/2009/07/getting-started-with-streamhub-and.html">Getting Started with StreamHub and Comet</a></li><li><a href="http://streamhub.blogspot.com/2009/07/tutorial-building-comet-chat.html">Tutorial: Building a Comet Chat Application with StreamHub</a></li></ul><div><br /></div></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-32423083587193693552009-08-05T11:16:00.001-07:002009-08-05T11:22:35.139-07:00StreamHub GWT Comet Adapter 1.0.2 ReleasedA new version of the StreamHub GWT Comet Adapter has just been released. It now features full publish/subscribe support bringing it 100% in to line with the StreamHub API. Accompanying this new release is a comprehensive set of Javadocs available to browse online or download as a JAR. Follow the links below:<div><br /></div><div><ul><li><a href="http://code.google.com/p/gwt-comet-streamhub/">StreamHub GWT Comet Adapter</a></li><li><a href="http://www.stream-hub.com/doc/streamhub-gwt-adapter/1.0.2/javadoc/">Javadoc - Online Version</a></li><li><a href="http://code.google.com/p/gwt-comet-streamhub/downloads/list">Javadoc - JAR</a></li></ul><div><br /></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-37241651006867500632009-07-22T04:04:00.001-07:002009-07-22T04:13:56.681-07:00Get Help in our New StreamHub Comet Google GroupWe've launched a new Google Group as a place where StreamHub users can seek help, get support, and ask any questions about StreamHub or Comet in general.<div><br /></div><div>The StreamHub Team will be monitoring the group to answer any questions you may have. Visit us using the link below:</div><div><br /></div><div><a href="http://groups.google.co.uk/group/streamhub-comet-server-community">StreamHub Comet Server Community</a></div><div><br /></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com0tag:blogger.com,1999:blog-840693053030195964.post-18447591995287838932009-07-21T05:01:00.000-07:002009-07-29T09:44:38.696-07:00Tutorial: Building a Comet Chat Application with StreamHub<b><div><span class="Apple-style-span" style="font-weight: normal;"><i>Newly updated for version 2.0.2.</i> <a href="http://www.stream-hub.com/download.html">Download 2.0.2 here</a>.</span></div><div><br /></div>Introduction</b><div><br /></div><div>This tutorial will guide you through how to create a simple Comet chat application using the <a href="http://www.stream-hub.com/">StreamHub Comet server</a>. <span> StreamHub is a lightweight Comet server used for streaming real-time data to web browsers and other clients. This tutorial assumes you know what <a href="http://www.stream-hub.com/about-comet.html">Comet</a> is and have some basic JavaScript and Java knowledge but it doesn't get too deep so don't worry. At the end of the tutorial we will have created a simple cross-browser chat application.</span></div><div><b><br /></b></div><div><span></span><span><span><span class="Apple-style-span" style="font-weight: bold; ">Step 1 - Download the Free Community Edition</span></span></span><span><span><b><br /></b></span></span></div><div><b><br /></b></div><div><span><span><span>First of all we need to download the StreamHub SDK from the website. Go to the <span><a href="http://www.stream-hub.com/download.html">StreamHub download page</a></span> and grab yourself a copy of the Community Edition. At time of writing the latest version was 2.0.1 but any version should work. There isn't any real difference between the .ZIP version and the .TAR.GZ version - so grab which ever one you prefer. After downloading, extract the archive somewhere you can store it permanently. I put mine in <span class="Apple-style-span" style=" ;font-family:'courier new';">C:\streamhub</span>. Don't worry at this point if you're using Linux or Mac - the StreamHub server is completely cross platform.</span></span></span></div><div><span><span><br /></span></span></div><div><span><span><span class="Apple-style-span" style="font-weight: bold; ">Step 2 - Creating the chat page</span></span></span></div><div><b><br /></b></div><div><span><span>We'll need a webpage to host the chat application so let's create that first. Create a new folder in your StreamHub directory called Chat, so now you'll have something like <span class="Apple-style-span" style=" ;font-family:'courier new';">C:\streamhub\Chat</span>. Create a new file in the Chat directory called <span class="Apple-style-span" style=" ;font-family:'courier new';">index.html</span>. This will be our Comet chat page. Edit that file, adding the following:</span></span></div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Comet Chat with StreamHub</title><br /></head><br /><body><br /><input type="text" id="chatText" onkeypress="checkForEnter(event)"><br /><input type="button" value="Chat" onclick="chat()"><br /><br /><div id="chatMessages"></div><br /><script><br /><br />function chat() {<br /> // ...<br />}<br /><br />function checkForEnter(e){<br /> var e = e || event;<br /> var key = e.keyCode || e.charCode;<br /><br /> if(key == 13){<br /> chat();<br /> }<br /><br /> return true;<br />}<br /></script><br /></body><br /></html><br /></code></pre><div>All we've done is to create a very simple page with a textbox and a button labelled 'Chat'. We've added an <span class="Apple-style-span" style="font-family:'courier new';">onclick</span> handler and an <span class="Apple-style-span" style="font-family:'courier new';">onkeypress</span> handler. Don't worry too much about the c<span class="Apple-style-span" style="font-family:'courier new';">heckForEnter()</span> function, this just handles the user pressing enter in the textbox so the user can chat by pressing enter or clicking 'Chat'. The <span class="Apple-style-span" style="font-family:'courier new';">chatMessages</span> div will hold any chat messages that we receive. We'll need to include the StreamHub JavaScript API, so lets do that now. The JavaScript API comes as a single mini-fied file called <span class="Apple-style-span" style="font-family:'courier new';">streamhub-min.js</span>. Its in the archive we extracted in step 1, mine was in the directory <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\examples\lib\js</span>. Copy this file and paste it in the Chat directory. We'll include it in the head of our chat page, so it should now look like:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Comet Chat with StreamHub</title><br /><script src="streamhub-min.js"></script><br /></head><br /><body><br /><input type="text" id="chatText" onkeypress="checkForEnter(event)"><br /><input type="button" value="Chat" onclick="chat()"><br /><br /><div id="chatMessages"></div><br /><script><br /><br />function chat() {<br /> // ...<br />}<br /><br />function checkForEnter(e){<br /> var e = e || event;<br /> var key = e.keyCode || e.charCode;<br /><br /> if(key == 13){<br /> chat();<br /> }<br /><br /> return true;<br />}<br /></script><br /></body><br /></html><br /></code></pre><br /></div><div><b>Step 3 - Creating a Java Chat Adapter</b><br /></div><div><br /></div><div>Now we have a basic webpage setup we'll need to write some code in the backend to handle the receiving of messages and sending of messages to all connected chat clients. We'll create a Chat Java class to do this.</div><div><br /></div><div>Create a new file in the chat directory called <span class="Apple-style-span" style="font-family:'courier new';">Chat.java</span>, and add the following code to it:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>import java.io.File;<br />import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br />import com.streamhub.api.Client;<br />import com.streamhub.api.PublishListener;<br />import com.streamhub.api.JsonPayload;<br />import com.streamhub.api.Payload;<br /><br />public class Chat implements PublishListener {<br />private PushServer server;<br /><br />public static void main(String[] args) throws Exception {<br /> new Chat();<br />}<br /><br />public Chat() throws Exception {<br /> server = new NIOServer(7878);<br /> server.addStaticContent(new File("."));<br /> server.start();<br /> server.getSubscriptionManager().addPublishListener(this);<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> server.stop();<br />}<br /><br />public void onMessageReceived(Client client, String topic, Payload payload) {<br /> Payload chatMessage = new JsonPayload(topic);<br /> chatMessage.addField("client", "Client-" + client.getUid());<br /> chatMessage.addField("message", payload.getFields().get("message"));<br /> server.publish(topic, chatMessage);<br />}<br />}</code></pre></div><div>In the Chat class we've created a new Comet server and started it on port 7878:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>server = new NIOServer(7878);<br />server.start();</code></pre></div><div>We've then added our Chat class as a <span class="Apple-style-span" style="font-family:'courier new';">PublishListener</span>:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>server.getSubscriptionManager().addPublishListener(this);</code></pre></div><div>This means that every time a client publishes something to the server we will get notified by a call to the <span class="Apple-style-span" style="font-family:'courier new';">onMessageReceived</span> method. Later, in our chat webpage, we will publish every chat message to the server. So each chat message will come through to the <span class="Apple-style-span" style="font-family:'courier new';">onMessageReceived</span> method. In this method we simply publish the chat message to every single user subscribed to the chat:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>public void onMessageReceived(Client client, String topic, Payload payload) {<br /> Payload chatMessage = new JsonPayload(topic);<br /> chatMessage.addField("client", "Client-" + client.getUid());<br /> chatMessage.addField("message", payload.getFields().get("message"));<br /> server.publish(topic, chatMessage);<br />}</code></pre></div><div>The <span class="Apple-style-span" style="font-family:'courier new';">client</span> is an object representing the user who sent the chat message. The<span class="Apple-style-span" style="font-family:'courier new';"> topic</span> is the name of the topic they published on (we'll see later this is just "chat"). The <span class="Apple-style-span" style="font-family:'courier new';">payload</span> is the JSON message that was published by the user. We will put each chat message in the field "message". We add two fields to the <span class="Apple-style-span" style="font-family:'courier new';">chatMessage</span> payload: "client" which shows which user sent the chat message and "message" which shows the actual chat message. A UID is a unique identifier for each client, it gives each user a name, so we can see who said what. In a richer chat application would would probably add a way of having users choose there own name, but this will do for our simple example.</div><div><br /></div><div><b>Step 4 - Connecting to the Server and Publishing Chat Messages</b></div><div><br /></div><div>Now we have a Chat adapter, we need to add the code to our chat webpage to connect to the server and send the chat messages.</div><div><br /></div><div>The code to connect looks like this:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>var hub = new StreamHub();<br />hub.connect("http://localhost:7878/");<br /></code></pre></div><div>Now we are connected, we can subscribe to chat updates. We do this by passing a topic and a function which will be called every time a new chat message is received:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>hub.subscribe("chat", chatUpdated);<br /></code></pre></div><div>We, define the chatUpdated() function elsewhere. Every data updated callback will receive two arguments: sTopic, the topic on which the update occurred and oData, a JSON object containing the fields which were updated. In the chatUpdated() function we extract the client who sent the chat message and the message itself and append it to the <span class="Apple-style-span" style="font-family:'courier new';">chatMessages</span> div:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>function chatUpdated(topic, data) {<br /> var div = document.createElement("DIV");<br /> div.innerHTML = data.client + ": " + data.message;<br /> document.getElementById('chatMessages').appendChild(div);<br />}</code></pre></div><div>Our chat webpage should now look like this:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Comet Chat with StreamHub</title><br /><script src="streamhub-min.js"></script><br /></head><br /><body><br /><input type="text" id="chatText" onkeypress="checkForEnter(event)"><br /><input type="button" value="Chat" onclick="chat()"><br /><br /><div id="chatMessages"></div><br /><script><br /><br />function chatUpdated(topic, data) {<br /> var div = document.createElement("DIV");<br /> div.innerHTML = data.client + ": " + data.message;<br /> document.getElementById('chatMessages').appendChild(div);<br />}<br /><br />function chat() {<br /> // ...<br />}<br /><br />function checkForEnter(e){<br /> var e = e || event;<br /> var key = e.keyCode || e.charCode;<br /><br /> if(key == 13){<br /> chat();<br /> }<br /><br /> return true;<br />}<br /><br />var hub = new StreamHub();<br />hub.connect("http://localhost:7878/");<br />hub.subscribe("chat", chatUpdated);<br /></script><br /></body><br /></html></code></pre></div><div>As you can see, we still haven't filled in what happens when the user clicks "Chat". In the chat() function we will need to send the users chat message to the server so it can be forwarded to every user subscirbed to the chat. We do this by using the publish method. The first argument to publish is the topic we want to publish on. The second argument is a string of arbitrary JSON. Whatever we pass to the publish method will be passed through to the onMessageReceived function in our Chat Java class. So we get the chat message out of the textbox and create a JSON object containing one field, the message:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>function chat() {<br /> var message = document.getElementById('chatText').value;<br /> var json = "{'message':'" + escapeQuotes(message) + "'}";<br /> hub.publish("chat", json);<br />}</code></pre></div><div>Notice we call an escapeQuotes() method on the input from the textbox before we add it to the JSON. We do this because if the user happened to type a single quote it would mess up our JSON since each field is delimited by a single quote. Don't worry too much about the innards of the escapeQuotes() method - it just takes care of escaping any single quotes that would mess up the JSON. Now we're almost ready to try it out - the entire chat webpage should now look like this:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Comet Chat with StreamHub</title><br /><script src="streamhub-min.js"></script><br /></head><br /><body><br /><input type="text" id="chatText" onkeypress="checkForEnter(event)"><br /><input type="button" value="Chat" onclick="chat()"><br /><br /><div id="chatMessages"></div><br /><script><br /><br />function chatUpdated(topic, data) {<br /> var div = document.createElement("DIV");<br /> div.innerHTML = data.client + ": " + data.message;<br /> document.getElementById('chatMessages').appendChild(div);<br />}<br /><br />function chat() {<br /> var message = document.getElementById('chatText').value;<br /> var json = "{'message':'" + escapeQuotes(message) + "'}";<br /> hub.publish("chat", json);<br />}<br /><br />function escapeQuotes(sString) {<br /> return sString.replace(/(\')/gi, "\\$1").replace(/(\\\\\')/gi, "\\'");<br />}<br /><br />function checkForEnter(e){<br /> var e = e || event;<br /> var key = e.keyCode || e.charCode;<br /><br /> if(key == 13){<br /> chat();<br /> }<br /><br /> return true;<br />}<br /><br />var hub = new StreamHub();<br />hub.connect("http://localhost:7878/");<br />hub.subscribe("chat", chatUpdated);<br /></script><br /></body><br /></html><br /></code></pre><br /></div><div><b>Step 5 - Compiling the Chat Adapter and Starting Up</b></div><div><br /></div><div>In this final step, we will compile the Chat class we created in Step 3, start it up and try out the chat application. Before we compile and start we need to copy over a few files. </div><div><br /></div><div>We'll need a license, we can use the Free Community Edition license which comes in the archive we downloaded in Step 1. Copy the license.txt file over to the Chat directory. Mine was at <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\license.txt</span>.</div><div><br /></div><div>We'll also need a few JARs to compile and run. All the JARs come in the archive we extracted in Step 1. Mine were in the folder <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\examples\lib\jar</span>. Copy the following JARs over to the Chat directory:</div><div><ul><li>streamhub-VERSION.jar (e.g. streamhub-2.0.2.jar)</li><li>log4j-1.2.14.jar</li><li>json-20080701.jar</li></ul><div>Lastly, so we can see some logging, copy over the whole <span class="Apple-style-span" style="font-family:'courier new';">conf</span> folder from the archive to the Chat directory. Mine was found here: <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\conf</span>.</div><div><br /></div><div>Now, to compile, open a Command Prompt in the Chat directory and issue the following command:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>javac -cp streamhub-2.0.2.jar Chat.java</code></pre></div><div>To run, issue the following command:</div><div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>java -cp json-20080701.jar;log4j-1.2.14.jar;streamhub-2.0.2.jar;. Chat<br /></code></pre><div>If you are using Unix (or Mac), classpath items are separated with ':' instead of ';', so you will need to run the following command instead of the above:</div><div><pre style="font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(153, 153, 153); border-right-color: rgb(153, 153, 153); border-bottom-color: rgb(153, 153, 153); border-left-color: rgb(153, 153, 153); line-height: 14px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; overflow-x: auto; overflow-y: auto; width: 663px; "><code>java -cp json-20080701.jar:log4j-1.2.14.jar:streamhub-2.0.2.jar:. Chat</code></pre></div></div><div>That's it, navigate to <a href="http://localhost:7878/">http://localhost:7878/</a>, type some text and chat away! Open up a couple of browser windows and see the Comet chat messages displayed in both windows.</div><div><br /></div><div>That's the tutorial finished. The source code is available to download here: <a href="http://www.stream-hub.com/download-page.html?download=CometChat-2.0.2.zip">CometChat-2.0.2.zip</a>. A good next step is to explore the examples that come with the Community Edition. We hope you found this useful - if you have any problems or suggestions for other guides and tutorials please comment.</div><div><br /></div></div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com9tag:blogger.com,1999:blog-840693053030195964.post-4497662617553086082009-07-14T11:05:00.000-07:002009-10-01T11:22:07.829-07:00Getting Started with StreamHub and Comet<div><i>This article has now been superseded by the similar: <a href="http://streamhub.blogspot.com/2009/10/getting-started-with-reverse-ajax-and.html">Getting Started with Reverse Ajax and Comet</a>.</i></div><div><i><br /></i></div><div><i>This article refers to version 2.0.2.</i> <a href="http://www.stream-hub.com/download.html">Download 2.0.2 here</a>.</div><div><b><br /></b></div><div><b>Introduction</b></div><div><br /></div>This is a quick getting started guide for <a href="http://www.stream-hub.com/">StreamHub</a>. StreamHub is a lightweight Comet server used for streaming real-time data to web browsers and other clients. In this article I'll take you through how to create a simple 'Hello World' Comet application using the StreamHub Java SDK for Streaming and the AJAX Client API. By the end of the guide we'll have a cross-browser webpage that will be receiving real-time data pushed from the server. This guide assumes you know what <a href="http://www.stream-hub.com/about-comet.html">Comet</a> is and have some basic JavaScript and Java knowledge but it doesn't get too deep so don't worry.<div><br /></div><div><b>Step 1 - Download the Free Community Edition</b></div><div><br /></div><div>First of all we need to download the StreamHub SDK from the website. Go to the <a href="http://www.stream-hub.com/download.html">StreamHub download page</a> and grab yourself a copy of the Community Edition. At time of writing the latest version was 2.0 but any version should work. There isn't any real difference between the .ZIP version and the .TAR.GZ version - so grab which ever one you prefer. After downloading, extract the archive somewhere you can store it permanently. I put mine in <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub</span>. Don't worry at this point if you're using Linux or Mac - the StreamHub server is completely cross platform. </div><div><br /></div><div><b>Step 2 - Creating the 'Hello World' web page</b></div><div><b><br /></b></div><div>Let's create a simple web page to host our Comet application. Create a new folder in your StreamHub directory called HelloWorld, so now you'll have something like <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\HelloWorld</span>. Create a new file in the HelloWorld directory called <span class="Apple-style-span" style="font-family:'courier new';">index.html</span>. This will be our Comet web page. Edit that file, adding the following:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Hello World Comet Application</title><br /></head><br /><body><br /><h1>Hello World Comet Application</h1><br /><input type="button" value="Start streaming" onclick="startStreaming()"><br /><div id="streamingData"></div><br /><script><br />function startStreaming() {<br />// empty for now<br />}<br /></script><br /></body><br /></html><br /></code></pre><div>That's it - all we've done so far is create a very basic HTML page with a single button that when clicked triggers an empty JavaScript function. We'll need to add the StreamHub JavaScript API in order to connect to the server, so lets grab that from the Community Edition we downloaded earlier and include it in our script. The JavaScript API comes as a single mini-fied file called <span class="Apple-style-span" style="font-family:'courier new';">streamhub-min.js</span>. Its in the archive we extracted in step 1, mine was in the directory <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\examples\lib\js</span>.</div><div><br /></div><div>Copy this file and paste it in the HelloWorld folder. Now we just need to include it in our web page, the new <span class="Apple-style-span" style="font-family:'courier new';">index.html</span> should look something like this:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Hello World Comet Application</title><br /><script src="streamhub-min.js" type="text/javascript"></script><br /></head><br /><body><br /><h1>Hello World Comet Application</h1><br /><input type="button" value="Start streaming" onclick="startStreaming()"><br /><div id="streamingData"></div><br /><script><br />function startStreaming() {<br />// empty for now<br />}<br /></script><br /></body><br /></html><br /></code></pre><div><b>Step 3 - Creating a Java Adapter for Streaming</b></div><div><b><br /></b></div><div>Now we've got a basic webpage we need to provide some sort of data to it before we connect to the Comet server. So in this section we'll be creating a HelloWorldStreamer Java class to stream data to our webpage.</div><div><br /></div><div>Create a new file in the HelloWorld directory called <span class="Apple-style-span" style="font-family:'courier new';">HelloWorldStreamer.java</span>. First we need to add the code to create and start the Comet server. Edit <span class="Apple-style-span" style="font-family:'courier new';">HelloWorldStreamer.java</span>, adding the following:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br /><br />public class HelloWorldStreamer {<br />public static void main(String[] args) throws Exception {<br /> new HelloWorldStreamer();<br />}<br /><br />public HelloWorldStreamer() throws Exception {<br /> // Create a new server on port 7878<br /> PushServer server = new NIOServer(7878);<br /> server.start();<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> server.stop();<br />}<br />}<br /></code></pre><div>This creates the Comet server and starts it. To actually stream some data to our webpage we'll need to add ourselves as a listener by changing the code to:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>import com.streamhub.api.Client;<br />import com.streamhub.api.SubscriptionListener;<br />import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br /><br />public class HelloWorldStreamer implements SubscriptionListener {<br />public static void main(String[] args) throws Exception {<br /> new HelloWorldStreamer();<br />}<br /><br />public HelloWorldStreamer() throws Exception {<br /> // Create a new server on port 7878<br /> PushServer server = new NIOServer(7878);<br /> server.start();<br /> server.getSubscriptionManager().addSubscriptionListener(this);<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> server.stop();<br />}<br /><br />public void onSubscribe(String topic, Client client) {<br /><br />}<br /><br />public void onUnSubscribe(String topic, Client client) {<br /><br />}<br />}<br /></code></pre><div>Notice we now implement <b>SubscriptionListener</b> which requires us to implement the <b>onSubscribe</b> and <b>onUnSubscribe</b> methods. These methods will be called when a client, such as our HelloWorld web page, subscribes or unsubscribes to a particular topic. For now lets just send a synchronous response back to the client when they subscribe:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>import com.streamhub.api.Client;<br />import com.streamhub.api.SubscriptionListener;<br />import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br />import com.streamhub.api.JsonPayload;<br /><br />public class HelloWorldStreamer implements SubscriptionListener {<br />public static void main(String[] args) throws Exception {<br /> new HelloWorldStreamer();<br />}<br /><br />public HelloWorldStreamer() throws Exception {<br /> // Create a new server on port 7878<br /> PushServer server = new NIOServer(7878);<br /> server.start();<br /> server.getSubscriptionManager().addSubscriptionListener(this);<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> server.stop();<br />}<br /><br />public void onSubscribe(String topic, Client client) {<br /> JsonPayload payload = new JsonPayload(topic);<br /> payload.addField("Response", "Hello World!");<br /> client.send(topic, payload);<br />}<br /><br />public void onUnSubscribe(String topic, Client client) {<br /><br />}<br />}<br /></code></pre><div>All we do here is create a new <b>Payload</b> (or message), add a field with a key of "Response" and value of "Hello World!", then send it to the client that subscribed. We'll see how to subscribe in the next step.</div><div><br /></div><div><b>Step 4 - Connecting to the Comet Server and Subscribing to a Topic</b></div><div><br /></div><div>Go back and edit the <span class="Apple-style-span" style="font-family:arial;">index.html</span> file in the HelloWorld directory. We're going to add the code to connect and subscribe:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><html><br /><head><br /><title>Hello World Comet Application</title><br /><script src="streamhub-min.js" type="text/javascript"></script><br /></head><br /><body><br /><h1>Hello World Comet Application</h1><br /><input type="button" value="Start streaming" onclick="startStreaming()"><br /><div id="streamingData"></div><br /><script><br />function topicUpdated(sTopic, oData) {<br />var newDiv = document.createElement("DIV");<br />newDiv.innerHTML = "Update for topic '" + sTopic + "' Response: '" + oData.Response + "'";<br />document.getElementById('streamingData').appendChild(newDiv);<br />}<br /><br />function startStreaming() {<br />var hub = new StreamHub();<br />hub.connect("http://localhost:7878/");<br />hub.subscribe("HelloWorld", topicUpdated);<br />}<br /></script><br /></body><br /></html><br /><br /></code></pre><div>Connecting is really easy. We just create a new StreamHub object and connect to the Comet server we created in <span class="Apple-style-span" style="font-family:'courier new';">HelloWorldStreamer.java</span>:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code> var hub = new StreamHub();<br />hub.connect("http://localhost:7878/");<br /></code></pre><div>To subscribe we need to specify a topic and an <b>update listener</b>.</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code> hub.subscribe("HelloWorld", topicUpdated);<br /></code></pre><div>The topic will be passed to the <b>onSubscribe</b> method in our HelloWorldStreamer. The update listener is just a JavaScript function with the arguments <b>sTopic</b>, the topic that has been updated, and <b>oData</b>, a JSON object containing the <b>Payload</b> we sent in our <b>onSubscribe</b> method. You don't need to understand too much about JSON for this guide, just know that any field we put in the <b>Payload</b> in our HelloWorldStreamer, we can get that same field out of <b>oData</b> using the key. In our listener we get the 'Response' field put it inside a new div and append it to the <b>streamingData</b> div:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>function topicUpdated(sTopic, oData) {<br />var newDiv = document.createElement("DIV");<br />newDiv.innerHTML = "Update for topic '" + sTopic + "' Response: '" + oData.Response + "'";<br />document.getElmentById('streamingData').appendChild(newDiv);<br />}<br /></code></pre><div>If you don't understand too much about JavaScript - this will just display every message we receive on our webpage inside the <b>streamingData </b>HTML element. <i>Note: update listeners don't need to have a specific name, we've just opted to call this one topicUpdated.</i> OK, now we're almost ready to try it out.</div><div><br /></div><div><b>Step 5 - Compiling HelloWorldStreamer and Starting the Server</b></div><div><br /></div><div>Just before we compile HelloWorldStreamer we need to make a couple of changes. Using <b>addStaticContentDir </b>we will make the HelloWorld folder available via the Comet server. Setting the file to <span class="Apple-style-span" style="font-family:'courier new';">"."</span> means we're adding the current directory. Although StreamHub is capable of serving normal static content, for example HTML pages, it was primarily designed as a Comet server. For a live website I would recommend serving static content from a standard HTTP Web server such as Apache or IIS. However, for our 'Hello World' application this will do just fine.</div><div><br /></div><div>To compile and run HelloWorldStreamer we just need to copy a few Java JAR libraries and the license file. The JARs can be found in the Community Edition downloaded in step one. You will need<span class="Apple-style-span" style="font-family:'courier new';"> streamhub-2.0.jar</span>, <span class="Apple-style-span" style="font-family:'courier new';">json-20080701.jar</span> and <span class="Apple-style-span" style="font-family:'courier new';">log4j-1.2.14.jar</span>. Mine were in the folder <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\examples\lib\jar</span>. Copy the JARs to the HelloWorld directory. You will also need a license file, if you have an evaluation or development license copy this over to the HelloWorld directory, otherwise copy the Community Edition license over. I used the Community Edition license at <span class="Apple-style-span" style="font-family:'courier new';">C:\streamhub\streamhub-java-adapter-sdk-1.0\license.txt</span>. You also might want to copy over the <span class="Apple-style-span" style="font-family:'courier new';">conf</span> directory containing the <b>log4j</b> configuration. Now, open a command prompt, navigate to the HelloWorld directory and execute the following command to compile:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>javac -cp streamhub-2.0.2.jar HelloWorldStreamer.java<br /></code></pre><div>Now start it up:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>java -cp .;streamhub-2.0.2.jar;json-20080701.jar;log4j-1.2.14.jar HelloWorldStreamer<br /></code></pre><div>On Unix systems you'll need to replace the ';' with a ':', like so:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>java -cp .:streamhub-2.0.2.jar:json-20080701.jar:log4j-1.2.14.jar HelloWorldStreamer<br /></code></pre><div>You should now see a message along the lines of:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>Comet server started at http://localhost:7878/.<br />Press any key to stop...<br /></code></pre><div>Open a browser and go to the address <a href="http://localhost:7878/">http://localhost:7878</a>/. You should now see the HelloWorld web page we created earlier. Click the <b>"Start streaming"</b> button. You should now see a message on the page saying:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>Update for topic 'HelloWorld'. Response: 'Hello World!'<br /></code></pre><div>That's it - your first Comet message! However, one message is pretty boring, let's change the HelloWorldStreamer to continually stream messages in true Comet fashion.</div><div><br /></div><div><b>Step 6 - Updating HelloWorldStreamer to Continuously Stream</b></div><div><br /></div><div>Stop the server if it's still running and open <span class="Apple-style-span" style="font-family:'courier new';">HelloWorldStreamer.java</span> for editing. First of all we're going to add a new <b>ContinuousStreamer</b> inner class which streams data until you stop the server. The final <span class="Apple-style-span" style="font-family:'courier new';">HelloWorldStreamer.java</span> should look like this:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>import java.io.File;<br />import com.streamhub.api.PushServer;<br />import com.streamhub.nio.NIOServer;<br />import com.streamhub.api.Client;<br />import com.streamhub.api.SubscriptionListener;<br />import com.streamhub.api.JsonPayload;<br /><br />public class HelloWorldStreamer implements SubscriptionListener {<br />public static void main(String[] args) throws Exception {<br /> new HelloWorldStreamer();<br />}<br /><br />public HelloWorldStreamer() throws Exception {<br /> PushServer server = new NIOServer(7878);<br /> server.addStaticContent(new File("."));<br /> server.start();<br /> server.getSubscriptionManager().addSubscriptionListener(this);<br /> ContinuousStreamer continuousStreamer = new ContinuousStreamer(server);<br /> new Thread(continuousStreamer).start();<br /> System.out.println("Comet server started at http://localhost:7878/.");<br /> System.out.println("Press any key to stop...");<br /> System.in.read();<br /> continuousStreamer.stop();<br /> server.stop();<br />}<br /><br />public void onSubscribe(String topic, Client client) {<br /> JsonPayload payload = new JsonPayload(topic);<br /> payload.addField("Response", "Hello World! Initial Response");<br /> client.send(topic, payload);<br /><br />}<br /><br />public void onUnSubscribe(String topic, Client client) {<br /><br />}<br /><br />private static class ContinuousStreamer implements Runnable {<br /> private boolean isStopped = false;<br /> private int updateNumber = 0;<br /> private final PushServer server;<br /><br /> public ContinuousStreamer(PushServer server) {<br /> this.server = server;<br /> }<br /><br /> public void run() {<br /> while (!isStopped) {<br /> JsonPayload payload = new JsonPayload("HelloWorld");<br /> payload.addField("Response", "Hello World! Response number " + updateNumber++);<br /> server.publish("HelloWorld", payload);<br /><br /> try {<br /> // Sleep for one second (1000ms)<br /> Thread.sleep(1000);<br /> } catch (InterruptedException e) {}<br /> }<br /> }<br /><br /> public void stop() {<br /> isStopped = true;<br /> }<br />}<br />}<br /></code></pre><div>Notice in the ContinuousUpdateStreamer we don't use <span class="Apple-style-span" style="font-family:'courier new';">client.send()</span>, but instead we use <span class="Apple-style-span" style="font-family:'courier new';">server.publish()</span>. Using <span class="Apple-style-span" style="font-family:'courier new';">client.send()</span> is a way of sending something to an individual client - whatever you send using this method will go to this client and this client only. Whereas, using <span class="Apple-style-span" style="font-family:'courier new';">server.publish(topic, payload)</span> will send that payload to every client who is subscribed to that topic. In most cases you should use <span class="Apple-style-span" style="font-family:'courier new';">server.publish()</span> as it knows best who is subscribed and who isn't. Using <span class="Apple-style-span" style="font-family:'courier new';">client.send()</span> to send an initial message inside <b>onSubscribe</b> is a common and good use. The only other time to prefer <span class="Apple-style-span" style="font-family:'courier new';">client.send()</span> is when each client will be receiving unique data. Lets compile and run one more time. Now when you click the <b>"Start streaming"</b> button you should see something like the following:</div><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>Update for topic 'HelloWorld' Response: 'Hello World! Initial Response'<br />Update for topic 'HelloWorld' Response: 'Hello World! Response number 8'<br />Update for topic 'HelloWorld' Response: 'Hello World! Response number 9'<br />Update for topic 'HelloWorld' Response: 'Hello World! Response number 10'<br />...<br /></code></pre><br /><div>The updates will keep streaming until you stop the server. That's the guide finished. The source code is available to download here: <a href="http://www.stream-hub.com/download-page.html?download=CometHelloWorld-2.0.2.zip">CometHelloWorld-2.0.2.zip</a>. A good next step is to explore the examples that come with the Community Edition. We hope you found this useful - if you have any problems or suggestions for other guides and tutorials please comment.</div>StreamHub Teamhttp://www.blogger.com/profile/05639361016094370609noreply@blogger.com6