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

<channel>
	<title>Christophe Coenraets &#187; Socket.IO</title>
	<atom:link href="http://coenraets.org/blog/category/socket-io/feed/" rel="self" type="application/rss+xml" />
	<link>http://coenraets.org/blog</link>
	<description>Web Platform, Cloud and Mobile Application Development</description>
	<lastBuildDate>Mon, 13 May 2013 16:05:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Real Time Web Analytics with Node.js and Socket.IO</title>
		<link>http://coenraets.org/blog/2012/10/real-time-web-analytics-with-node-js-and-socket-io/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=real-time-web-analytics-with-node-js-and-socket-io</link>
		<comments>http://coenraets.org/blog/2012/10/real-time-web-analytics-with-node-js-and-socket-io/#comments</comments>
		<pubDate>Wed, 10 Oct 2012 16:20:53 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Socket.IO]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=4236</guid>
		<description><![CDATA[I&#8217;ve always enjoyed building real-time applications. A few years ago, I built the Java back-end for the Tour of California &#8220;Tour Tracker&#8221;, and over the years, I have also been involved in several real-time Trader Desktop projects that I documented in this blog. So I thought it would be nice to explore the process of [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/10/socketioanalytics.gif"><img src="http://coenraets.org/blog/wp-content/uploads/2012/10/socketioanalytics.gif" alt="" title="socketioanalytics" width="640" height="520" class="aligncenter size-full wp-image-4430" /></a></p>
<p>I&#8217;ve always enjoyed building real-time applications. A few years ago, I built the <a href="http://coenraets.org/blog/2007/02/building-the-back-end-of-the-tour-of-california-tour-tracker-using-flex-data-services/">Java back-end</a> for the Tour of California &#8220;Tour Tracker&#8221;, and over the years, I have also been involved in several real-time Trader Desktop projects that I documented in this blog. So I thought it would be nice to explore the process of building a real-time application with Node.js and Socket.IO.</p>
<p>As an example, we&#8217;ll build a simple web analytics dashboard that shows pages being accessed on a web site in real-time. Kind of like the <a href="http://analytics.blogspot.com/2011/09/whats-happening-on-your-site-right-now.html">real-time view</a> in Google Analytics.</p>
<p>The basic flow of the app is as follows:</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/10/socketiodiagram.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2012/10/socketiodiagram.jpg" alt="" title="socketiodiagram" width="428" height="290" class="aligncenter size-full wp-image-4293" /></a><br />
<span id="more-4236"></span></p>
<ol>
<li>The instrumented web application sends a message to the server every time there is a page change within the app.</li>
<li>Upon reception, the server processes the message and&#8230;</li>
<li>&#8230; pushes it to the clients who listen for &#8220;pageview&#8221; messages.</li>
</ol>
<p><br/></p>
<h3>Testing the Hosted Version of the Application</h3>
<p>A live version of the application is hosted on <a href="http://www.heroku.com/">Heroku</a>. </p>
<ol>
<li>Open a browser and access <a href="http://nodecellar.coenraets.org/dashboard.html">http://nodecellar.coenraets.org/dashboard.html</a></li>
<li>Open a different browser window and start the main Node Cellar application: <a href="http://nodecellar.coenraets.org">http://nodecellar.coenraets.org</a></li>
<li>Navigate through the application: the dashboard should display each page view.</li>
</ol>
<p>In the remaining of this article we will go through the steps of building the application from scratch.</p>
<h3>First Iteration: Basic Implementation</h3>
<p>Node.js and Socket.IO make it easy to implement this type of real-time messaging system. Here is a simple (yet fully functional) implementation of the application:</p>
<h4>The Server</h4>
<p><script src="https://gist.github.com/3859582.js?file=server.js"></script><br />
In this first implementation, Node.js doesn&#8217;t serve the application&#8217;s HTML pages. Pages loaded from any domain (or even from the file system) can connect to our message server to send or listen to &#8220;pageview&#8221; messages.</p>
<h4>The Instrumented Web App</h4>
<p>Here is an example of an instrumented page with a script that sends a message to the server every time the page is loaded.<br />
<script src="https://gist.github.com/3859582.js?file=simplepage.html"></script></p>
<p>As mentioned above, this page can be loaded from any domain or from the file system.</p>
<h4>The Real Time Dashboard</h4>
<p>Here is a bare-bones implementation of the real-time dashboard application that receives &#8220;pageview&#8221; messages from the server.<br />
<script src="https://gist.github.com/3859582.js?file=dashboard.html"></script></p>
<p>That&#8217;s basically all you need to start building a sophisticated user interface with real-time charts, counters, maps, etc.</p>
<h4>Testing the Application</h4>
<ol>
<li>Make sure you have Node.js and Socket.IO installed</li>
<li>Start the Node.js server
<p class="shell">node server</p>
</li>
<li>Double-click dashboard.html in Finder (Mac) or Explorer (Windows) to open the page in your default browser.</li>
<li>Double-click simplepage.html in Finder or Explorer to open the page in your default browser (in a separate window).
<li>Refresh simplepage.html repeatedly: the dashboard should display each page view.</li>
</ol>
<p><br/></p>
<h3>Second Iteration: Adding Authorization</h3>
<p>The solution described above works fine, but there are some potential security issues we need to address: </p>
<ol>
<li>Any application (from any domain) can send a message to our server.</li>
<li>Any application (from any domain) can listen to the messages pushed by our server.</li>
</ol>
<p>Let&#8217;s refine our solution to make sure that only authorized clients can connect to our server. Socket.IO provides two different authorization methods: global authorization and namespace authorization (<a href="https://github.com/LearnBoost/socket.io/wiki/Authorizing">more info</a>). In both cases, the <em>handshakeData</em> object provides information (headers, IP address, xdomain, etc) that is useful to implement your authorization logic and determine whether or not you want to allow the client to connect. In this application, we will use global authorization and reject all the cross-domain connection attempts:<br />
<script src="https://gist.github.com/3859430.js?file=authorization.js"></script></p>
<p>There are many other ways you can secure your connections, but that discussion is beyond the scope of this article. </p>
<p>Rejecting cross-domain connections means that the application pages now also have to be served by the Node.js server. To put our new authorization policy into practice, let&#8217;s add the real-time web analytics capability to the Node Cellar application that I shared in my <a href="http://coenraets.org/blog/2012/10/nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb/">previous post</a>. </p>
<h4>The Server</h4>
<p>The server now serves the HTML pages and hosts Socket.IO.<br />
<script src="https://gist.github.com/3859656.js?file=server.js"></script></p>
<h4>The Instrumented Web App</h4>
<p>The following script has been added to index.html to send a &#8220;pageview&#8221; message to the server every time the page changes.<br />
<script src="https://gist.github.com/3859656.js?file=index.html"></script><br />
Notes:</p>
<ul>
<li>We actually don&#8217;t need to use Socket.IO for this part of the application. The client sends a &#8220;pageview&#8221; message to the server and doesn&#8217;t listen for messages from the server. In other words, this is a traditional client-to-server one-way communication that could be implemented with a traditional Ajax request.</li>
<li>The <em>onhashchange</em> event is used because Node Cellar is a &#8220;Single Page Application&#8221;. The entire application runs within a single page (index.html): views are created dynamically at the client-side and injected into or removed from the DOM as you navigate through the application. Only the hash part of the URL changes (without a page refresh) to reflect the current state of the application.</li>
</ul>
<h4>The Real Time Dashboard</h4>
<p>The final version of the dashboard is shown in the screenshot at the top of this post. The Socket.IO code didn&#8217;t change much since our initial implementation. The final code for dashboard.html is available <a href="https://github.com/ccoenraets/nodecellar/blob/master/public/dashboard.html">here</a>.</p>
<h4>Testing the Application</h4>
<ol>
<li>Make sure you have Node.js and Socket.IO installed</li>
<li>Download the source code</li>
<li>Uncomment the Socket.IO related script in the head of public/index.html</li>
<li>Start the Node.js server
<p class="shell">node serverwithanalytics</p>
</li>
<li>Open a browser and access <a href="http://localhost:3000/dashboard.html">http://localhost:3000/dashboard.html</a></li>
<li>Open a different browser window and start the main Node Cellar application : <a href="http://localhost:3000">http://localhost:3000</a></li>
<li>Navigate through the application: the dashboard should display each page view.</li>
</ol>
<h3>Source Code</h3>
<p>I added the real-time analytics feature to the existing <a href="https://github.com/ccoenraets/nodecellar">nodecellar repository</a>. </p>
<ul>
<li>To start the regular server (without analytics), use:
<p class="shell">node server</p>
</li>
<li>To start the server with analytics, uncomment the Socket.IO related script in the head of public/index.html, and use:
<p class="shell">node serverwithanalytics</p>
</li>
</ul>
<h3>Disclaimer</h3>
<p>This is a sample application, not a production application. Some trade-offs were made to keep the code generic, simple and readable.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/10/real-time-web-analytics-with-node-js-and-socket-io/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
