<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Phil Leggetter - Real-Time Web Software and Technology Evangelist</title>
	
	<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>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PhilLeggettersBlog" /><feedburner:info uri="philleggettersblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Hosted realtime services – making the realtime web more accessible</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/JLiriPS_040/hosted-realtime-services-making-the-realtime-web-more-accessible.html</link>
		<comments>http://www.leggetter.co.uk/2012/01/24/hosted-realtime-services-making-the-realtime-web-more-accessible.html#comments</comments>
		<pubDate>Tue, 24 Jan 2012 09:05:11 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[real-time web]]></category>
		<category><![CDATA[realtime hosted services]]></category>
		<category><![CDATA[self-hosted realtime services]]></category>
		<category><![CDATA[socket.io]]></category>
		<category><![CDATA[websockets]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=22151</guid>
		<description><![CDATA[<p>The real-time web started off by just being &#8220;cool&#8221;; a quirky and fun space to be in with lots of &#8220;cool&#8221; technology. People weren&#8217;t sure whether it was just a fad, stimulated by hype. The value it delivers in the form of customer engagement, interaction, collaboration and the opportunities it can provide by being real-time [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/08/27/google-realtime-search-isnt-real-time.html' rel='bookmark' title='Google realtime search isn&#8217;t real-time'>Google realtime search isn&#8217;t real-time</a></li>
<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/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html' rel='bookmark' title='Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest'>Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The <strong>real-time web</strong> started off by just being &#8220;cool&#8221;; a quirky and fun space to be in with lots of &#8220;cool&#8221; technology. People weren&#8217;t sure whether it was just a fad, stimulated by hype. The value it delivers in the form of customer engagement, interaction, collaboration and the opportunities it can provide by being real-time is now much clearer, and consequently the benefits of using real-time technologies are beginning to be understood.</p>
<h2>Realtime Web Technology Accessibility</h2>
<p>One of the problems with real-time technologies over the past 10+ years has been the accessibility. Comet servers were difficult to install, a pain to maintain and upgrade and generally difficult to use due to numerous configuration options and technology quirks, mainly exposed by different web browsers. There have been a number of very important changes have happened over the past few years that now make real-time technologies much more accessible.</p>
<h3>Web Browser Wars</h3>
<p>For such a long time Internet Explorer 6 was by far the best web browser available. It&#8217;s the reason that Microsoft &#8220;dropped the ball&#8221; and why Firefox and Chrome are where they are today. But now we are in a great position of having a number of actively developed web browsers being driven by real competition to offer the best browsing experience. This has lead to a general improvements in browser speed (JavaScript and rendering engines) but also improvements in web technology available to web browsers and, possibly most important of all, web standardisation. <strong>HTML5 does indeed rock!</strong></p>
<h3>Cloud Hosted Services</h3>
<p>Cloud hosted services, frequently referred to as Infrastructure as a Service (IaaS). These hosted solutions take away the pain of installation, maintenance and scaling, and frequently deliver them at a fraction of the cost possible if you were self-hosting.</p>
<h3>Better self hosted solutions</h3>
<p>Cloud hosted services are awesome (I would say that, but they are!) but the <a  href="http://www.leggetter.co.uk/real-time-web-technologies-guide#self-hosted">self hosted realtime web solutions</a> that are available and the ease of installation has massively improved. As an example, you can have a <a  href="http://socket.io">socket.io</a> example page up and running on node.js within minutes. These improvements have been driven by an increased demand for</p>
<h3>WebSockets</h3>
<p>WebSockets is a standard for continuous bi-directional single-connection communication between client and server. Real-time technologies, and in particular real-time messaging within a web browser, has been possible before but not until WebSockets has there been a standard that is so likely to succeed.</p>
<p>Unfortunately WebSockets don&#8217;t mean that the pain has completely gone away. The technology, whilst more accessible, still isn&#8217;t as easy as it could be for developers to use. On some platforms WebSocket server installation can still take too long, maintenance is just something developers don&#8217;t really want to do, and scaling takes time, effort and lots of configuration. So, we turn to the first important change as a solution to this problem &#8211; hosted realtime services.</p>
<h2>Hosted realtime services</h2>
<p>Hosted realtime services, like <a  href="http://pusher.com">Pusher</a> who I work for, make it much faster and easier for developers to start adding real-time functionality (push notifications, activity streams, realtime chat, collaboration, realtime data visualisations, multiplayer games, 2nd screen/Social TV experiences etc.) to their applications within minutes. For bigger organisations, the same solution also means that you know your developers are busy adding value, not installing, configuring and maintaining. This means they are happy and productive.</p>
<p>The web is only around 20 years old and the real-time web is younger still. We don&#8217;t know exactly where the next few years will take the web but I&#8217;m sure that HTML5, WebSockets and real-time messaging will be a key component, and services like Pusher in a great position to help provide the infrastructure that developers need to easily use these technologies.</p>
<h2>Where next?</h2>
<ul>
<li>If you found this interesting you might find my <a  href="http://www.leggetter.co.uk/real-time-web-technologies-guide">Realtime Web Technology Guide/List</a> of interest. If you know of any technologies that I&#8217;ve missed, please <a  href="/contact-me">get in touch</a>.</li>
<li>Why not take a look at <a  href="http://pusher.com">Pusher</a> and the <a  href="http://blog.pusher.com">Pusher Blog</a></li>
</ul>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/08/27/google-realtime-search-isnt-real-time.html' rel='bookmark' title='Google realtime search isn&#8217;t real-time'>Google realtime search isn&#8217;t real-time</a></li>
<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/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html' rel='bookmark' title='Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest'>Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2012/01/24/hosted-realtime-services-making-the-realtime-web-more-accessible.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2012/01/24/hosted-realtime-services-making-the-realtime-web-more-accessible.html</feedburner:origLink></item>
		<item>
		<title>The Right Place At The Right Time: How The Real-Time Web Influences The “local” World</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/fh_M67bdZPQ/the-right-place-at-the-right-time-how-the-real-time-web-influences-the-local-world.html</link>
		<comments>http://www.leggetter.co.uk/2011/11/09/the-right-place-at-the-right-time-how-the-real-time-web-influences-the-local-world.html#comments</comments>
		<pubDate>Wed, 09 Nov 2011 17:09:37 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[thoughts]]></category>
		<category><![CDATA[Local Social Summit]]></category>
		<category><![CDATA[pusher]]></category>
		<category><![CDATA[Social]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=22012</guid>
		<description><![CDATA[<p>A couple of hours ago I was on a on the &#8216;The Right Place At The Right Time: How The Real-Time Web Influences The &#8220;local&#8221; World&#8217; panel at the <a href="http://www.localsocialsummit.com/">Local Social Summit</a>. The panel was organised and chaired by <a href="http://twitter.com/#!/sebprovencher">Sebastien Provencher</a> and also included <a href="http://twitter.com/#!/ryanmacjones">RyanMacJones</a>, <a href="http://twitter.com/#!/daveambrose">Dave Ambrose</a> and <a href="http://twitter.com/#!/daveambrose">Stefano Diemmi</a>.</p> [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/06/11/kwwika-world-cup-2010-real-time-push-web-app-apple-ipad-competition.html' rel='bookmark' title='Kwwika World Cup 2010 Real-Time Push Web App &#8211; Apple iPad competition'>Kwwika World Cup 2010 Real-Time Push Web App &#8211; Apple iPad competition</a></li>
<li><a href='http://www.leggetter.co.uk/2010/08/27/google-realtime-search-isnt-real-time.html' rel='bookmark' title='Google realtime search isn&#8217;t real-time'>Google realtime search isn&#8217;t real-time</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>A couple of hours ago I was on a on the &#8216;The Right Place At The Right Time: How The Real-Time Web Influences The &#8220;local&#8221; World&#8217; panel at the <a  href="http://www.localsocialsummit.com/">Local Social Summit</a>. The panel was organised and chaired by <a  href="http://twitter.com/#!/sebprovencher">Sebastien Provencher</a> and also included <a  href="http://twitter.com/#!/ryanmacjones">RyanMacJones</a>, <a  href="http://twitter.com/#!/daveambrose">Dave Ambrose</a> and <a  href="http://twitter.com/#!/daveambrose">Stefano Diemmi</a>.</p>
<p>Here&#8217;s the information about the panel and my thoughts on the questions that were asked.</p>
<h2>Description</h2>
<p>The rise of the real-time Web is well documented. Propelled by both the social networking revolution and mobile device ubiquitousness, we&#8217;re seeing the birth of new user services and business opportunities. In this panel,  we will explore the time element in the local/social Web and will try to discover what kind of content works well in real-time, what are the benefits for consumers and what kind of business models can be deployed to leverage the &#8220;time&#8221; dimension.</p>
<h2>Questions</h2>
<h3>Introduce yourself, describe your business</h3>
<p><a  href="http://twitter.com/leggetter">Phil Leggetter</a><br />
Developer Evangelist at <a  href="http://pusher.com">Pusher</a><br />
Pusher is a cloud hosted service and API that makes it really easy to add cool realtime user engaging functionality, like push notifications, activity streams and chat, to any Web, Mobile, Tablet or Desktop application.</p>
<h3>How do you define the real-time Web? What is the importance of the time dimension on the Web today?</h3>
<p>Firstly I think we need to define &#8216;realtime&#8217;. Realtime means that when information is generated following an event of some kind, that information must be available and received in a timely manner so that the context of that information is not lost; so that the information is still relevant and usable.</p>
<p>The realtime web, made popular by Twitter and the instant availability of information, takes this concept of timely information to the web. To me &#8216;the realtime web&#8217; means that instant availability of information but also the instant distribution of that information. It means that those that have registered an interest in a pieces of information will have it pushed to them. It also means we now have the technology available for realtime (timely) bi-directional communication making realtime chat and collaboration using the Internet as the network something that is truly achievable.</p>
<h3>How does the time dimension expresses itself in your business? or in the local/social universe, social media, daily deals, etc. (feel free to comment/provide examples outside of your business as well)</h3>
<p>At a fundamental level Pusher is an Internet realtime messaging service. We aim to keep latency, the time between a message being sent and it being received, as low as possible so it&#8217;s a core part of our service. The value in realtime is the <strong>opportunity</strong> that receiving information as quickly as possible presents.</p>
<p>The technology behind this comes from a trading background where milliseconds can mean getting the best price and can make the difference between getting a great price for a commodity/stock/share or a bad one. This results in potentially millions of pounds.</p>
<p>Realtime in local and social also results in opportunity. The first to hear about and respond to a deal benefits. Those who are aware of the unexpected U2 concert on a near-by roof top have the opportunity to get there in time to see this one-off event. People aware of a terror threat or some other kind of emergency can act accordingly &#8211; either get the hell out of the area or head to it to cover the event or help out. It&#8217;s all about the opportunity that getting timely data presents.</p>
<h3>What kind of content works well in real-time Web? Are there business categories that work better?</h3>
<p>Traditionally realtime web technologies have been used in finance because that&#8217;s where the benefits have been greatest. This means that the content has been pricing information about stocks and shares along with news related to finance.</p>
<p>But with both realtime technology and realtime data much more accessible we are seeing other businesses using and benefiting from it. Sports and betting data is the most obvious second step for this technology. Auctions are a good use and again this is really money driven. Then there&#8217;s business categories where people just want to get the information as soon as possible. News, sport scores, disaster warning systems, disaster relief and short lived deals are examples. Then there&#8217;s information around systems that allow for realtime collaboration; where people are working together to discuss and solve problems. Chat is the first obvious example but synchronised document editing is another more complex, yet highly beneficial one.</p>
<p>Twitter demonstrates a form of chat but it&#8217;s only really good for broadcasting information and for one-to-one chat. If you want a multi-user experience you need to take the conversation away from Twitter. Google hangouts or apps such as <a  href="http://blether.co">!blether</a> and <a  href="http://nurph.com">Nurph</a> are great for that.</p>
<h3>What is the role of “mobile” in this evolution?</h3>
<p>We&#8217;re seeing a lot of notification platforms for mobile, but that means the data is going just one way. In some cases this is all that&#8217;s needed e.g. &#8220;Daily Deal X available at Y&#8221;. But for collaborative applications you need more than just a notification infrastructure. For that we needs better mobile data infrastructure. In London it&#8217;s fine but where I live in Scotland it&#8217;s nearly non-existent. So, mobile and local is going to benefit a lot of people but not everybody. Also, mobile data plans need to be revamped to take into account we are becoming more data, and less voice focused.</p>
<h3>What are the benefits for consumers? emergency/Short-term need vs. long term need. Real-time local news (Japan tsunami, London riots, hashtags, etc.)</h3>
<p>I think we&#8217;ve already covered this. It&#8217;s about the opportunity that getting realtime information brings. To know something is going on and get to or away from somewhere as quickly as possible.</p>
<h3>What are the business models (new or not) that emerge when we add the time dimension? Yield management /last-minute: real or hype? Is this real? Groupon Now disappointing?</h3>
<p>There&#8217;s an excitement generated by having a time constraint. So I think in general we&#8217;ll see some fun ideas come out of this. I&#8217;m particularly excited to see some <strong>2nd Screen</strong> applications that synchronise with live events or scheduled TV programmes. There&#8217;s an opportunity to add a lot more context and fun to TV beyond what we are watching and I&#8217;ve yet to see a really great example. I&#8217;m not a betting guy so I&#8217;ve not tried out <a  href="https://picklive.com/">PickLive</a> but for this interested in Football and Fantasy Football I&#8217;m sure it&#8217;s a great experience. I want to see more in this space.</p>
<p>What&#8217;s the business model? Probably synchronised contextual advertising and also increased user engagement in a programme, and TV figures mean more advertising revenue.</p>
<h3>Are there technologies/technology stacks that are core to real-time? How do we implement real-time technologies?</h3>
<p>Adding realtime functionality to an application is now easier than it&#8217;s ever been. In the past few years the technologies allowing realtime communication have improved and are much more accessible. Scaling and maintain such technology stacks can still be a problem which is one of the features that Pusher offers.</p>
<p>For a true realtime experience the best technology in my opinion is <a  href="http://pusher.com/websockets">WebSockets</a>. They allow for low latency true bi-directional communication over the Internet. There are other HTTP-based techniques but they suffer from the overhead inherent in HTTP such as the additional load of HTTP Headers sent with each HTTP request. Browser techniques which do work have to be implemented in different ways in different web browsers. The standardised approach being taken with WebSockets means that it will become the best way of implementing realtime server to client bi-directional communication.</p>
<p>Technologies worth a mention include:</p>
<ul>
<li><a  href="http://pusher.com">Pusher</a>: a hosted realtime service with APIs that make it really easy to add realtime user engaging functionality to a web, mobile, tablet or desktop app. Have I already said that? <img src='http://www.leggetter.co.uk/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li><a  href="http://code.google.com/p/pubsubhubbub/">PubSubHubbub</a>: provides a way to subscribe to RSS feeds so that new content is instantly pushed to you as soon as it&#8217;s available. It&#8217;s a server to server technology and has been used more recently to let you subscribe to any arbitrary data, not just RSS. <a  href="http://nodejs.org/">Node.js</a> is big in the tech community because JavaScript is generally big on the Web and Node let&#8217;s you code in JavaScript on the server and client.</li>
<li><a  href="http://socket.io">Socket.io</a> is frequently used to add realtime functionality to Node apps.</li>
<li><a  href="https://github.com/socketstream/socketstream">SocketStream</a>: WebSocket-powered web framework dedicated to creating single-page real time websites.</li>
</ul>
<h3>What are the benefits of the real-time Web to local shops/local commerce of real-time Web? location-based, customers on the go.</h3>
<p>The ability to let people know of short term deals or the ability to sell perishable goods at the end of the day that would otherwise be wasted. I&#8217;ve heard of a product called <a  href="http://www.sicamp.org/si-camp-uk/scotland-2011/ideas/foodini/">Foodini</a> that might be doing something in this space. FourSquare check-in can still provide more value to encourage meetups in areas where groups of friends hang out.</p>
<h3>Typically real time does not allow for a lot of context beyond short bits of info. How does context play a deeper role as we move forward in a real time world?</h3>
<p>As I mentioned earlier, context is absolutely key to getting real value from realtime information. Without context the data can be worthless. When something has a time constraint then context has to be present. Applications such as FourSquare add the context which gives it real value. Who has checked-in, where have they checked-in, what type of place have they checked-in to. All this key information let&#8217;s anybody viewing the check-in decide what to do. Tweets normally rely on you knowing a user. If you&#8217;ve missed the start of a conversation thread between two users you follow then, depending on the time constraints, the opportunity could be lost.</p>
<p>Context is essential and as realtime web applications move forward this is most definitely the area where we need to, and will, see improvement.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/06/11/kwwika-world-cup-2010-real-time-push-web-app-apple-ipad-competition.html' rel='bookmark' title='Kwwika World Cup 2010 Real-Time Push Web App &#8211; Apple iPad competition'>Kwwika World Cup 2010 Real-Time Push Web App &#8211; Apple iPad competition</a></li>
<li><a href='http://www.leggetter.co.uk/2010/08/27/google-realtime-search-isnt-real-time.html' rel='bookmark' title='Google realtime search isn&#8217;t real-time'>Google realtime search isn&#8217;t real-time</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/11/09/the-right-place-at-the-right-time-how-the-real-time-web-influences-the-local-world.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/11/09/the-right-place-at-the-right-time-how-the-real-time-web-influences-the-local-world.html</feedburner:origLink></item>
		<item>
		<title>The Zoom! book got me thinking about Kwwika</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/-uokdssMkQg/the-zoom-book-got-me-thinking-about-kwwika.html</link>
		<comments>http://www.leggetter.co.uk/2011/09/21/the-zoom-book-got-me-thinking-about-kwwika.html#comments</comments>
		<pubDate>Wed, 21 Sep 2011 15:50:48 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[thoughts]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[ian sanders]]></category>
		<category><![CDATA[Kwwika]]></category>
		<category><![CDATA[unplan]]></category>
		<category><![CDATA[work/life integration]]></category>
		<category><![CDATA[Working]]></category>
		<category><![CDATA[Zoom Book]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=21797</guid>
		<description><![CDATA[<p>I&#8217;ve just finished reading chapter 2 of <a href="http://www.amazon.co.uk/gp/product/0273755676/ref=as_li_ss_tl?ie=UTF8&#038;tag=philleggsoftc-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0273755676">Zoom! The faster way to make your business idea happen</a> and to use one of <a href="http://scrambledup.blogspot.com/">Ian Sanders</a> favourite words it really &#8220;resonated&#8221; with me and my experiences with <a href="http://kwwika.com/">Kwwika</a>.</p> <a href="http://www.amazon.co.uk/gp/product/0273755676/ref=as_li_ss_il?ie=UTF8&#038;tag=philleggsoftc-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0273755676"></a> <p>Chapter 2 is entitled &#8220;The trouble with too much planning. How to unplan your [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/01/07/marriage-worklife-integration-real-time-web-technology-evangelism-kwwika-a-retrospective-of-my-2010.html' rel='bookmark' title='Marriage, Work/life integration, real-time web technology evangelism &amp; Kwwika: A retrospective of my 2010'>Marriage, Work/life integration, real-time web technology evangelism &#038; Kwwika: A retrospective of my 2010</a></li>
<li><a href='http://www.leggetter.co.uk/2009/08/05/book-review-juggle-rethink-work-reclaim-your-life.html' rel='bookmark' title='Book review: Juggle! Rethink work, reclaim your life'>Book review: Juggle! Rethink work, reclaim your life</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>I&#8217;ve just finished reading chapter 2 of <a  href="http://www.amazon.co.uk/gp/product/0273755676/ref=as_li_ss_tl?ie=UTF8&#038;tag=philleggsoftc-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0273755676">Zoom! The faster way to make your business idea happen</a> and to use one of <a  href="http://scrambledup.blogspot.com/">Ian Sanders</a> favourite words it really &#8220;resonated&#8221; with me and my experiences with <a  href="http://kwwika.com/">Kwwika</a>.</p>
<div style="margin:20px;text-align:centre; float:right;"><a  href="http://www.amazon.co.uk/gp/product/0273755676/ref=as_li_ss_il?ie=UTF8&#038;tag=philleggsoftc-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0273755676"><img border="0" src="http://ws.assoc-amazon.co.uk/widgets/q?_encoding=UTF8&#038;Format=_SL160_&#038;ASIN=0273755676&#038;MarketPlace=GB&#038;ID=AsinImage&#038;WS=1&#038;tag=philleggsoftc-21&#038;ServiceVersion=20070822" ></a><img src="http://www.assoc-amazon.co.uk/e/ir?t=philleggsoftc-21&#038;l=as2&#038;o=2&#038;a=0273755676" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></div>
<p>Chapter 2 is entitled &#8220;The trouble with too much planning. How to unplan your business&#8221;. I&#8217;ve been following Ian for probably around three years now and for around the last two he&#8217;s been talking, <a  href="http://twitter.com/iansanders">tweeting</a>, blogging and vlogging about unplanning your business.</p>
<p>I had tried to unplan Kwwika. The fact that it was a great idea, I had real passion for it and had a lot of potential to be used in many different ways unfortunately wasn&#8217;t enough for everybody involved. There had to be more of a business plan. This meant documents and spreadsheets. These documents and spreadsheets alone didn&#8217;t clearly show a massive turnover. But the spreadsheets were full of best guess estimates and didn&#8217;t take into account all the various possibilities and things that hadn&#8217;t even been thought of yet &#8211; how could they? Kwwika didn&#8217;t need a plan beyond the basics we already had in place. We had enough information to see that it was a great idea and had lots potential. What it needed was more faith, commitment* and belief in the idea.</p>
<p><em>*It would probably be better to say that the commitment needed re-focused since there was plenty of time, effort and money spent on the project.</em></p>
<p>Chapter 2 in Zoom! talks about a business idea needing a &#8216;why&#8217; and a &#8216;who&#8217;. <strong>Why</strong> a business is needed and <strong>Who</strong> will make it happen. The Why for Kwwika has now been justified by services like <a  href="http://pusher.com">Pusher</a>, of which I&#8217;m now part, and the competitors PubNub and Beacon Push. There is absolutely no reason why Kwwika couldn&#8217;t still be running and competing too. The problem lies in the belief in the &#8216;why&#8217; and the restrictive nature of the &#8216;who&#8217;, where a big part of the &#8216;who&#8217; was me.</p>
<p>One of the things that <a  href="http://www.garyvaynerchuk.com">Gary Vaynerchuk</a> talks about quite a bit is the importance of concentrating on what you are good at. If you&#8217;re not good at something, or if you know it could be done better by somebody else, then find that somebody else and get them to do it. This means you can focus on the things you are good at. We didn&#8217;t do this with Kwwika and it was partly my fault. It was my fault because I was on a good salary, knew the project was constantly under review and knew that at the start of 2012 I wanted to buy a home for my family. These all conflicted with how I should have approached Kwwika. My salary shouldn&#8217;t have been a salary at all. It should have been a budget to spend as required in order to give Kwwika a better chance of being successful.</p>
<p>Knowing, or admitting, you are not good at something can be a difficult thing. I&#8217;m actually reasonably open and honest about this. I think I know what my strengths and weaknesses are although I do try to put myself in situations which I&#8217;d say are outside of my comfort zone. One example of this is that I actually really enjoy working with others although I work from home so quite frequently have to work alone. Another is giving talks. Since a kid, and a particularly bad experience trying to give a talk about the football team I was captain of, I&#8217;ve never been too keen on giving talks or presentations. But I&#8217;m now trying to put myself in situations where I have to do this to get over this worry, increase my confidence and to try and improve as a person.</p>
<p>All this feeds in very well to chapter 3 of <a  href="http://www.amazon.co.uk/gp/product/0273755676/ref=as_li_ss_tl?ie=UTF8&#038;tag=philleggsoftc-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0273755676">Zoom!</a>, &#8220;Getting to grips with your mission. Why you need to understand what&#8217;s driving you&#8221;. More to come as I read on.</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2011/01/07/marriage-worklife-integration-real-time-web-technology-evangelism-kwwika-a-retrospective-of-my-2010.html' rel='bookmark' title='Marriage, Work/life integration, real-time web technology evangelism &amp; Kwwika: A retrospective of my 2010'>Marriage, Work/life integration, real-time web technology evangelism &#038; Kwwika: A retrospective of my 2010</a></li>
<li><a href='http://www.leggetter.co.uk/2009/08/05/book-review-juggle-rethink-work-reclaim-your-life.html' rel='bookmark' title='Book review: Juggle! Rethink work, reclaim your life'>Book review: Juggle! Rethink work, reclaim your life</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/09/21/the-zoom-book-got-me-thinking-about-kwwika.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/09/21/the-zoom-book-got-me-thinking-about-kwwika.html</feedburner:origLink></item>
		<item>
		<title>Q&amp;A: Are WebSockets ready for commercial use?</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/OQWmYqVyanU/qa-are-websockets-ready-for-commercial-use.html</link>
		<comments>http://www.leggetter.co.uk/2011/09/07/qa-are-websockets-ready-for-commercial-use.html#comments</comments>
		<pubDate>Wed, 07 Sep 2011 11:48:43 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Q&A]]></category>
		<category><![CDATA[realtime web]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=21772</guid>
		<description><![CDATA[<p>I&#8217;m not answering this question directly in the post. I&#8217;d like people to ask questions and raise concerns in the comments and I&#8217;ll then do my best to answer the questions and alleviate any concerns.</p> <p>I believe that WebSockets are ready for commercial use and I&#8217;ll justify this stance in answering any questions.</p> <p>Look forward [...]
Related posts:<ol>
<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/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>I&#8217;m not answering this question directly in the post. I&#8217;d like people to ask questions and raise concerns in the comments and I&#8217;ll then do my best to answer the questions and alleviate any concerns.</p>
<p>I believe that WebSockets are ready for commercial use and I&#8217;ll justify this stance in answering any questions.</p>
<p>Look forward to hearing your questions and thoughts.</p>
<p><a  href="http://www.leggetter.co.uk/2011/09/07/qa-are-websockets-ready-for-commercial-use.html#disqus_thread">View Q&#038;A/Comments</a></p>
<p>Related posts:<ol>
<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/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/09/07/qa-are-websockets-ready-for-commercial-use.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/09/07/qa-are-websockets-ready-for-commercial-use.html</feedburner:origLink></item>
		<item>
		<title>What came before WebSockets?</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/OYJbcQ5Vmx4/what-came-before-websockets.html</link>
		<comments>http://www.leggetter.co.uk/2011/08/25/what-came-before-websockets.html#comments</comments>
		<pubDate>Thu, 25 Aug 2011 00:00:00 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.pusherapp.com/2011/8/10/what-came-before-websockets</guid>
		<description><![CDATA[With the arrival of WebSockets we finally have a standardised technology for true realtime bi-directional communication between a server and a web browser (or any other client). When we were creating our What are WebSockets?  page we decided to write u...
Related posts:<ol>
<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>
<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>With the arrival of <a  href="http://pusher.com/websockets">WebSockets</a> we finally have a standardised technology for true realtime bi-directional communication between a server and a web browser (or any other client). When we were creating our <a  href="http://pusher.com/websockets">What are WebSockets?</a>  page we decided to write up a history of the technologies that came before and that are in some cases still in use today. How did we (developers) achieve <strong>realtime browser push</strong> before WebSockets and what were the downfalls of those technologies which meant they never really became mainstream? Here&#8217;s that write-up.</p>
<p>The Internet wasn&#8217;t originally built to be all that dynamic. It was conceived to be a collection of HyperText Markup Language (HTML) pages linking to one another to form a conceptual web of information. Over time the static resources increased in number and richer items, such as images, began to be part of the web fabric. Server technologies advanced allowing for dynamic server pages &#8211; pages whose content was generated based a query.</p>
<h3>DHTML</h3>
<p>Soon there was a requirement for the Internet client, the web browser, to be more dynamic, for it to offer a richer experience. This was achieved through browser scripting in the form of VBScript and JavaScript and was known as Dynamic Hyper Text Markup Language (DHTML). Whilst this improved the web browser experience to some degree it still fell short in allowing a true application experience to be built within the web browser &#8211; the web pages still needed to refresh and reload relatively frequently.</p>
<h3>Cross Frame Communication</h3>
<p>As web browsers evolved so did the scripting technologies and the techniques employed when using them. Application-style functionality was achieved within websites though tricks such as cross frame communication.  These techniques allowed new data to be loaded from the server without the page refreshing by a frame loading a new page from the server and in doing so retrieving new information.</p>
<p>Up until this point all actions within a website, web page or web application had consistent of a user action generating a request to a server from the web browser. But what if the web server had some new, additional information for the user?</p>
<h3>HTTP Polling</h3>
<p>The first solution to this problem was for the client to poll the server at regular intervals. This solution was, and still is, inefficient and leads to stale data being displayed in web pages and applications.</p>
<h3>LiveConnect</h3>
<p>The next step in the evolution of the web and web applications was for developers to find a way for the server to push new information to the to the web browser from the server. This was first achieved through the use of Java applets which could create a long-held connection with the server and communicate with JavaScript in the web page through a feature known as <strong><a  href="http://en.wikipedia.org/wiki/LiveConnect">LiveConnect</a></strong>.</p>
<h3>Forever Frame</h3>
<p>The LiveConnect technique was relatively quickly superseded, due to Java Virtual machine inconsistencies, by a native browser technique known as <strong><a  href="http://cometdaily.com/2007/11/05/the-forever-frame-technique/">forever frame</a></strong> where a long-lived HTTP connection is established to the server using a hidden frame. Data, usually &lt;script&gt; blocks, can then be pushed from the server to the client over this connection and incrementally executed by the web browser.</p>
<h3>AJAX</h3>
<p>Then, thanks to Microsoft&#8217;s requirements with their Outlook web application, the <code>XMLHttpRequest</code> object was born introducing at technology that made something we all now know as Asynchronous JavaScript and XML (<a  href="http://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a>) possible. The ability to make a request to the server from JavaScript without the need for any cross frame communication, often referred to as a hack, had been long awaited. Other browser vendors slowly but surely introduced support for the <code>XMLHttpRequest</code> and without it being an official standard it became one.</p>
<h3>HTTP Long-Polling and XHR Streaming</h3>
<p>Additional techniques arrived including <strong>script tag long-polling</strong>, <strong>htmlfile ActiveX Object</strong>, <strong>XHR long-polling</strong>, <strong>XHR multipart-replace</strong> and <strong>XHR Streaming</strong>.</p>
<p>The <strong>long-polling</strong> techniques work by establishing a connection to the server which is held open. When the server has more data for the client it sends that data through and closes the connection. The client then re-establishes the connection and waits for any new data. The main problem with this technique is that during the reconnection process the data on the page could be out of date and inaccurate.</p>
<p><strong>XHR multipart-replace</strong> and <strong>XHR Streaming</strong> are much better HTTP solutions since they maintain a connection between the client and the server. Even so the long-polling solutions were more popular due cross browser inconsistencies with XHR multipart-replace and XHR Streaming. XHR multipart-replace, which was potentially the best solution of all, only works in Gecko-based browsers. XHR Streaming worked in all browsers the <code>responseText</code> of the <code>XMLHttpRequest</code> object would continue to grow until the connection was closed meaning a reconnection had to eventually be forced to clear this buffer.</p>
<h3>Bi-directional Communication (and the two connection limit)</h3>
<p>One of the problems with all of the realtime browser solutions so far was that they all required two HTTP connections. The first HTTP connection is used as the back/data/streaming channel where data is sent from the server to the client. A second connection is required to send commands for things such as logging in, changing subscriptions and publishing events/messages. To begin with this caused quite a few problems due to a two &#8216;same domain&#8217; connection limit enforced by web browsers which could lead to slow loading pages or the connection in a second browser window failing to establish at all. All modern browsers now have a high same domain connection limit which means this is much less of a problem.</p>
<h3>Cross domain support</h3>
<p>For a long time we&#8217;ve been able to embed a <code>script</code> tag on our site from CDNs to save us bandwidth and benefit from browser caching. One big restriction with scripting however is that script running on a web page can only communicate with other scripts executing in the same domain. For example, if a page served from pusher.com contained an <code>iframe</code> serving news.bbc.co.uk then script in these web pages would not be able to communicate with one another, and rightly so. This restriction was also enforced for the <code>XMLHttpRequest</code> object; If script was running in a page on pusher.com the <code>XMLHttpRequest</code> could only be made to a resource on pusher.com. In an age where web services are everywhere and usage of such services are encouraged for things such as mashups then this became quite a big restriction. This additionally meant that anybody trying to develop an application using a realtime push technology had to host their realtime server on the same domain as their website. This meant they <strong>had to</strong> self host. Again, in a time where <strong>cloud hosting</strong>, <strong>cloud services</strong>, <strong>Software as a Service (SaaS)</strong>, <strong>Platform as a Service (PaaS)</strong> and <strong>Infrastructure as a Service (IaaS)</strong> are so popular this was a massive restriction.</p>
<p>The need for this <strong><a  href="http://www.w3.org/TR/cors/">Cross Origin Resource Sharing (CORS)</a></strong> lead to the introduction of the <strong><a  href="http://www.w3.org/TR/cors/#access-control-allow-origin-response-hea">Access-Control-Allow-Origin header</a></strong> which allowed the server to indicate to the browser making the <code>XMLHttpRequest</code> whether that request was actually allowed.</p>
<p>Even with CORS things weren&#8217;t as simple as they should be. The forever frame v XHR long-polling v XHR streaming v XHR multipart-replace decision still needed to be made along with the new additional quirk of Internet Explorer adding its very own object, <code>XDomainRequest</code>, which had to be used for cross domain web requests.</p>
<p>These inconsistencies between web browsers and the multitude of &#8216;realtime browser solutions&#8217; meant that barrier to using realtime push functionality, not to mention bi-directional communication, was still too high.</p>
<p><strong>But now we have <a  href="http://pusher.com/websockets">WebSockets</a></strong>!</p>
<p>Related posts:<ol>
<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>
<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/25/what-came-before-websockets.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/08/25/what-came-before-websockets.html</feedburner:origLink></item>
		<item>
		<title>JavaScript namespace utility</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/Wy-n-YpRZqc/javascript-namespace-utility.html</link>
		<comments>http://www.leggetter.co.uk/2011/08/23/javascript-namespace-utility.html#comments</comments>
		<pubDate>Tue, 23 Aug 2011 16:09:24 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[namespace]]></category>
		<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=21748</guid>
		<description><![CDATA[<p>Over the past 10 or so years I&#8217;ve written a lot of JavaScript. From very early on, at <a href="http://www.caplin.com">Caplin Systems</a>, I had to write things in a way which ensured that code was clear, usable, discoverable, reusable, extensible and can easily built upon. One of the concepts that was used was to put code [...]
Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html' rel='bookmark' title='Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest'>Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest</a></li>
<li><a href='http://www.leggetter.co.uk/2010/03/19/using-fiddler-to-help-develop-cross-domain-capable-javascript-web-applications.html' rel='bookmark' title='Using Fiddler to help develop cross domain capable JavaScript web applications'>Using Fiddler to help develop cross domain capable JavaScript web applications</a></li>
<li><a href='http://www.leggetter.co.uk/2005/06/30/a-career-using-javascript.html' rel='bookmark' title='A Career Using JavaScript'>A Career Using JavaScript</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Over the past 10 or so years I&#8217;ve written a lot of JavaScript. From very early on, at <a  href="http://www.caplin.com">Caplin Systems</a>, I had to write things in a way which ensured that code was clear, usable, discoverable, reusable, extensible and can easily built upon. One of the concepts that was used was to put code within a namespace. This ensured that you couldn&#8217;t accidentally override a function in the global <code>window</code> namespace and also meant that the namespace would describe the sort of functionality contained within. I&#8217;ve continued to use this concept in various forms but just realised that I&#8217;ve never actually shared how I do this. So here goes.</p>
<p>It&#8217;s actually really simple. I&#8217;ve got two functions that I use, and I&#8217;ve recently ported over to the <code>com.pusher</code> namespace since I&#8217;m creating demos for my work (and play). The first creates some default namespace objects and then defines a <code>namespace</code> function that can be used from then on to create any other namespace objects.</p>
<pre><code>/**
 * @namespace
 * Top-level namespace to stop namespace clutter.
 */
if(!window["com"]) {
  window["com"] = {};
}

// create pusher ns
if(!com.pusher) {
  com.pusher = {};
}

/**
 * Ensures that a namespace exists.
 * @param {String} namespace The namespace to check for and create if required.
 *
 * @return {Object} The existing or new namespace.
 */
com.pusher.namespace = function(namespace) {
  var parts = namespace.split(".");
  var context = window;
  var nsPath = "";
  for(var i = 0, l = parts.length; i &lt; l; ++i) {
    var name = parts[i];
    if(!context[name]) {
      context[name] = {};
      context[name].__namespace = name;
    }
    nsPath += name + ".";
    context = context[name];
    if(!context.__namespace) {
      context.__namespace = nsPath.substring(0, nsPath.length-1); // trim off '.'
    }
  }
  return context;
};
</code></pre>
<p>A quick example of this might be:</p>
<pre><code>com.pusher.namespace("my.new.namespace");

my.new.namespace.SomeClass = function() {
};
/* define methods etc. */
</code></pre>
<p>Then you can access the class anywhere using:</p>
<pre><code>var instance = new my.new.namespace.SomeClass();
</code></pre>
<p>The second function that I&#8217;ve only just started to use takes a leaf from <strong>node.js</strong>. It in that it passes in an <code>exports</code> variable which represents the newly created namespace and then you can add items to that namespace.</p>
<p><em>Note: I&#8217;d previously called the <code>exports</code> variable called <code>export</code> but it would appear this is a reserved word in Safari &amp; Firefox</em></p>
<pre><code>com.pusher.define = function(namespace, definition) {
  var exports = {};
  definition(exports);

  var nsObject = com.pusher.namespace(namespace);
  for(var thingToexports in exports) {
    nsObject[thingToexports] = exports[thingToexports];
  }
};
</code></pre>
<p>You&#8217;ll noticed that it uses the <code>com.pusher.namespace</code> function to create the namespace object. The usage of this is then as follows:</p>
<pre><code>com.pusher.namespace("my.new.namespace", function(exports) {

  var SomeClass = function() {
  };
  /* define methods etc. */

  exports.SomeClass = SomeClass;
});
</code></pre>
<p>The class can then be accessed in the same way as shown previously:</p>
<pre><code>var instance = new my.new.namespace.SomeClass();
</code></pre>
<p>I like this last way of doing things as you declare the namespace at the top and wrap everything in a function. You then can pick what you want to expose to the outside world by just adding it to the <code>exports</code> variable.</p>
<p>I&#8217;d be interested to hear what you think about this approach. Do you have a better one?</p>
<p>Related posts:<ol>
<li><a href='http://www.leggetter.co.uk/2010/03/12/making-cross-domain-javascript-requests-using-xmlhttprequest-or-xdomainrequest.html' rel='bookmark' title='Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest'>Making cross domain JavaScript requests using XMLHttpRequest or XDomainRequest</a></li>
<li><a href='http://www.leggetter.co.uk/2010/03/19/using-fiddler-to-help-develop-cross-domain-capable-javascript-web-applications.html' rel='bookmark' title='Using Fiddler to help develop cross domain capable JavaScript web applications'>Using Fiddler to help develop cross domain capable JavaScript web applications</a></li>
<li><a href='http://www.leggetter.co.uk/2005/06/30/a-career-using-javascript.html' rel='bookmark' title='A Career Using JavaScript'>A Career Using JavaScript</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/08/23/javascript-namespace-utility.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/08/23/javascript-namespace-utility.html</feedburner:origLink></item>
		<item>
		<title>It makes me mad!</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/xQMW22gzNMI/it-makes-me-mad.html</link>
		<comments>http://www.leggetter.co.uk/2011/08/18/it-makes-me-mad.html#comments</comments>
		<pubDate>Thu, 18 Aug 2011 09:57:44 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[thoughts]]></category>
		<category><![CDATA[Care]]></category>
		<category><![CDATA[Customer Service]]></category>
		<category><![CDATA[Fairness]]></category>
		<category><![CDATA[Thought]]></category>
		<category><![CDATA[Thoughtfulness]]></category>

		<guid isPermaLink="false">http://www.leggetter.co.uk/?p=21736</guid>
		<description><![CDATA[<p>I value honesty, fairness and thoughtfulness above many other things. And I believe that the way I conduct myself reflects these values. I don&#8217;t do this through any real thought process. It&#8217;s driven by a physical feeling. It&#8217;s difficult to explain, but I feel it in my chest. When I feel I&#8217;ve been treated unfairly [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>I value honesty, fairness and thoughtfulness above many other things. And I believe that the way I conduct myself reflects these values. I don&#8217;t do this through any real thought process. It&#8217;s driven by a physical feeling. It&#8217;s difficult to explain, but I feel it in my chest. When I feel I&#8217;ve been treated unfairly I just have a sensation of unfairness, lack of care and thought. When I see others treated unfairly I have the same feeling. It annoys me, it makes me mad, and it adds to my drive to make sure that I am fair, honest and thoughtful. I want to treat others how I want to be treated.</p>
<div id="attachment_21743" class="wp-caption alignright" style="width: 423px"><img class="size-full wp-image-21743 " title="It makes me mad!" src="http://www.leggetter.co.uk/wp-content/uploads/2011/08/Screen-shot-2011-08-18-at-12.17.01.png" alt="It makes me mad!" width="413" height="247" /><p class="wp-caption-text">It makes me mad!</p></div>
<p>Annoyance is a negative emotion and I&#8217;d like to be a bit more laid back. But unfortunately the phrase &#8220;it&#8217;s like water off a duck&#8217;s back&#8221; doesn&#8217;t apply to me. When I&#8217;m annoyed I look at the thing that&#8217;s caused the combination of feelings and emotions and analyse what could have been done better and what should have been done with fairness in mind. It&#8217;s really this that drives my philosophy and passion in customer service.</p>
<p>This might sound like a simple philosophy, and fundamentally it is, but it&#8217;s actually really difficult. I want to be 100% open and honest but whilst honesty is absolutely possible there are some pieces of information you can&#8217;t divulge due to contracts, business considerations or simply setting expectations that might not be met. I want to try to correctly set expectations based on the information that I have but there are external factors that can end up impacting the things I&#8217;ve set expectations on. This can lead to letting people down. This can be as easy as saying &#8220;I&#8217;ll get back to you tomorrow morning&#8221; and then other things become a bigger priority and I don&#8217;t get back to somebody until the afternoon or the next day. I feel really bad about this so what are the alternatives?</p>
<p>One is to manage these expectations without committing. This means using words such as &#8220;maybe&#8221;, &#8220;possibly&#8221; and &#8220;probably&#8221;. Whilst this resolves the issue of guaranteeing that something will be delivered, or that you&#8217;ll get back to somebody by a certain time, it also has a negative feeling about it. By not committing you never guarantee anything so what&#8217;s the point? This approach annoys me, so isn&#8217;t an option.</p>
<p>Ultimately it comes down to setting rock solid expectations and communication.</p>
<p>To set solid expectations this you need as much data as possible to be able to make the right decision. You also need experience to be able to foresee problems or things that might impact estimates. You need to be able to know how much of a buffer to add on to projected delivery dates in order to let others know when they really should expect something.</p>
<p>Communication is actually really easy. We have so many communication tools at our disposal; email, Twitter, blogs, instant messenger and many more. With these there&#8217;s not reason why we can&#8217;t keep others informed of progress or even simply let them know that they&#8217;ve not been forgotten and that their problem or query will be dealt with. Sometimes this is enough.</p>
<p>I don&#8217;t believe a formulae can&#8217;t be applied here, there are too many factors. It requires experience, common sense a sense of what is right and the authority to be able to make a decision.</p>
<p>In taking on the Developer Evangelist job at <a  href="http://pusher.com">Pusher</a> I&#8217;ve also asked to take on the majority of the support. This is sometimes seen as a burden but I think it&#8217;s a great opportunity to exercise some of my ideas and philosophy as well as to get to know the people using our service. It&#8217;s also a great way of learning how best to set expectations. And it is a learning process and I don&#8217;t expect to get things right 100% of the time. But I do guarantee that I&#8217;ll always be putting myself in the shoes of those making the support request and that I&#8217;ll do everything I can to make sure their questions are answered to the best of my ability and that their expectations are met.</p>
<h4>Side note:</h4>
<p>Ironically, I&#8217;m sitting on the train next to a young girl who has booked travel using her company credit card. The ticket she&#8217;s booked means she needs to bring this credit card with her. After she had booked the ticket she noticed this term so treble-checked with <a  href="http://www.eastcoast.co.uk">East Coast</a> who told her it would be fine as long as she had ID with her. She had her driving licence with her but was told by the conductor that this wasn&#8217;t acceptable and was asked to pay for a new ticket. I piped up and said this wasn&#8217;t fair and couldn&#8217;t the conductor apply some common sense. No. If it were me I&#8217;d have made the common sense decision to ignore this missed rule and taken into account that the girl had actually checked this with East Coast and been mis-informed. The conductor didn&#8217;t have this authority, nor it seemed really cared &#8211; maybe she deals with &#8220;chancers&#8221; all the time. What the young girl, who clearly isn&#8217;t lying, has been able to do is provide here contact information so that she doesn&#8217;t have to pay now and can appeal against the penalty later by post.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.leggetter.co.uk/2011/08/18/it-makes-me-mad.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/08/18/it-makes-me-mad.html</feedburner:origLink></item>
		<item>
		<title>Adding a real-time "Who’s shopping?" widget to an ASP.NET Web App</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/kGmxNn-G6wg/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>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/08/04/adding-a-real-time-whos-shopping-widget-to-an-asp-net-web-app.html</feedburner:origLink></item>
		<item>
		<title>The easiest way to add real-time functionality to an ASP.NET e-commerce application</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/0IOHxAVcqGI/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>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/07/05/the-easiest-way-to-add-real-time-functionality-to-an-asp-net-e-commerce-application.html</feedburner:origLink></item>
		<item>
		<title>Recent article in .net magazine: WebSockets – Code a real-time survey</title>
		<link>http://feedproxy.google.com/~r/PhilLeggettersBlog/~3/7lXQGINuqI0/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>
		<feedburner:origLink>http://www.leggetter.co.uk/2011/06/28/recent-article-in-net-magazine-websockets-code-a-real-time-survey.html</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced (Requested URI contains query)

Served from: www.leggetter.co.uk @ 2012-02-01 19:28:52 -->

