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

<channel>
	<title>Phil Leggetter - Real-Time Web Software and Technology Evangelist &#187; real-time</title>
	<atom:link href="http://www.leggetter.co.uk/tag/real-time/feed" rel="self" type="application/rss+xml" />
	<link>http://www.leggetter.co.uk</link>
	<description>Real-Time Web, Real-Time Data and Social Media Software and Technology Evangelist and Consultant</description>
	<lastBuildDate>Sun, 29 Jan 2012 05:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Adding a real-time &quot;Who&#8217;s shopping?&quot; widget to an ASP.NET Web App</title>
		<link>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html</link>
		<comments>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html#comments</comments>
		<pubDate>Thu, 04 Aug 2011 00:00:00 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time web]]></category>

		<guid isPermaLink="false">http://blog.pusherapp.com/2011/8/3/adding-a-real-time-who-s-shopping-widget-to-an-asp-net-web-app</guid>
		<description><![CDATA[<p>In our last ASP.NET post, <a href="http://blog.pusher.com/2011/6/25/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application">The easiest way to add real-time functionality to an ASP.NET e-commerce application</a>, I demonstrated how to add realtime stock level updates and notifications to an ASP.NET e-commerce application. In this post I&#8217;m going to show how to add a &#8220;Who&#8217;s shopping?&#8221; widget to the same application. The purpose of [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html' rel='bookmark' title='The easiest way to add real-time functionality to an ASP.NET e-commerce application'>The easiest way to add real-time functionality to an ASP.NET e-commerce application</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/17/kwwika-powered-real-time-opta-sports-cricket-widget.html' rel='bookmark' title='Kwwika Powered Real-Time Opta Sports Cricket Widget'>Kwwika Powered Real-Time Opta Sports Cricket Widget</a></li>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In our last ASP.NET post, <a  href="http://blog.pusher.com/2011/6/25/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application">The easiest way to add real-time functionality to an ASP.NET e-commerce application</a>, I demonstrated how to add realtime stock level updates and notifications to an ASP.NET e-commerce application. In this post I&#8217;m going to show how to add a &#8220;Who&#8217;s shopping?&#8221; widget to the same application. The purpose of this widget is to show other users that interest in the product they are viewing is high and that, in combination with the realtime stock levels, will encourage them to make a purchase before the product sells out.</p>
<p>In this tutorial I&#8217;ll show how to:</p>
<ul>
<li>subscribe to a presence channel</li>
<li>authenticate a subscription to a channel</li>
<li>provide Pusher with additional information about a user</li>
<li>display presence information on a product page for the &#8220;Who&#8217;s shopping?&#8221; widget</li>
</ul>
<p>If you are desperate to see the demo in action you can see the <a  href="http://realtimewebstore.apphb.com/">Real-Time Web Store demo here</a>.</p>
<h2>Pusher Presence</h2>
<p>To achieve the &#8220;Who&#8217;s shopping?&#8221; functionality I&#8217;m going to be using a feature in Pusher called <a  href="http://pusher.com/docs/client_api_guide/client_channels#subscribe-presence-channels">presence</a>. Presence provides you with additional information about a channel you are subscribed to so that you know:</p>
<ul>
<li>who is subscribed to that channel</li>
<li>when new users subscribe</li>
<li>when existing users unsubscribe (by either actually unsubscribing or navigating away from the page).</li>
</ul>
<p>We are going to have a presence channel per product so that we know who is viewing each product.</p>
<h2>User Info &amp; Authentication</h2>
<h3>Subscribing to a presence channel</h3>
<p>You subscribe to a presence channel in the same way that you do to any other channel but the name of the channel must have a <code>presence-</code> prefix. Presence channels are normal channels with two additions; authentication and presence information. With this in mind we are just going to update our application to use a presence channel.</p>
<p>The JavaScript that makes the subscription in our Razor view looks like this:</p>
<pre><code>var productId = "@Model.ProductId";
var pusher = new Pusher("APP_KEY");
var channel = pusher.subscribe("presence-" + productId);
</code></pre>
<p>We also need to update the code in our <code>StoreController</code> to publish our stock events on the new presence channel:</p>
<pre><code>var stockEvent = new StockUpdatedEvent(model, socketId);
ObjectPusherRequest request = new ObjectPusherRequest("presence-" + stockEvent.ProductId, "stockUpdated", stockEvent);
_provider.Trigger(request);
</code></pre>
<p><em>Note: If you are continuing where we left off in our last blog post there are a final couple of updates that are required to change the app to use the latest version of the Pusher JavaScript API. We recently released version 1.9 which introduced <a  href="http://blog.pusher.com/2011/7/12/connections-states">new connection state functionality</a> and also a new <code>connection</code> object. So, update your Pusher script tag as follows:</em></p>
<pre><code>&lt;script src="http://js.pusherapp.com/1.9/pusher.js"&gt;&lt;/script&gt;
</code></pre>
<p><em>And you&#8217;ll also need to update any pieces of code that access the <code>socket_id</code> via the <code>Pusher</code> instance. It should now be accessed via the new <code>connection</code> object as follows:</em></p>
<pre><code>var socketId = pusher.connection.socket_id;
</code></pre>
<h3>Getting User information</h3>
<p>If Pusher is to send events about users subscribing to and unsubscribing from presence channels it needs information about the users. It gets this information from your application when the subscription request to the channel is made (<code>pusher.subscribe('presence-channel')</code>). Since we can&#8217;t really trust the web browser/client (it&#8217;s so easy to hack JavaScript running in a web browser) the Pusher library requests this information from your web server by making an AJAX call. By default this call goes to <code>/pusher/auth</code> and passes two parameters; <code>channel_name</code>, which is the name of the channel being subscribed to, and <code>socket_id</code>, which is a unique identifier for the current user&#8217;s connection to Pusher.</p>
<pre><code>/pusher/auth/?channel_name=presence-pusher-tshirt&amp;socket_id=&lt;unique_socket_id&gt;
</code></pre>
<p>When our application responds to this request we must provide an authentication signature to confirm that the user can subscribe to the channel and, importantly for our &#8220;Who&#8217;s shopping?&#8221; widget, information about the current user. The way we&#8217;ll handle this within our ASP.NET MVC application is by creating a <code>PusherController</code> with an <code>Auth(string socket_id, string channel_name)</code> action, and by using the authentication functionality within the <a  href="https://github.com/leggetter/pusher-rest-dotnet">PusherRESTDotNet library</a>. This library is also available as a <a  href="http://nuget.org/List/Packages/PusherRESTDotNet">NuGet package</a>.</p>
<p><em>Note: If you got the NuGet package as part of the last tutorial you&#8217;ll need to update it since the authentication functionality has just been added. You should also check that the .NET 3.5 runtime version of Newtonsoft.Json is added.</em></p>
<h3>Handling the authentication request</h3>
<p>As mentioned above, the Pusher JavaScript library will make a request to <code>/pusher/auth</code> when making the authentication request. Our new <code>PusherController</code> with <code>Auth</code> action does the following:</p>
<ol>
<li>Fetches our Pusher credentials from the Web.config file.</li>
<li>Creates a new <code>PusherProvider</code> using the Pusher credentials</li>
<li>Creates a unique <code>user_id</code> for the presence channel</li>
<li>Creates an authentication string and returns that string as the <code>Content</code> of a <code>ContentResult' with the</code>ContentType<code>set to</code>application/json` in response to the AJAX request.</li>
</ol>
<p>For the moment this code doesn&#8217;t do any user authentication or provide any additional information about the current user.</p>
<pre><code>using System;
using System.Configuration;
using System.Web.Mvc;
using PusherRESTDotNet;
using PusherRESTDotNet.Authentication;

namespace RealTimeWebStore.Controllers
{
    public class PusherController : Controller
    {
        public ActionResult Auth(string channel_name, string socket_id)
        {
            var applicationId = ConfigurationManager.AppSettings["application_id"];
            var applicationKey = ConfigurationManager.AppSettings["application_key"];
            var applicationSecret = ConfigurationManager.AppSettings["application_secret"];

            var channelData = new PresenceChannelData()
            {
                user_id = Guid.NewGuid().ToString()
            };

            var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
            string authJson = provider.Authenticate(channel_name, socket_id, channelData);

            return new ContentResult { Content = authJson, ContentType = "application/json" };
        }
    }
}
</code></pre>
<p>If we use one of the many web browser development tools available to us to inspect the authentication call within the browser we&#8217;ll see the JSON response coming back.</p>
<p><img alt="Screen+shot+2011-08-04+at+17" src="http://blog.pusher.com/media/2011/08/04/09/07/01/978/Screen+shot+2011-08-04+at+17.06.17.jpg?m=resize&amp;o%5Bgeometry%5D=500x400&amp;s=0d9d3c037a95e8d6" /></p>
<p>You&#8217;ll see the response contains a <code>channel_data</code> property which itself has a <code>user_id</code> with a unique <a  href="http://msdn.microsoft.com/en-us/library/system.guid.aspx"><code>Guid</code></a> value and a <code>user_info</code> property with a <code>null</code> value. Pusher uses this <code>user_id</code> value to uniquely identify the user subscription to the presence channel. So it&#8217;s very important to make sure that each user has a unique ID.</p>
<h3>Adding authentication</h3>
<p>We&#8217;ve mentioned authentication a few times but as yet we haven&#8217;t authenticated the user. If the user has already logged (our app doesn&#8217;t have this functionality, but most do) in we can use the existing <code>User.Identity</code> or else we can just assign a guest identity to the user. Once we have a unique ID for the user we&#8217;ll also add some additional <code>user_info</code> to the <code>channelData</code>. The value of <code>user_info</code> can be anything you like from a simple string to a complex object. This gives you the ability to push as much additional information through Pusher and to the web page as you like. In our case we&#8217;ll just send through a timestamp which identifies how long the user has been on the site.</p>
<pre><code>public ActionResult Auth(string channel_name, string socket_id)
{
    var channelData = new PresenceChannelData();
    if (User.Identity.IsAuthenticated)
    {
        channelData.user_id = User.Identity.Name;
    }
    else
    {
        channelData.user_id = GetUniqueUserId();
    }
    channelData.user_info = GetUserInfo();

    var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
    string authJson = provider.Authenticate(channel_name, socket_id, channelData);

    return new ContentResult { Content = authJson, ContentType = "application/json" };
}
</code></pre>
<p><em>Note: In our case we don&#8217;t really need to authorise a user but in other situations where the user needs to be logged in we can return a 401  <a  href="http://msdn.microsoft.com/en-us/library/system.web.mvc.httpstatuscoderesult(v=vs.98).aspx?ppud=4"><code>HttpStatusCodeResult</code></a>.</em></p>
<h2>Who&#8217;s Shopping?</h2>
<p>Now that we&#8217;ve got a <code>PusherController</code> that gives Pusher information about the user, we can start showing information about the user on the product page. You can get information about the users subscribed to presence channels by binding to the <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#pusher-subscription-succeeded"><code>pusher:subscription_succeeded</code></a> event on the presence channel object. The callback method for this event receives a <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#members-parameter"><code>members</code></a> parameter which contains all the information about users subscribed to the channel.</p>
<p>First we&#8217;ll create some HTML within our web page where we are going to show &#8220;Who&#8217;s shopping?&#8221;. Then we&#8217;ll add the users to the HTML when pusher notifies us of them.</p>
<p><strong>HTML</strong></p>
<pre><code>&lt;div class="whos-shopping"&gt;
    &lt;h3&gt;Who's shopping?&lt;/h3&gt;
    &lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
</code></pre>
<p><strong>JavaScript</strong></p>
<pre><code>var pusher = new Pusher("006c79b1fe1700c6c10d");
var channel = pusher.subscribe("presence-" + productId);
channel.bind("pusher:subscription_succeeded", function(members) {

    members.each(function(member) {
        addMember(member);
    });

});

function addMember(member) {
    var enteredSite = new Date(member.info.timestamp);
    var now = new Date();
    var timeOnSite = (now - enteredSite);
    var li = $("&lt;li data-user-id='" + member.id + "'&gt;" +
                    member.id + " here for " +
                    toReadableTime(timeOnSite) +
               "&lt;/li&gt;");
    $(".whos-shopping ul").append(li);
};
</code></pre>
<p><em>Note: The <code>members</code> object comes with a handy <code>each</code> method to make iterating the members collection really easy.</em></p>
<p>Of course new users can navigate to the page and existing users can leave it so the Pusher JavaScript library also exposes <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#pusher-member-added"><code>pusher:member_added</code></a> and <a  href="http://pusher.com/docs/client_api_guide/client_presence_events#pusher-member-removed"><code>pusher:member_removed</code></a> events on the presence channel object. When these events fire we should add or remove the user as required.</p>
<pre><code>channel.bind("pusher:member_added", function(member) {
    addMember(member);
});
channel.bind("pusher:member_removed", function(member) {
    removeMember(member);
});

function addMember(member) {
    /* as before */
};

function removeMember(member) {
    $(".whos-shopping ul li[data-user-id='" + member.id + "']").remove();
};
</code></pre>
<p>With this in place we now have a fully functioning &#8220;Who&#8217;s shopping?&#8221; widget that shows the current user who else is viewing the same product as they are.</p>
<p><img alt="Screen+shot+2011-08-03+at+21" src="http://blog.pusher.com/media/2011/08/03/13/19/53/544/Screen+shot+2011-08-03+at+21.10.42.jpg?m=resize&amp;o%5Bgeometry%5D=500x400&amp;s=ee8762b09260ca71" /></p>
<p>As mentioned in the opening paragraph, the theory here is that if shoppers can see that others users are viewing the same product it might give them that little push they need to take the plunge and make that purchase &#8220;while stocks last&#8221;.</p>
<p>There are a few refinements and enhancements that could be made to this widget such as filtering out the current user from the &#8220;Who&#8217;s shopping?&#8221; list or possibly showing them which one they are. You could also use the notification system from last time to notify the shopper when another shopper joins or leaves the product page. And, of course, you could add some user chat functionality to get the users discussing the product and really engaging. You could also have a staff member user who could answer any questions that the shoppers may have.</p>
<p>Just as last time all the code from this post is available in the <a  href="https://github.com/leggetter/realtime-webstore">real-time web store github repo</a>. You can also see the <a  href="http://realtimewebstore.apphb.com/">Real-Time Web Store application up and running</a> on <a  href="https://appharbor.com/">AppHarbor</a>. I&#8217;ve tried to link to relevant parts of the <a  href="http://pusher.com/docs">Pusher documentation</a> throughout the post but if there anything that isn&#8217;t clear, if there&#8217;s anything that I&#8217;ve not provided enough detail on and it all just seems too <em>&#8216;magical&#8217;</em>, then please leave a comment or send an email to me (<a  href="mailto:phil@pusher.com?subject=ASP.NET%20real-time%20web%20store">phil@pusher.com</a>).</p>
<p>Here are some links to the key things covered in this post:</p>
<ul>
<li><a  href="http://pusher.com/docs/presence">Presence channels</a></li>
<li><a  href="http://pusher.com/docs/client_api_guide/client_presence_events">Presence channel events</a></li>
<li><a  href="http://pusher.com/docs/authenticating_users">Authenticating Users</a></li>
<li><a  href="http://pusher.com/docs/rest_libraries#cs">Pusher REST .NET Library</a> | <a  href="http://nuget.org/List/Packages/PusherRESTDotNet">NuGet package</a></li>
<li><a  href="https://github.com/leggetter/realtime-webstore">ASP.NET real-time web store in github</a></li>
<li><a  href="http://realtimewebstore.apphb.com/">Real-Time Web Store application up and running</a></li>
<li><a  href="http://www.asp.net/mvc/mvc3">ASP.NET MVC 3</a></li>
</ul>
<h2>Addendum: What about WebForms?</h2>
<p>The post above shows how to user the Pusher REST .NET library within an ASP.NET MVC application but it can just as easily be used within an ASP.NET WebForms app. The way I achieved this was by adding a new Generic HTTP Handler to our web app which will handle the authentication AJAX call.</p>
<p><img alt="Screen+shot+2011-08-02+at+16" src="http://blog.pusher.com/media/2011/08/03/13/22/53/682/Screen+shot+2011-08-02+at+16.07.19.jpg?m=resize&amp;o%5Bgeometry%5D=500x400&amp;s=8b9774ad1cdd29ca" /></p>
<p>In the code below the <code>ProcessRequest</code> method does the following things:</p>
<ol>
<li>Fetches our Pusher credentials from the Web.config file.</li>
<li>Gets the values of the <code>channel_name</code> and <code>socket_id</code> parameters from the <code>context.Request</code></li>
<li>Creates a new <code>PusherProvider</code> using the Pusher credentials</li>
<li>Creates a unique <code>user_id</code> for the presence channel</li>
<li>Creates an authentication string and returns that string as the response body of the AJAX request.</li>
</ol>
<p>For the moment this code doesn&#8217;t do any user authentication or provide any additional information about the current user.</p>
<pre><code>using System.Configuration;
using System.Web;
using PusherRESTDotNet;
using PusherRESTDotNet.Authentication;
using System;

namespace RealTimeWebStore
{
    public class AuthHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            var applicationId = ConfigurationManager.AppSettings["pusher-application-id"];
            var applicationKey = ConfigurationManager.AppSettings["pusher-application-key"];
            var applicationSecret = ConfigurationManager.AppSettings["pusher-application-secret"];

            var socketID = context.Request["socket_id"].ToString();
            var channelName = context.Request["channel_name"].ToString();
            var channelData = new PresenceChannelData()
            {
                user_id = Guid.NewGuid().ToString()
            };

            var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
            string authJson = provider.Authenticate(channelName, socketId,  channelData);

            context.Response.Write(authJson);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
</code></pre>
<p>Finally we need to configure our handler in the application <code>Web.config</code> file. We want the <code>ProcessRequest</code> method of our handler to be invoked for any call to <code>/pusher/auth</code>. To do this we just add a handler to the <code>httpHandlers</code> element and specify our handler, <code>RealTimeWebStore.AuthHandler</code> as the handler:</p>
<pre><code>&lt;system.web&gt;
  &lt;!-- other config --&gt;
  &lt;httpHandlers&gt;
    &lt;add verb="*"
         path="/pusher/auth/"
         type="RealTimeWebStore.AuthHandler" /&gt;
  &lt;/httpHandlers&gt;
&lt;/system.web&gt;
</code></pre>
<p><script>
var div = $("
<div/>")
.css({
"text-align":"center",
"margin":"auto",
"margin-bottom":"10px"
});
$(".entrybody img")
.css({
"-moz-border-radius": "4px", 
"-webkit-border-radius": "4px", 
"-o-border-radius": "4px", 
"-ms-border-radius": "4px", 
"-khtml-border-radius": "4px", 
"border-radius": "4px", 
"border": "1px solid #DEDEDE", 
"padding": "4px"})
.wrap(div);
</script></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html' rel='bookmark' title='The easiest way to add real-time functionality to an ASP.NET e-commerce application'>The easiest way to add real-time functionality to an ASP.NET e-commerce application</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/17/kwwika-powered-real-time-opta-sports-cricket-widget.html' rel='bookmark' title='Kwwika Powered Real-Time Opta Sports Cricket Widget'>Kwwika Powered Real-Time Opta Sports Cricket Widget</a></li>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The easiest way to add real-time functionality to an ASP.NET e-commerce application</title>
		<link>http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html</link>
		<comments>http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html#comments</comments>
		<pubDate>Tue, 05 Jul 2011 00:00:00 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time web]]></category>

		<guid isPermaLink="false">http://blog.pusherapp.com/2011/6/25/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application</guid>
		<description><![CDATA[While adding realtime functionality to ASP.NET applications has often seemed difficult due to the connection limitations of the IIS platform, it can actually be achieved fairly easily by offloading this component to third party services like Pusher. In...
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html' rel='bookmark' title='Adding a real-time &quot;Who&#8217;s shopping?&quot; widget to an ASP.NET Web App'>Adding a real-time &quot;Who&#8217;s shopping?&quot; widget to an ASP.NET Web App</a></li>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
<li><a href='http://www.leggetter.co.uk/2009/11/07/which-rich-internet-application-technology-will-dominate.html' rel='bookmark' title='Which Rich Internet Application Technology will dominate?'>Which Rich Internet Application Technology will dominate?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>While adding realtime functionality to ASP.NET applications has often seemed difficult due to the connection limitations of the IIS platform, it can actually be achieved fairly easily by offloading this component to third party services like Pusher. In this series of posts, I&#8217;ll get you started with this exciting technology through a number of hands-on tutorials. In the first one we&#8217;ll build a simple e-commerce application that displays realtime stock levels to the customers.</p>
<p>One of the problems with existing e-commerce solutions can be trying to buy something which, whilst you&#8217;ve been online, has sold out. This can be a big problem for high demand products like gig tickets or sporting events such as the Olympics. A really good way of avoiding this is to show the customers just how fast tickets are selling. The added benefit of this, from a business point of view, is that it can give users that little push they needed to make that purchase. In this tutorial I&#8217;ll show how to:</p>
<ul>
<li>establish a connection to Pusher in the view</li>
<li>subscribe to a product channel</li>
<li>bind events from this channel to our stock indicator in the view and update the stock level</li>
<li>send stock level update from our server when someone buys something</li>
</ul>
<h2>Getting started</h2>
<p>To demonstrate adding real-time functionality to an ASP.NET website I&#8217;m going to start with a simple one page e-commerce site which has one product: our cool Pusher t-shirt (Sorry, they&#8217;re not really for sale. You&#8217;ve got to earn them!). On the product page there is a counter which tells the customer how many t-shirts we have in stock.</p>
<div style="margin:auto; text-align:center;margin-bottom:20px;"><img alt="One-browser" src="http://blog.pusher.com/media/2011/06/27/05/04/29/40/one-browser.jpg?m=resize&amp;o%5Bgeometry%5D=600x300&amp;s=413d474f960a2e7c" /></div>
<p>To start off with our e-commerce website is a simple ASP.NET MVC3 app with:</p>
<ul>
<li>A <code>StoreController</code> with two actions. One to display the default view and one to handle the &#8220;Buy&#8221; button being clicked and the stock level being decreased.</li>
<li>A single <a  href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx">Razor</a> view displaying the single product</li>
<li>Two models; one for the product called <code>ProductModel</code> and one for images called <code>ProductImage</code></li>
<li>A <code>ProductRepository</code> where we store our products</li>
</ul>
<h2>Connect to Pusher</h2>
<p>As I&#8217;ve already said, adding real-time functionality is really simple &#8211; that&#8217;s the point! Firstly we have to include the Pusher JavaScript client library. We&#8217;ll add this to the view for the moment although we might want to make the include part of the site layout in the future.</p>
<p><em>Note: If your e-commerce page was being served up over HTTPS you would include our library over HTTPS too to avoid any browser warnings.</em></p>
<p>Since we are using ASP.NET MVC we&#8217;ve already got jQuery included from the <code>_Layout.cs.html</code> so we can wait until the page has loaded and connect to Pusher. The script include and the code that connects to Pusher looks as follows:</p>
<pre><code>&lt;script src="http://js.pusherapp.com/1.8/pusher.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
    $(function() {
        var pusher = new Pusher("006c79b1fe1700c6c10d");
    });
&lt;/script&gt;
</code></pre>
<h2>Subscribe to the product channel</h2>
<p>Now that we&#8217;ve connected to Pusher we can push events from our StoreController to all connected browsers if any information changes about the product. The main piece of information that customers might want to know about is if the stock level changes. These t-shirts could sell out fast!</p>
<p>We need to choose a channel name to subscribe and publish to and the obvious choice is to use the unique product id for this. We&#8217;ll also prefix it with <code>product-</code> just so it&#8217;s really clear that the channels is for a product. We subscribe to this channel on the client as follows getting the product id from the Model that has been bound to the page:</p>
<pre><code>var channel = pusher.subscribe("product-@Model.ProductId");
</code></pre>
<h2>Bind to stock update events</h2>
<p>Once we&#8217;ve got a channel object we can bind to events on it. We want to be informed when the stock level changes so let&#8217;s bind to an event called <code>stockUpdated</code>. We&#8217;ll also expect a JSON object to be passed which represents the <code>ProductModel</code> and will have the same properties on it. That way we can simply update the stock level in the page to match the value on the server by accessing the <code>ProductModel.StockLevel</code> value. We can also update the stock status:</p>
<pre><code>channel.bind("stockUpdated", function(product) {
    $(".product .stock .level").html(product.StockLevel);
    $(".product .stock .status").html(product.StockStatus);
});
</code></pre>
<h2>Trigger stock update events</h2>
<p>As you can see, this is really easy to do. It&#8217;s just as easy to trigger the event on the server too. To do this we&#8217;re going to be using the <a  href="https://github.com/grahamscott/pusherrestdotnet">C# REST API library</a> within our <code>StoreController</code>. You can get the PusherRESTDotNet library from <a  href="https://github.com/grahamscott/pusherrestdotnet">github</a> or <a  href="http://nuget.org/Package/Edit/PusherRESTDotNet/1.0">via NugGet</a>.</p>
<div style="margin:auto;text-align:center;margin-bottom:20px;"><a  href="http://nuget.org/Package/Edit/PusherRESTDotNet/1.0"><img alt="Pusher-rest-library-nuget" src="http://blog.pusher.com/media/2011/06/25/14/08/10/392/pusher-rest-library-nuget.jpg?m=resize&amp;o%5Bgeometry%5D=600x300&amp;s=837c6fbf2f053537" /></a></div>
<p>Once we&#8217;ve added our PusherRESTDotNet reference we can add a few lines of code to our <code>StoreController</code> to instantly push any changes in stock level to all connected web browsers viewing our t-shirt page.</p>
<p>The first thing to do is to create a <code>PusherProvider</code> and pass in our Pusher details. In this example we are storing these details in the ASP.NET MVC3 <code>Web.config</code>.</p>
<h3>Web.config</h3>
<pre><code>&lt;configuration&gt;
  &lt;appSettings&gt;
    &lt;add key="application_id" value="APP_ID" /&gt;
    &lt;add key="application_key" value="APP_KEY" /&gt;
    &lt;add key="application_secret" value="APP_SECRET" /&gt;

    &lt;!-- more settings --&gt;
  &lt;/appSettings&gt;

  &lt;!-- more config --&gt;
&lt;/configuration&gt;
</code></pre>
<h3>StoreController.cs</h3>
<pre><code>public class StoreController : Controller
{
  private IPusherProvider _provider;

  public StoreController()
  {
      string applicationKey = ConfigurationManager.AppSettings["application_key"];
      string applicaitonSecret = ConfigurationManager.AppSettings["application_secret"];
      string applicationId = ConfigurationManager.AppSettings["application_id"];
      _provider = new PusherProvider(applicationId, applicationKey, applicaitonSecret);
  }

  // more code here...
}
</code></pre>
<p>Once we&#8217;ve created our instance of the <code>PusherProvider</code> we can create a <code>PusherObjectRequest</code> to push the <code>ProductModel</code>, with an updated <code>StockLevel</code> following the purchase, to the clients. The serialisation of the model object is handled for us by the PusherRESTDotNet library. The full <code>StoreController.Index</code> HTTP POST handling action looks like this:</p>
<pre><code>[HttpPost]
public ActionResult Index()
{
  bool bought = MvcApplication.ProductRepository.Buy(MvcApplication.BLUE_TSHIRT_ID);
  var model = MvcApplication.ProductRepository.GetProductById(MvcApplication.BLUE_TSHIRT_ID);

  if (bought)
  {
      ViewBag.Info = model.Title + " successfully bought";

      ObjectPusherRequest request = new ObjectPusherRequest("product-" + model.ProductId, "stockUpdated", model);
      _provider.Trigger(request);
  }
  else
  {
      ViewBag.Error = "There was a problem buying " + model.Title;
  }

  return View("Index", model);
}
</code></pre>
<p>Now, if you run your application and open two or more windows, as soon as a user in one window clicks the &#8220;Buy&#8221; button you&#8217;ll see that the stock level value instantly updates in all other windows.</p>
<div style="margin:auto; text-align:center;margin-bottom:20px;"><iframe src="http://www.screenr.com/embed/kfNs" width="600" height="366" frameborder="0"></iframe><br />
<small><em>Note: the video looks a little jittery because it was recorded on a VM running on Mac</em></small></div>
<h2>Next time &#8211; displaying real-time &#8220;Who&#8217;s shopping&#8221; info with Pusher presence</h2>
<p>We now have the stock level indicator changing in real-time. This tells the users that these t-shirts are selling out fast and gives them an added incentive to make that impulse buy. This is a simple yet effective change but there&#8217;s more we can do. What if we also show the user how many other users are viewing that product at the same time so that they know there is competition for the last few t-shirts? We can do that easily using Pusher&#8217;s <a  href="http://pusher.com/docs/presence">presence</a> functionality and I&#8217;ll cover that in my next <strong>Real-Time ASP.NET</strong> blog post which will also go into how to add Pusher <a  href="http://pusher.com/docs/authenticating_users">user authentication</a> to your ASP.NET web application.</p>
<p>In the meantime you can download the source of the <a  href="https://github.com/leggetter/realtime-webstore">Real-Time Web Store from github</a>. The solution contains a project with the basic web store without any real-time Pusher functionality as well as a solution project. Here are some additional things you you might also want to try out:</p>
<ul>
<li>Changing the form submission when the user clicks &#8220;Buy&#8221; so that the <code>POST</code> to the <code>Buy</code> action it is made using a <a  href="http://api.jquery.com/jQuery.ajax/">jQuery ajax call</a></li>
<li>Making the change in stock levels more visually interesting. Try adding an <a  href="http://jqueryui.com/docs/effect/">effect</a> to the number change or providing a <a  href="http://webtoolkit4.me/2009/08/13/jquery-growl-likenotification-systems/">growl-like notification</a></li>
<li>Changing the CSS &#8211; it&#8217;s not my strong point <img src='http://www.leggetter.co.uk/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html' rel='bookmark' title='Adding a real-time &quot;Who&#8217;s shopping?&quot; widget to an ASP.NET Web App'>Adding a real-time &quot;Who&#8217;s shopping?&quot; widget to an ASP.NET Web App</a></li>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
<li><a href='http://www.leggetter.co.uk/2009/11/07/which-rich-internet-application-technology-will-dominate.html' rel='bookmark' title='Which Rich Internet Application Technology will dominate?'>Which Rich Internet Application Technology will dominate?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</title>
		<link>http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html</link>
		<comments>http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html#comments</comments>
		<pubDate>Tue, 28 Jun 2011 22:14:35 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[thoughts]]></category>
		<category><![CDATA[.net magazine]]></category>
		<category><![CDATA[magazine]]></category>
		<category><![CDATA[publication]]></category>
		<category><![CDATA[publications]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=20597</guid>
		<description><![CDATA[<p><a href="http://www.leggetter.co.uk/wp-content/uploads/2011/06/start.png"></a>I <a href="http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html">joined Pusher</a> around over a month ago now and it&#8217;s been a non-stop whirlwind of activity. On my first day I was in Poland at <a href="http://www.leggetter.co.uk/2011/05/24/notes-on-falsy-values.html">Falsy Values</a> for a JavaScript conference and at the same time I was putting together an article for <a href="http://www.netmagazine.com/">.net magazine</a>. The article is now in [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html' rel='bookmark' title='Goodbye Kwwika. Hello Pusher!'>Goodbye Kwwika. Hello Pusher!</a></li>
<li><a href='http://www.leggetter.co.uk/2011/08/25/what-came-before-websockets.html' rel='bookmark' title='What came before WebSockets?'>What came before WebSockets?</a></li>
<li><a href='http://www.leggetter.co.uk/2011/09/07/qa-are-websockets-ready-for-commercial-use.html' rel='bookmark' title='Q&amp;A: Are WebSockets ready for commercial use?'>Q&#038;A: Are WebSockets ready for commercial use?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a  href="http://www.leggetter.co.uk/wp-content/uploads/2011/06/start.png"></a>I <a href="http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html">joined Pusher</a> around over a month ago now and it&#8217;s been a non-stop whirlwind of activity. On my first day I was in Poland at <a  href="http://www.leggetter.co.uk/2011/05/24/notes-on-falsy-values.html">Falsy Values</a> for a JavaScript conference and at the same time I was putting together an article for <a  href="http://www.netmagazine.com/">.net magazine</a>. The article is now in the August edition (issue 217) and it got a massive 5 page spread (must be all the pictures).</p>
<div id="attachment_20598" class="wp-caption aligncenter" style="width: 251px"><a  href="http://www.leggetter.co.uk/wp-content/uploads/2011/06/homepage.png" class="thickbox no_icon" rel="gallery-20597" title=".net magazine issue 227 (August)"><img class="size-medium wp-image-20598" title=".net magazine issue 227 (August)" src="http://www.leggetter.co.uk/wp-content/uploads/2011/06/homepage-241x300.png" alt="" width="241" height="300" /></a><p class="wp-caption-text">.net magazine issue 227 (August)</p></div>
<p>The article covers building a real-time survey using Ruby on Rails and <a  href="http://pusher.com">Pusher</a>. I also wrote about how Pusher can be used to progressively enhance an application in the way that has been touted as a &#8220;best practice&#8221; approach when adding JavaScript to a web application. I won&#8217;t got into any more detail, if you are interested you can <a  href="http://www.netmagazine.com/shop/magazines/august-2011-217">pick up a copy</a> <img src='http://www.leggetter.co.uk/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I bought one.</p>
<p style="text-align: center;"><a  href="http://www.leggetter.co.uk/wp-content/uploads/2011/06/start.png" class="thickbox no_icon" rel="gallery-20597" title="start"><img class="aligncenter" title="start" src="http://www.leggetter.co.uk/wp-content/uploads/2011/06/start.png" alt="" width="617" height="188" /></a></p>
<p>This is a really big achievement for me and for Pusher, so I&#8217;d like to thank the guys at Pusher for taking me on and also for giving me the opportunity to write the article. It showed a lot of confidence in my ability from day one and that means a lot. Maybe it was a test? <img src='http://www.leggetter.co.uk/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<div>
<div id="attachment_20600" class="wp-caption aligncenter" style="width: 704px"><a  href="http://www.leggetter.co.uk/wp-content/uploads/2011/06/end.png" class="thickbox no_icon" rel="gallery-20597" title="end"><img class="size-full wp-image-20600" title="end" src="http://www.leggetter.co.uk/wp-content/uploads/2011/06/end.png" alt="" width="694" height="231" /></a><p class="wp-caption-text">Mugshot</p></div>
<p>I&#8217;ll keep this short as I don&#8217;t want to make it too much of a &#8220;look at me&#8221; post. I just want to post something as a &#8220;record of achievement&#8221; of something I&#8217;m proud of and as a thanks to the guys as Pusher.</p>
</div>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html' rel='bookmark' title='Goodbye Kwwika. Hello Pusher!'>Goodbye Kwwika. Hello Pusher!</a></li>
<li><a href='http://www.leggetter.co.uk/2011/08/25/what-came-before-websockets.html' rel='bookmark' title='What came before WebSockets?'>What came before WebSockets?</a></li>
<li><a href='http://www.leggetter.co.uk/2011/09/07/qa-are-websockets-ready-for-commercial-use.html' rel='bookmark' title='Q&amp;A: Are WebSockets ready for commercial use?'>Q&#038;A: Are WebSockets ready for commercial use?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Collecta Gets Dispensed: Was It Solving a Hard Enough Problem?</title>
		<link>http://www.leggetter.co.uk/2011/06/02/collecta-gets-dispensed-was-it-solving-a-hard-enough-problem.html</link>
		<comments>http://www.leggetter.co.uk/2011/06/02/collecta-gets-dispensed-was-it-solving-a-hard-enough-problem.html#comments</comments>
		<pubDate>Thu, 02 Jun 2011 07:00:47 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[business models]]></category>
		<category><![CDATA[collecta]]></category>
		<category><![CDATA[product development]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time search]]></category>
		<category><![CDATA[real-time web]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[social mention]]></category>
		<category><![CDATA[Topsy]]></category>

		<guid isPermaLink="false">http://blog.programmableweb.com/2011/06/01/collecta-gets-dispensed-were-they-solving-a-hard-enough-problem/</guid>
		<description><![CDATA[<a href="http://www.programmableweb.com/api/collecta"><img src="http://www.programmableweb.com/images/apis/at1703.png" alt="Collecta" class="imgRight" /></a>At the beginning of 2011 we reported that <a href="http://blog.programmableweb.com/2011/01/24/collecta-drops-its-real-time-search-api/">Collect had decided to drop it's API</a> in order to change their offering to something more profitable. But now ReadWriteWeb have reported <a href="http://www.readwriteweb.com/archives/the_lights_go_out_at_collecta_real_time_search.php">the disappointing demise of Collecta</a>. This has the potential of being the first big failure of a well funded real-time web focused company, so questions need to be asked about why this happened and why Collecta weren't successful. Back in January of this year we asked "<a href="http://blog.programmableweb.com/2011/01/25/is-it-finally-the-end-for-real-time-search-engines/">Is It Finally the End for Real-time Search Engines?"</a> and it now looks like that very question is being raised again.
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2008/12/10/problem-solving-lessons-relearnt.html' rel='bookmark' title='Problem solving lessons relearnt'>Problem solving lessons relearnt</a></li>
<li><a href='http://www.leggetter.co.uk/2009/10/23/how-i-approach-problem-solving-in-code.html' rel='bookmark' title='How I approach problem solving in code?'>How I approach problem solving in code?</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/25/is-it-finally-the-end-for-real-time-search-engines.html' rel='bookmark' title='Is It Finally the End for Real-time Search Engines?'>Is It Finally the End for Real-time Search Engines?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a  href="http://www.programmableweb.com/api/collecta"><img src="http://www.programmableweb.com/images/apis/at1703.png" alt="Collecta" class="imgRight" /></a>At the beginning of 2011 we reported that <a  href="http://blog.programmableweb.com/2011/01/24/collecta-drops-its-real-time-search-api/">Collect had decided to drop it&#8217;s API</a> in order to change their offering to something more profitable. But now ReadWriteWeb have reported <a  href="http://www.readwriteweb.com/archives/the_lights_go_out_at_collecta_real_time_search.php">the disappointing demise of Collecta</a>. This has the potential of being the first big failure of a well funded real-time web focused company, so questions need to be asked about why this happened and why Collecta weren&#8217;t successful. Back in January of this year we asked &#8220;<a  href="http://blog.programmableweb.com/2011/01/25/is-it-finally-the-end-for-real-time-search-engines/">Is It Finally the End for Real-time Search Engines?&#8221;</a> and it now looks like that very question is being raised again.</p>
<p>A very important question, that I recently heard from <a  href="http://twitter.com/#!/roanlavery">Roan Laverly</a> of <a  href="http://www.freeagentcentral.com/">FreeAgent</a>: &#8220;Is your product solving a hard enough problem?&#8221; Well, what problems was Collecta solving?</p>
<p><a  href="http://collecta.com"><img style="vertical-align: middle; display: block; margin-left: auto; margin-right: auto;" src="http://blog.programmableweb.com/wp-content/collecta1.png" alt="" width="448" height="335" /></a></p>
<p>The first problem Collecta was solving was search, and the problem with building a search product in general is that the market is massively dominated by Google. Even Microsoft&#8217;s Bing and Yahoo! can&#8217;t really make a significant dent in the search market, so how can anybody compete? Collecta tried to compete by using real-time search results as their unique selling point &#8211; Google now has a real-time search option, and if a topic is trending real-time search results can form part of the general search results too.</p>
<p>Another problem that Collecta was solving was making real-time data accessible. So many companies that have real-time data are now opening up their own APIs and increasing the ease at which anybody can access that data. This means individuals and companies can now got direct to source and build their own search offering, or just extract just the data they need themselves. I&#8217;m quite sure that Collecta has some very clever technology that delivered their best guess (algorithmically computed) search results in real-time. But again, it doesn&#8217;t sound like that was enough.</p>
<p>Creating real-time technology components capable of consuming, processing and distributing large amounts of data was another problem that Collecta had to answer. Initially building the technology capable of doing this was difficult but now, a few years later, real-time technology components are much more widely accessible. So whilst the difficulty level is still high the problem isn&#8217;t as difficult as it once was. This in itself has meant that data companies can build their own APIs.</p>
<p>Then there&#8217;s the problem of creating a compelling application and products. A website showing real-time search results in a intuitive and informative way. Widgets showing search results in an easy to digest and embeddable format. The post on ReadWriteWeb provides a comment by one of their own writers, Jared Smith, on Collecta&#8217;s applications:</p>
<blockquote><p>Collecta&#8217;s emphasis on a search experience that went beyond Twitter into photos and videos made it a great tool to truly watch a story unfold in real time. Their embeddable widget, which I used regularly on ReadWriteWeb&#8217;s event sites, was far more powerful than what Twitter provided and is still unmatched in my mind.</p>
</blockquote>
<p>So, even though they were building a useful products it wasn&#8217;t enough. Did Jared pay for the widget, and if not would he have been willing to? Would enough users have been willing to pay?</p>
<p>The good news out of all of this is that it sounds like the Collecta technology is going to be open sourced. A quote on the ReadWriteWeb post states:</p>
<blockquote><p>Collecta now says it will open source its software and is working with a variety of organizations to do so &#8211; including United Nations crisis relief projects.</p>
</blockquote>
<p>Is the real-time search problem hard enough? We should keep our eyes on <a  href="http://topsy.com/">Topsy</a> and <a  href="http://www.socialmention.com/">Social Mention</a> to see how they get on. What we can be sure of though is that with Collecta open sourcing their technology the real-time search technology question will now be easier than ever to answer.</p>
<p>
Originally written by me and <a  href="http://blog.programmableweb.com/2011/06/02/collecta-gets-dispensed-was-it-solving-a-hard-enough-problem/">posted on Programmable Web</a></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2008/12/10/problem-solving-lessons-relearnt.html' rel='bookmark' title='Problem solving lessons relearnt'>Problem solving lessons relearnt</a></li>
<li><a href='http://www.leggetter.co.uk/2009/10/23/how-i-approach-problem-solving-in-code.html' rel='bookmark' title='How I approach problem solving in code?'>How I approach problem solving in code?</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/25/is-it-finally-the-end-for-real-time-search-engines.html' rel='bookmark' title='Is It Finally the End for Real-time Search Engines?'>Is It Finally the End for Real-time Search Engines?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/06/02/collecta-gets-dispensed-was-it-solving-a-hard-enough-problem.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Goodbye Kwwika. Hello Pusher!</title>
		<link>http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html</link>
		<comments>http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html#comments</comments>
		<pubDate>Sat, 21 May 2011 12:15:17 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[real-time]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=15639</guid>
		<description><![CDATA[<p>If you follow <a href="http://twitter.com/leggetter">me on Twitter</a> or if I&#8217;ve met up with you in the past few weeks you&#8217;ll probably know, or have guessed the news. I&#8217;m leaving Kwwika, and have joined <a href="http://pusher.com/">Pusher</a>. Whilst it&#8217;s disappointing to leave a project that I&#8217;ve spent the last one year and three months on behind, the move to [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
<li><a href='http://www.leggetter.co.uk/2010/05/10/kwwika-silverlight-api-chat-example.html' rel='bookmark' title='Kwwika Silverlight API &#8211; Chat Example'>Kwwika Silverlight API &#8211; Chat Example</a></li>
<li><a href='http://www.leggetter.co.uk/2010/06/19/want-to-try-out-the-kwwika-api-but-dont-want-to-register.html' rel='bookmark' title='Want to try out the Kwwika API but don&#8217;t want to register?'>Want to try out the Kwwika API but don&#8217;t want to register?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>If you follow <a  href="http://twitter.com/leggetter">me on Twitter</a> or if I&#8217;ve met up with you in the past few weeks you&#8217;ll probably know, or have guessed the news. I&#8217;m leaving Kwwika, and have joined <a  href="http://pusher.com/">Pusher</a>. Whilst it&#8217;s disappointing to leave a project that I&#8217;ve spent the last one year and three months on behind, the move to Pusher couldn&#8217;t have happened without it.</p>
<p>My new role as Developer Evangelist at Pusher is the type of role that I&#8217;ve been trying to build for myself for a long time and it&#8217;s fantastic that <a  href="http://twitter.com/maxthelion">Max</a> and <a  href="http://twitter.com/dctanner">Damien</a> at Pusher have given me this opportunity. The days that I&#8217;ve enjoyed most over the past year and a bit have been the days when I&#8217;ve been working with others, interacting online, attending events, writing blog posts to gauge opinion and share ideas, and learning from others. This is exactly what I&#8217;ll be doing in my new job. Awesome!</p>
<div id="attachment_15640" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-15640" title="Me with co-founder of Pusher, Damien Tanner" src="http://www.leggetter.co.uk/wp-content/uploads/2011/05/damien_phil_pusher-300x224.jpg" alt="Phil Leggetter with co-founder of Pusher, Damien Tanner" width="300" height="224" /><p class="wp-caption-text">Me with co-founder of Pusher, Damien Tanner</p></div>
<h3>What is Pusher?</h3>
<p>Pusher is a hosted HTML5 WebSockets service that makes it possible to quickly, easily and securely add real-time functionality to any web, mobile or desktop application (anything connected to the Internet). This sort of thing is ideally suited to collaboration and communication apps, multiplayer games, real-time dashboards, social media integration, real-time messaging and a whole range of applications that have yet to be discovered.</p>
<p>Please drop me an <a  href="mailto:phil@leggetter.co.uk?subject=Goodbye%20Kwwika,%20Hello%20Pusher%21">email</a> or send me a <a  href="http://twitter.com/leggetter">tweet</a> if you have any questions at all.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html' rel='bookmark' title='Recent article in .net magazine: WebSockets &#8211; Code a real-time survey'>Recent article in .net magazine: WebSockets &#8211; Code a real-time survey</a></li>
<li><a href='http://www.leggetter.co.uk/2010/05/10/kwwika-silverlight-api-chat-example.html' rel='bookmark' title='Kwwika Silverlight API &#8211; Chat Example'>Kwwika Silverlight API &#8211; Chat Example</a></li>
<li><a href='http://www.leggetter.co.uk/2010/06/19/want-to-try-out-the-kwwika-api-but-dont-want-to-register.html' rel='bookmark' title='Want to try out the Kwwika API but don&#8217;t want to register?'>Want to try out the Kwwika API but don&#8217;t want to register?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/05/21/goodbye-kwwika-hello-pusher.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Glug, Glug: Guzzle Ayup a Hosted PubSubHubbub Hub Service</title>
		<link>http://www.leggetter.co.uk/2011/05/18/glug-glug-guzzle-ayup-a-hosted-pubsubhubbub-hub-service.html</link>
		<comments>http://www.leggetter.co.uk/2011/05/18/glug-glug-guzzle-ayup-a-hosted-pubsubhubbub-hub-service.html#comments</comments>
		<pubDate>Wed, 18 May 2011 07:00:22 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[Atom]]></category>
		<category><![CDATA[Ayup]]></category>
		<category><![CDATA[Guzzle Ayup]]></category>
		<category><![CDATA[Paris]]></category>
		<category><![CDATA[pubsubhubbub]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time data]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[Redis]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Superfeedr]]></category>

		<guid isPermaLink="false">http://blog.programmableweb.com/?p=19415</guid>
		<description><![CDATA[PubSubHubbub has become the standard protocol for real-time RSS and Atom feed subscription and delivery. But not everybody wants to host their own PubSubHubbub hub in the same way that hardly anybody hosts their own website, and why cloud services in general have become so popular. Guzzle Ayup has entered the market to offer a [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/01/07/real-time-data-delivery-http-streaming-versus-pubsubhubbub.html' rel='bookmark' title='Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub'>Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub</a></li>
<li><a href='http://www.leggetter.co.uk/2010/09/17/xmpp-pubsub-or-pubsubhubbub-for-real-time-server-push.html' rel='bookmark' title='XMPP PubSub or PubSubHubbub for real-time server push?'>XMPP PubSub or PubSubHubbub for real-time server push?</a></li>
<li><a href='http://www.leggetter.co.uk/2010/07/04/basic-authentication-against-the-superfeedr-http-pubsubhubbub-api-using-a-net-httpwebrequest.html' rel='bookmark' title='Basic Authentication against the Superfeedr HTTP PubSubHubbub API using a .NET HttpWebRequest'>Basic Authentication against the Superfeedr HTTP PubSubHubbub API using a .NET HttpWebRequest</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a  href="http://www.programmableweb.com/api/guzzle-ayup"><img src="http://www.programmableweb.com/images/apis/at3641.png" alt="Guzzle Ayup!" class="imgRight" /></a>PubSubHubbub has become the standard protocol for real-time RSS and Atom feed subscription and delivery. But not everybody wants to host their own PubSubHubbub hub in the same way that hardly anybody hosts their own website, and why cloud services in general have become so popular. <a  href="http://ayup.us/">Guzzle Ayup</a> has entered the market to offer a hosted PubSubHubbub hub service.</p>
<p>Since PubSubHubbub has been around for a while it’s relatively easy for a developer to start using a hub such as Guzzle Ayup (Ayup for short). There are a good number of PubSubHubbub <a  href="http://code.google.com/p/pubsubhubbub/wiki/PublisherClients">publisher</a> and <a  href="http://code.google.com/p/pubsubhubbub/wiki/SubscriberClients">subscriber</a> clients that can be used. There is also a reasonable amount of documentation on the subject including the <a  href="http://code.google.com/p/pubsubhubbub/">Google PubSubHubbub home page</a> and <a  href="https://ayup.us/documentation">Ayup’s documentation</a>.</p>
<p>Ayup was created by a web agency based in Paris called <a  href="http://lemonchik.com/">Lemonchik</a> following the requirement to provide notifications to a real-time theme-based news aggregator called <a  href="http://guzzle.it/">Guzzle</a> and for future web and iOS applications that will require real-time notifications. They were so happy with the final implementation that they decided to build a front-end console and offer it as a public service.</p>
<p><img class="aligncenter size-medium wp-image-19418" title="Ayup User Dashboard - Add a feed" src="http://blog.programmableweb.com/wp-content/ayup_dashboard-266x300.png" alt="" width="266" height="300" /></p>
<p>Marca Tatem of Lemonchik (and Guzzle Ayup) explains a bit more about the internals of the the service:</p>
<blockquote><p>The internals of Ayup are fun to look at. It&#8217;s a ruby application with a Sinatra web-service, and everything is happening in high-performance, RAM only, Resque queues (backed with Redis). Ayup structure is in itself completely scalable, adding a server with hundreds of new workers is a matter of minutes.</p>
</blockquote>
<p>Ayup offer a simple pay for what you use pricing policy and allow you to set a notification limit which can be handy in keeping costs down when subscribed feeds update more than expected. They also offer something called Virtual hubs which Marca explains as:</p>
<blockquote><p>Virtual Hubs are PubSubHubbub hubs content publishers can create to push free notifications to subscribers. For example, let&#8217;s say that you want people to be able to receive instant push notifications each time you publish a story, you simply create a virtual hub ([YourHubName].ayup.us) people can subscribe to (with a subscribe request) and notifications will be sent to their http callback for free.</p>
</blockquote>
<p>Marca continues to explain why Virtual Hubs are a good way of encouraging simple and free access to your content:</p>
<blockquote><p>The difference between a virtual hub and the actual ayup&#8217;s hub is that with a virtual hub, you can only send a subscribe request for a topic that belongs to the virtual hub&#8217;s owner. In other words, if you create a virtual hub, I can&#8217;t send a subscribe request for MacRumor&#8217;s RSS feed. If I want to subscribe to many different feeds without limitations, then I&#8217;ll have to create an Ayup account and pay for sent notifications.</p>
</blockquote>
<p>Ayup’s focus for the near future is to keep things simple by delivering a good experience for developers and good quality of service such as fast and constant notifications and clean ATOM.</p>
<p>At the time of writing there are only two hosted PubSubHubbub hub services (<a  href="http://code.google.com/p/pubsubhubbub/wiki/Hubs">Hub implementations and hosted services</a>). The first well-known service <a  href="http://superfeedr.com/">Superfeedr</a> and now there is the welcome addition of a second in <a  href="http://ayup.us/">Guzzle Ayup</a></p>
<p>Originally written by me and <a  href="http://blog.programmableweb.com/2011/05/18/glug-glug-guzzle-ayup-a-hosted-pubsubhubbub-hub-service/">posted on Programmable Web</a></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/01/07/real-time-data-delivery-http-streaming-versus-pubsubhubbub.html' rel='bookmark' title='Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub'>Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub</a></li>
<li><a href='http://www.leggetter.co.uk/2010/09/17/xmpp-pubsub-or-pubsubhubbub-for-real-time-server-push.html' rel='bookmark' title='XMPP PubSub or PubSubHubbub for real-time server push?'>XMPP PubSub or PubSubHubbub for real-time server push?</a></li>
<li><a href='http://www.leggetter.co.uk/2010/07/04/basic-authentication-against-the-superfeedr-http-pubsubhubbub-api-using-a-net-httpwebrequest.html' rel='bookmark' title='Basic Authentication against the Superfeedr HTTP PubSubHubbub API using a .NET HttpWebRequest'>Basic Authentication against the Superfeedr HTTP PubSubHubbub API using a .NET HttpWebRequest</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/05/18/glug-glug-guzzle-ayup-a-hosted-pubsubhubbub-hub-service.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Browse, Build and Share Real-time Streams with DataSift</title>
		<link>http://www.leggetter.co.uk/2011/01/17/browse-build-and-share-real-time-streams-with-datasift.html</link>
		<comments>http://www.leggetter.co.uk/2011/01/17/browse-build-and-share-real-time-streams-with-datasift.html#comments</comments>
		<pubDate>Mon, 17 Jan 2011 08:00:20 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[DataSift]]></category>
		<category><![CDATA[digg]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[google buzz]]></category>
		<category><![CDATA[http streaming]]></category>
		<category><![CDATA[InfoChimps]]></category>
		<category><![CDATA[Klout]]></category>
		<category><![CDATA[myspace]]></category>
		<category><![CDATA[Peer Index]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time data]]></category>
		<category><![CDATA[real-time web]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[Salience]]></category>
		<category><![CDATA[Sentiment]]></category>
		<category><![CDATA[SixApart]]></category>
		<category><![CDATA[TweetMeme]]></category>
		<category><![CDATA[websockets]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.programmableweb.com/?p=17676</guid>
		<description><![CDATA[<a href="http://www.programmableweb.com/api/datasift"><img src="http://www.programmableweb.com/images/apis/at2922.png" alt="DataSift" class="imgRight" /></a>A core feature of the real-time web is the continuously updating real-time streams of information. These streams are commonly generated by social networks and with the continued uptake of social networking the amount of information is only going to increase. This will continue to introduce opportunities for companies to create products and services that extract value from that vast amount of data. Some of the most common services built around these streams include trend and sentiment analysis, data storage, aggregation, sorting, search and filtering. <a href="http://datasift.net/">DataSift</a> is a service that offers a host of exciting features including the ability to let users browse, build and share their own real-time streams using social media data drawn from a host of sources.
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/03/31/who-curates-the-real-time-web.html' rel='bookmark' title='Who Curates the Real-Time Web?'>Who Curates the Real-Time Web?</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/07/real-time-data-delivery-http-streaming-versus-pubsubhubbub.html' rel='bookmark' title='Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub'>Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html' rel='bookmark' title='Why client APIs are an important part of any real-time service'>Why client APIs are an important part of any real-time service</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a  href="http://www.programmableweb.com/api/datasift"><img class="imgRight" src="http://www.programmableweb.com/images/apis/at2922.png" alt="DataSift" /></a>A core feature of the real-time web is the continuously updating real-time streams of information. These streams are commonly generated by social networks and with the continued uptake of social networking the amount of information is only going to increase. This will continue to introduce opportunities for companies to create products and services that extract value from that vast amount of data. Some of the most common services built around these streams include trend and sentiment analysis, data storage, aggregation, sorting, search and filtering. <a  href="http://datasift.net/">DataSift</a> is a service that offers a host of exciting features including the ability to let users browse, build and share their own real-time streams using social media data drawn from a host of sources.</p>
<p>DataSift <a  href="http://techcrunch.com/2010/09/27/tweetmeme-founders-datasift-helps-you-find-a-needle-in-a-tweetstack/">launched</a> its Alpha service at TechCrunch Disrupt in September and describe it as a &#8220;real time social media filtering engine.&#8221; The initial buzz around DataSift was generated when Twitter agreed to give them access to the Twitter firehose, but they now have access to a much wider range of data including the Google Buzz, MySpace, SixApart, WordPress, Facebook and Digg. These sources of data within DataSift, sometimes called input services, are defined as <a  href="http://support.datasift.net/help/kb/fsdl/targets">Targets</a> in the DataSift knowledge base.</p>
<p>Users can use Targets to <a  href="http://support.datasift.net/help/kb/getting-started/creating-your-first-stream">create their own streams</a> from within the My Streams section of the DataSift dashboard using a language called <a  href="http://support.datasift.net/help/kb/fsdl/an-introduction-to-fsdl">FSDL</a> (Filtered Stream Definition Language). The Web editor used to define your streams is pretty simple but it does provide some basic syntax highlighting as well as validating your syntax whenever you save. FSDL also provides access to <a  href="http://support.datasift.net/help/kb/targets/targets-augmentations">augmentation Targets</a> through services such as Salience, TweetMeme, Peer Index, Klout and InfoChimps that allow streams to be augmented with third party data.</p>
<p style="text-align: center;"><img class="aligncenter" style="max-width: 800px;" title="DataSift Stream Edit Definition Page (FSDL)" src="http://www.leggetter.co.uk/wp-content/uploads/2011/01/FSDLEditor.png" alt="" width="602" height="326" /></p>
<p>Once a stream has been defined you can choose to build your feed. At present this takes up to 60 minutes and the dashboard will show you the progress of the build as well as a host of other features including a data preview, a live example of the data, a graph showing matched stream items (iterations per minute) and the history of the feed definition.</p>
<p><strong>Update:</strong> Nick Halstead (CEO of DataSift) has provided a clarification about the stream preview, the live stream feature and also when the stream can be used via the API:</p>
<blockquote><p>The stream ‘preview’ does not need to be built for anything to work, you can define + attach to API immediately (or just hit ‘live’ tab to see live results) – the preview was to allow stream owners to demonstrate what the stream would offer.</p>
</blockquote>
<p>You can see Nick&#8217;s full comment in <a  href="http://blog.programmableweb.com/2011/01/17/browse-build-and-share-real-time-streams-with-datasift/#comment-167921">the comments section</a> below.</p>
<p style="text-align: center;"><a  href="http://www.leggetter.co.uk/wp-content/uploads/2011/01/DataSiftDashBoard.png" class="thickbox no_icon" rel="gallery-5224" title="DataSift Stream Dashboard page"><img class="aligncenter" style="max-width: 800px;" title="DataSift Stream Dashboard page" src="http://www.leggetter.co.uk/wp-content/uploads/2011/01/DataSiftDashBoard.png" alt="" width="592" height="485" /></a></p>
<p>DataSift is encouraging its users to build feeds that are discoverable and accessible to other users, although it does offer a private feed option, by providing a number of options on the stream page including tagging, an area to encourage you to tell others about it on common social networks and a comments area to encourage users to interact and visits to the stream page. Recently added, most commented and top rated streams are also featured on the home section of the DataSift dashboard.</p>
<p style="text-align: center;"><img class="aligncenter" style="max-width: 800px;" title="DataSift Dashboard Homepage" src="http://blog.programmableweb.com/wp-content/DataSiftDashBoardHome.png" alt="" width="596" height="478" /></p>
<p>Once the stream has been built it <a  href="http://blog.datasift.com/2010/12/10/building-on-top-of-other-streams/">can also be used</a> in the definition of another user stream, and it in another stream and so on. DataSift really have exposed a lot of functionality and capabilities within their user dashboard and the <a  href="http://support.datasift.net/help/kb">documentation</a> that they provide is quite thorough and really helps a user get to grips with creating streams reasonably quickly.</p>
<p>All these rich features would be a waste unless there was a way of accessing the data and using it with an application. Unsurprisingly, the <a  href="http://www.programmableweb.com/api/datasift">DataSift API</a> delivers by providing three endpoints, including access to filtered data in a paged manner, HTTP Streaming and an RSS endpoint. It also recently introduced a <a  href="http://support.datasift.net/help/kb/streaming-api/websocket-streaming">WebSockets Streaming API</a>.</p>
<p>Although DataSift is still in Alpha it is offering what seems <a  title="DataSift pricing" href="http://datasift.net/pricing?hash=8ee1d6ba2359b33a8a0427723bfec28f&#038;id=2402">an affordable</a> and very impressive service which should excite any developer interested in real-time technologies and data. The company&#8217;s access to a wide range of data sources, engaging and intuitive user dashboard and range of API endpoints should mean that most developers will have their technology needs met.</p>
<div class="youtube-video" style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.youtube.com/v/X7aiKaCi8O8&amp;feature=youtube_gdata_player" /><param name="wmode" value="transparent" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://www.youtube.com/v/X7aiKaCi8O8&amp;feature=youtube_gdata_player" wmode="transparent"></embed></object></div>
<p>A good starting point to learn about DataSift is an <a  href="http://www.youtube.com/watch?v=X7aiKaCi8O8">interview</a> by Robert Scoble with Nick Halstead, the CEO of DataSift (embedded above). The video is a little old but provides a good overview and an example of creating a stream. If you&#8217;ve any comments or questions about DataSift please leave a comment here. After that you should head over to <a  href="http://datasift.net">http://datasift.net</a> and register for the DataSift Alpha program.</p>
<p>This <a  href="http://blog.programmableweb.com/2011/01/17/browse-build-and-share-real-time-streams-with-datasift/">post</a> was originally written by me for <a  href="http://blog.programmableweb.com">ProgrammableWeb</a></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/03/31/who-curates-the-real-time-web.html' rel='bookmark' title='Who Curates the Real-Time Web?'>Who Curates the Real-Time Web?</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/07/real-time-data-delivery-http-streaming-versus-pubsubhubbub.html' rel='bookmark' title='Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub'>Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html' rel='bookmark' title='Why client APIs are an important part of any real-time service'>Why client APIs are an important part of any real-time service</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/01/17/browse-build-and-share-real-time-streams-with-datasift.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yahoo’s Open Sourced S4 Could be a Real-time Cloud Platform</title>
		<link>http://www.leggetter.co.uk/2010/12/31/yahoo%e2%80%99s-open-sourced-s4-could-be-a-real-time-cloud-platform.html</link>
		<comments>http://www.leggetter.co.uk/2010/12/31/yahoo%e2%80%99s-open-sourced-s4-could-be-a-real-time-cloud-platform.html#comments</comments>
		<pubDate>Fri, 31 Dec 2010 08:00:07 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[MapReduce]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[Yahoo]]></category>

		<guid isPermaLink="false">http://blog.programmableweb.com/?p=16860</guid>
		<description><![CDATA[<img class="imgRight" src="http://blog.programmableweb.com/wp-content/s4.png" alt="Yahoo! S4" width="188" height="30" />In a world where real-time data streams are becoming much more common, and with the volume of that data continuing to increase, it makes sense that a framework would be developed to increase the ease at which that data can be processed. <a href="http://s4.io/">Yahoo! S4</a> isn't the first such framework to be concieved, or even open sourced, but it is likely to massively increase awareness that such frameworks exist, what problems they may help solve and get developers thinking about how they could use the technology and potentially increase the likelihood of somebody moving S4-like capabilities into the cloud and offering it as as service.
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/09/14/client-push-services-open-up-real-time-to-everyone.html' rel='bookmark' title='Client Push Services Open Up Real-Time to Everyone'>Client Push Services Open Up Real-Time to Everyone</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/17/browse-build-and-share-real-time-streams-with-datasift.html' rel='bookmark' title='Browse, Build and Share Real-time Streams with DataSift'>Browse, Build and Share Real-time Streams with DataSift</a></li>
<li><a href='http://www.leggetter.co.uk/2011/03/31/who-curates-the-real-time-web.html' rel='bookmark' title='Who Curates the Real-Time Web?'>Who Curates the Real-Time Web?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="imgRight" src="http://blog.programmableweb.com/wp-content/s4.png" alt="Yahoo! S4" width="188" height="30"/>In a world where real-time data streams are becoming much more common, and with the volume of that data continuing to increase, it makes sense that a framework would be developed to increase the ease at which that data can be processed. <a  href="http://s4.io/">Yahoo! S4</a> isn&#8217;t the first such framework to be concieved, or even open sourced, but it is likely to massively increase awareness that such frameworks exist, what problems they may help solve and get developers thinking about how they could use the technology and potentially increase the likelihood of somebody moving S4-like capabilities into the cloud and offering it as as service.</p>
<p>The requirement for a &#8220;distributed stream computing platform&#8221; came about for Yahoo! in order to be able to process thousands of search queries per second, from potentially millions of users per day,  to facilitate the generation of highly <a  href="http://labs.yahoo.com/node/474">personalized adverts</a> for web search. A new framework was required because Yahoo! felt that <a  href="http://en.wikipedia.org/wiki/MapReduce">MapReduce</a>, which is commonly used to process large datasets in batch jobs, was &#8220;hard to apply to stream computational tasks&#8221;.</p>
<p>Yahoo! describe the S4 framework using a number of terms that have become common place in the world of cloud computing:</p>
<blockquote><p>S4 is a general-purpose, distributed, scalable, partially fault-tolerant, pluggable platform that allows programmers to easily develop applications for processing continuous unbounded streams of data.</p>
</blockquote>
<p>Exactly what Yahoo! S4 is, and what it is capable of, has been <a  href="http://bit.ly/igjbDu">discussed</a> in a number of other places. The most commonly used term by <a  href="http://bit.ly/g2GUVE">comparable frameworks</a> is <em>Complex Event Processing</em> with applications including filtering, correlation and pattern matching. These discussions will no doubt continue but ultimately a framework is something that can be put to multiple uses which is why Yahoo! chose to call it &#8220;general-purpose&#8221;.</p>
<p>Yahoo! have created a <a  href="https://github.com/s4/examples">couple of examples</a> to demonstrate some of the basic capabilities and clarify what S4 can do. One of the examples recieves data from the Twitter real-time <a  href="http://dev.twitter.com/pages/streaming_api_methods#statuses-sample">Garden Hose</a> stream, counts the number of times a hashtag is mentioned and keeps an ordered list of the most commonly mentioned hashtags. Each step of the process is performed in what Yahoo! are calling <a  href="http://wiki.s4.io/Manual/S4Overview#toc6">Processing Elements</a> and it&#8217;s these elements that enforce the separation of each logical step of the process (e.g. recieve update, extract hashtags, count hashtags, order hastag count list)  and allow the execution of the process to take place on a distributed system.</p>
<p>One potential thing holding S4 adoption back is that as yet it&#8217;s not offered as a service. As well as writing their own Processing Elements developers will have to host their own distributed stream computing platform. If S4 proves to be a useful and popular framework then we may start to see <em>hosted</em> distributed stream computing platform services in the same way that we&#8217;ve already seen MapReduce being <a  href="http://aws.amazon.com/elasticmapreduce/">offered as a service</a> by Amazon.</p>
<p>Yahoo! S4 is yet another powerful real-time component now available to the Programmable Web. It opens up a number of possibilities for developers to start building exciting data-centric applications, mashups or hosted services which could integrate with other components such as <a  href="http://www.programmableweb.com/apitag/realtime">real-time APIs</a>, <a  href="http://blog.programmableweb.com/2010/09/14/client-push-services-open-up-real-time-to-everyone/">real-time client push services</a> and <a  href="http://blog.programmableweb.com/?s=%22data%20as%20a%20service%22">DaaS</a> services.</p>
<p><a  href="http://blog.programmableweb.com/2010/12/31/yahoos-open-sourced-s4-could-be-a-real-time-cloud-platform/">Originally posted on Programmable Web</a></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/09/14/client-push-services-open-up-real-time-to-everyone.html' rel='bookmark' title='Client Push Services Open Up Real-Time to Everyone'>Client Push Services Open Up Real-Time to Everyone</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/17/browse-build-and-share-real-time-streams-with-datasift.html' rel='bookmark' title='Browse, Build and Share Real-time Streams with DataSift'>Browse, Build and Share Real-time Streams with DataSift</a></li>
<li><a href='http://www.leggetter.co.uk/2011/03/31/who-curates-the-real-time-web.html' rel='bookmark' title='Who Curates the Real-Time Web?'>Who Curates the Real-Time Web?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2010/12/31/yahoo%e2%80%99s-open-sourced-s4-could-be-a-real-time-cloud-platform.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why client APIs are an important part of any real-time service</title>
		<link>http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html</link>
		<comments>http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html#comments</comments>
		<pubDate>Tue, 21 Dec 2010 17:53:20 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Curation]]></category>
		<category><![CDATA[Data Filtering]]></category>
		<category><![CDATA[DataSift]]></category>
		<category><![CDATA[Kwwika]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time data]]></category>
		<category><![CDATA[real-time push]]></category>
		<category><![CDATA[real-time web]]></category>
		<category><![CDATA[Superfeedr]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=3863</guid>
		<description><![CDATA[<p>I&#8217;ve just been involved in a twitter conversation with <a href="http://twitter.com/#%21/nickhalstead">Nick Halstead</a> of <a href="http://datasift.net">DataSift</a> on Twitter. This all started when I <a href="http://twitter.com/#%21/leggetter/status/17233038429655041">tweeted</a> that I thought <a href="http://kwwika.com">Kwwika</a> would be a great way of distributing data from DataSift to any web-enabled device.</p> <p>The conversation continued:</p> <p></p> <p>The main thing here for me is Nick&#8217;s [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/08/10/kwwika-superfeedr-real-time-demo-available-2.html' rel='bookmark' title='Kwwika-Superfeedr real-time demo available'>Kwwika-Superfeedr real-time demo available</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/08/delivery-as-a-service-and-data-as-a-service-in-2011.html' rel='bookmark' title='Delivery as a Service and Data as a Service in 2011'>Delivery as a Service and Data as a Service in 2011</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/07/real-time-data-delivery-http-streaming-versus-pubsubhubbub.html' rel='bookmark' title='Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub'>Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just been involved in a twitter conversation with <a  href="http://twitter.com/#%21/nickhalstead">Nick Halstead</a> of <a  href="http://datasift.net">DataSift</a> on Twitter. This all started when I <a  href="http://twitter.com/#%21/leggetter/status/17233038429655041">tweeted</a> that I thought <a  href="http://kwwika.com">Kwwika</a> would be a great way of distributing data from DataSift to any web-enabled device.</p>
<p>The conversation continued:</p>
<p><img style="max-width: 800px;" src="http://www.leggetter.co.uk/wp-content/uploads/2010/12/leggetter-nickhalstead-conversation1.png" alt="" /></p>
<p>The main thing here for me is Nick&#8217;s point that &#8220;<strong>you just need a client-side library</strong>&#8220;. This is an assumption that a lot of services make. Services tend to offer one or a number of server APIs; maybe a REST one and now luckily we are seeing a HTTP Streaming and WebSocket support. That service may then release some example code that can be used to call the web service. I see a number of problems with this mainly when it comes to HTTP Streaming and WebSockets.</p>
<ul>
<li><a  href="http://support.datasift.net/help/kb/rest-api/websocket-streaming">DataSift WebSocket Streaming Docs</a></li>
<li><a  href="http://support.datasift.net/help/kb/rest-api/http-streaming-api">DataSift HTTP Streaming Docs</a></li>
</ul>
<p>WebSockets aren&#8217;t as yet supported in enough browsers. Therefore it&#8217;s not viable to purely rely on WebSocket support in any production application. So, you can&#8217;t build a web application unless there is a fallback alternative. HTTP Streaming in a web browser could be a fallback (XmlHttpReqeust, XDomainRequest or Flash connections) if the server provides the necessary <a  href="http://dev.w3.org/2006/waf/access-control/#access-control-allow-origin-response-hea">Access-Control-Allow-Origin</a> response header, the browser is new enough, or if the user has Flash installed the server serves up a crossdomain.xml file and the developer is willing to also write code to deal with all the browser types and technoloy scenarios. Then you need to deal with authentication from a web browser for some services to let you access their HTTP Streaming API. DataSift will class your connection as a 2nd class client if you don&#8217;t authenticate:</p>
<blockquote><p>Authorization is not required on the streaming API. However, should you chose not to authenticate, you may be subject to stricter rate limiting and other disadvantages over an authorized user. Therefore, authorization is strongly recommended</p></blockquote>
<p>What this means is that DataSift as yet don&#8217;t support real-time updates in web browser clients fully.</p>
<p>Then you need to consider other technologies like .NET, Java, C or C++ desktop applications, mobile applications on iPhone, iPad, Windows Mobile 7 or Palm using webOS. Each of these technologies requires a client API.</p>
<ul>
<li><a  href="http://support.datasift.net/help/kb/libraries/api-client-libraries">DataSift API Client Libraries</a></li>
</ul>
<h3>A Scenario</h3>
<p>Say I were building a new service which focused on real-time data and delivery of that data in our custom application to desktop app, mobile apps and web apps. My service is focused on curating real-time data from different sources. My first port of call would be DataSift or Superfeedr (I&#8217;m going to leave Kwwika out of the equation here). I know these guys can deal with large volumes of data and can provide some filtering. Maybe if filtering was absolutely key I would go for DataSift (maybe <a  href="http://twitter.com/#%21/julien51">Julien</a> would tell me off for that).</p>
<p>Now I&#8217;ve made my choice and I&#8217;ve got all the data I want streaming through my chosen service and I start to build my client applications. If I choose to build my web application first I&#8217;m stumped as I&#8217;ve already explained, but let&#8217;s say I want to build a Windows desktop application first. Simple, I use the HttpWebRequest object to create a HTTP Streaming connection to DataSift, follow the connection guidelines that DataSift follow (<a  href="http://dev.twitter.com/pages/streaming_api_concepts#connecting">Twitter&#8217;s HTTP Streaming guidelines</a> including a backing off process and handle reconnection) and I&#8217;ve not got my real-time Windows desktop application.</p>
<p>I now decide to build an iPhone application so that people on the move can access my service. I need to start from scratch by writing iOS (Objective-C) code to connect to DataSift&#8217;s HTTP streaming API, following the back off process and deal with reconnection. Once I&#8217;ve done that I move on to Windows 7 Mobile and I have to do the same again.</p>
<p><img style="max-width: 800px;" src="http://www.leggetter.co.uk/wp-content/uploads/2010/12/DataSift-not-kwwika1.png" alt="" /></p>
<p>You get my point.</p>
<p>Now, once DataSift becomes popular, and it will, there will be loads of open source client APIs to choose from. However, these APIs are likely to have been built by a number of different developers providing different ways of doing the same things. Some might be DataSift specific but hopefully they&#8217;ll be generic HTTP Streaming libraries. At this point building my service applications will become a little easier but, in my opinion, still not as easy as it should be.</p>
<h3>Using Kwwika</h3>
<p>If I were to build this service, and not exclude Kwwika, I would set up all my real-time data streaming through DataSift and write a single library, probably reusing the <a  href="http://wiki.kwwika.com/components/kwwika-tweet-streamer">Kwwika Tweet Streamer</a> code which handles the HTTP Streaming connection and the Twitter connection guidelines, and push the data from DataSift into Kwwika. For each of my client applications I could simply download/use the relevant <a  href="http://wiki.kwwika.com/api">Kwwika API</a> (JavaScript, .NET, Silverlight, Flash, Objective-C, Java, C) to subscribe to the DataSift data on any web-enabled device. And because these APIs are are developed and maintained by Kwwika they are consistent across platforms e.g. if you&#8217;ve used the .NET API you will be familiar with the JavaScript API.</p>
<p><img style="max-width: 800px;" src="http://www.leggetter.co.uk/wp-content/uploads/2010/12/DataSift-just-kwwika.png" alt="" /></p>
<p>My point is that the client APIs are as important as the server APIs. A quality real-time client API adds a lot of value to the service such as handling reconnection, failover, subscription management, connection monitoring, error handling, bi-directional messaing and request batching (not relevant in this scenario). As well as real-time data distrubtion/messaging/client push this is a key part of what Kwwika offers.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/08/10/kwwika-superfeedr-real-time-demo-available-2.html' rel='bookmark' title='Kwwika-Superfeedr real-time demo available'>Kwwika-Superfeedr real-time demo available</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/08/delivery-as-a-service-and-data-as-a-service-in-2011.html' rel='bookmark' title='Delivery as a Service and Data as a Service in 2011'>Delivery as a Service and Data as a Service in 2011</a></li>
<li><a href='http://www.leggetter.co.uk/2011/01/07/real-time-data-delivery-http-streaming-versus-pubsubhubbub.html' rel='bookmark' title='Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub'>Real-time Data Delivery: HTTP Streaming Versus PubSubHubbub</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Client Push Services Open Up Real-Time to Everyone</title>
		<link>http://www.leggetter.co.uk/2010/09/14/client-push-services-open-up-real-time-to-everyone.html</link>
		<comments>http://www.leggetter.co.uk/2010/09/14/client-push-services-open-up-real-time-to-everyone.html#comments</comments>
		<pubDate>Tue, 14 Sep 2010 04:00:58 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[real-time client push]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[SaaS]]></category>
		<category><![CDATA[websockets]]></category>

		<guid isPermaLink="false">http://blog.programmableweb.com/?p=15331</guid>
		<description><![CDATA[<a href="http://www.flickr.com/photos/blakespot/4011035061/"><img src="http://blog.programmableweb.com/wp-content/stopwatch.jpg" alt="Real-time" width="100" height="75" class="imgRight" /></a>The number of services offering <a href="http://www.programmableweb.com/apitag/?q=realtime">real-time APIs</a> is slowly but surely expanding and it looks like we're going to have to add quite a few more. Since the start of the year a new type of service has started to appear--client push services, which help developers include real-time updates in their web apps.
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/12/31/yahoo%e2%80%99s-open-sourced-s4-could-be-a-real-time-cloud-platform.html' rel='bookmark' title='Yahoo’s Open Sourced S4 Could be a Real-time Cloud Platform'>Yahoo’s Open Sourced S4 Could be a Real-time Cloud Platform</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html' rel='bookmark' title='Why client APIs are an important part of any real-time service'>Why client APIs are an important part of any real-time service</a></li>
<li><a href='http://www.leggetter.co.uk/2012/01/24/hosted-realtime-services-making-the-realtime-web-more-accessible.html' rel='bookmark' title='Hosted realtime services &#8211; making the realtime web more accessible'>Hosted realtime services &#8211; making the realtime web more accessible</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a  href="http://www.flickr.com/photos/blakespot/4011035061/"><img src="http://blog.programmableweb.com/wp-content/stopwatch.jpg" alt="Real-time" title="Real-time" width="100" height="75" class="imgRight" /></a>The number of services offering <a  href="http://www.programmableweb.com/apitag/?q=realtime">real-time APIs</a> is slowly but surely expanding and it looks like we&#8217;re going to have to add quite a few more. Since the start of the year a new type of service has started to appear&#8211;client push services, which help developers include real-time updates in their web apps.</p>
<p>Real-time client push APIs have actually been around for quite a while (around 10 years) as they are shipped with <a  href="http://en.wikipedia.org/wiki/Comet_(programming)">Comet servers</a> but only recently have these been moved into the cloud and offered as a service. The service flavour of these APIs give the developer the ability to instantly push information from their web server, through their chosen push service and into a web browser viewing their website.</p>
<p><img src="http://blog.programmableweb.com/wp-content/scrabbly.jpg" alt="Scrabb.ly -- real-time multi-player word game" title="Scrabb.ly -- real-time multi-player word game" width="578" height="342" class="aligncenter size-full wp-image-15374" /></p>
<p>Real-time client push is intended to replace the previous pull, or polling, mechanism that has been used for many years to mimic live data on a website. Using push via a dedicated Comet server is generally more resource efficient than polling a web server, and by using a service the resource load and complexity involved in setting up and running a Comet service is completely taken away from the developer&#8217;s considerations. This means that the web server is under much less strain, the developer can concentrate on building a killer real-time application and the website user gets the benefit of a truly real-time experience.</p>
<p>These services have only recently started to pop up due to a number of technology advancements. To be able to use a real-time client push service the web browser needs to be able to maintain a persistent connection back to the web server so that the web server can push information to it as soon as it becomes available. This has been achievable for a number of years via what some developer have labelled as &#8220;hacks&#8221; but is now easier than it has ever been. Most of the new services use the JavaScript <a  href="http://en.wikipedia.org/wiki/WebSockets">WebSocket</a> object to achieve this and fallback to using Flash if WebSockets are not supported by the browser.</p>
<p>The web browser also needs to be able to maintain a <em>cross domain</em> connection from the JavaScript code running in the website to the service e.g. a connection from blog.programmableweb.com to www.example.com. In older browsers cross domain connections were not allowed but the introduction of client access policy files (<a  href="http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html">crossdomain.xml</a> and <a  href="http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx">clientaccesspolicy.xml</a>) and more recently the <a  href="http://www.w3.org/TR/2008/WD-access-control-20080912/#access-control-allow-origin">Access-Control-Allow-Origin</a> HTTP header have made cross domain calls from JavaScript possible (You can find more information and a demo of this in action <a  href="http://www.leggetter.co.uk/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html">here</a>).</p>
<p>All of the real-time client push services have adopted a data <a  href="http://en.wikipedia.org/wiki/Publish/subscribe">publisher subscriber model</a> with the web server code generally acting as the data publisher and the JavaScript code running in the web browser acting as the data subscriber. Subscriptions are made to a channel (or topic), that either exists or will be created, within the service and are identified by a name e.g. &#8220;my_channel&#8221; or &#8220;/PW/CHAT&#8221;. The publishers then simply publish data to that channel or topic using a service API and the information is instantly received by all subscribers, again via an API.</p>
<p>The real-time client push services that we know of at the moment are:</p>
<ul>
<li><a  href="http://beaconpush.com/">Beacon</a></li>
<li><a  href="http://hookbox.org/">Hookbox</a></li>
<li><a  href="http://kwwika.com/">Kwwika</a> (disclosure: author is a founder)</li>
<li><a  href="http://www.pubnub.com/">PubNub</a></li>
<li><a  href="http://pusherapp.com/">Pusher</a></li>
<li><a  href="http://www.frozenmountain.com/websync/">WebSync</a></li>
</ul>
<p>And some examples of their use include:</p>
<ul>
<li><a  href="http://blog.programmableweb.com/2010/08/26/real-time-news-reader-shows-off-push-to-browser/">A real-time news reader</a></li>
<li><a  href="http://www.pubnub.com/blog/facebook-meh-button">A Facebook &#8220;meh&#8221; button</a></li>
<li><a  href="http://www.startupmonkeys.com/2010/09/building-a-scrabble-mmo-in-48-hours/">Interactive games</a></li>
<li><a  href="http://kwwika.com/Standalone/Demos/ReplayWorldCup2010/">Real-time sports statistics</a> (requires HTML5 support)</li>
</ul>
<p>You can also check out the demos on each of the services websites.</p>
<p><img src="http://blog.programmableweb.com/wp-content/meh-button.jpg" alt="The real-time &#039;meh&#039; button" title="The real-time &#039;meh&#039; button" width="457" height="136" class="aligncenter size-full wp-image-15373" /></p>
<p>Real-time is already a big topic and users are starting to demand data and results as fast as possible. There is also the expectation that they should be informed as soon as new data is available or the existing data changes. Google are already pressing ahead with new real-time advancements such as <a  href="http://www.google.com/realtime">Google Real-Time search</a> (which actually <a  href="http://www.leggetter.co.uk/2010/08/27/google-realtime-search-isnt-real-time.html">uses polling</a>) and <a  href="http://www.google.com/instant/">Google Instant</a> but the good news is that with the availability of real-time client push services any developer can now add real-time to their website.</p>
<p>Let us know if you are interested in finding out more about these real-time client push APIs and services and we&#8217;ll cover each one in more detail.</p>
<p>Photo via <a  href="http://www.blakespot.com/">Blake Patterson</a></p>
<p><a  href="http://blog.programmableweb.com/2010/09/14/client-push-services-open-up-real-time-to-everyone/">Originally posted on Programmable Web</a></p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/12/31/yahoo%e2%80%99s-open-sourced-s4-could-be-a-real-time-cloud-platform.html' rel='bookmark' title='Yahoo’s Open Sourced S4 Could be a Real-time Cloud Platform'>Yahoo’s Open Sourced S4 Could be a Real-time Cloud Platform</a></li>
<li><a href='http://www.leggetter.co.uk/2010/12/21/why-client-apis-are-an-important-part-of-any-real-time-service.html' rel='bookmark' title='Why client APIs are an important part of any real-time service'>Why client APIs are an important part of any real-time service</a></li>
<li><a href='http://www.leggetter.co.uk/2012/01/24/hosted-realtime-services-making-the-realtime-web-more-accessible.html' rel='bookmark' title='Hosted realtime services &#8211; making the realtime web more accessible'>Hosted realtime services &#8211; making the realtime web more accessible</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2010/09/14/client-push-services-open-up-real-time-to-everyone.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced
Database Caching 29/115 queries in 0.096 seconds using disk: basic

Served from: www.leggetter.co.uk @ 2012-02-04 20:31:17 -->
