Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

1558 lines (1445 sloc) 89.279 kb
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Why Know Node?</title>
<meta name="description" content="">
<meta name="author" content="">
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- Le styles -->
<link href="css/bootstrap.css" rel="stylesheet">
<link href="css/docs.css" rel="stylesheet">
<link href="js/libs/google-code-prettify/prettify.css" rel="stylesheet">
<!-- Le fav and touch icons -->
<link rel="shortcut icon" type="image/x-icon" href="ico/favicon.ico">
<link rel="apple-touch-icon" href="ico/bootstrap-apple-57x57.png">
<link rel="apple-touch-icon" sizes="72x72" href="ico/bootstrap-apple-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="assets/ico/bootstrap-apple-114x114.png">
</head>
<body>
<!-- Slide Catalog
Slide 1 - Agenda
Slide 2 - Get Node
Slide 3 - Ok, So What is it?
Slide 4 - Do something! Say Hello World
Slide 5 - kNOw thy REPL
Slide 6 - Start me up (a web server)
Slide 7 - Creating a REST-ful JSON service
Slide 8 - Templating (like a rock star)
Slide 9 - Let's build a Chat Server :)
Slide 10 - What is this require?
Slide 11 - Event Emitters and you
Slide 12 - Data Persistence - Simple, Fast (but lossy), or Reliable
Slide 13 - Testing It
Slide 14 - Performance &amp; Scaling
Slide 15 - Debugging
Slide 16 - Required Reading
Slide 17 - Attributions
-->
<!-- Port Directory
MYSERVERIP =
WEBREPLPORT = 9001
NIDEPORT = 9002
-->
<!-- Topbar
================================================== -->
<div class="topbar" data-scrollspy="scrollspy" >
<div class="topbar-inner">
<div class="container">
<a class="brand" href="#">Why Know Node.js?</a>
<ul class="nav">
<li class="active"><a href="#intro">Intro</a></li>
<li><a href="#1">Slide 1</a></li>
<li><a href="#2">Slide 2</a></li>
<li><a href="#3">Slide 3</a></li>
<li><a href="#4">Slide 4</a></li>
<li><a href="#5">Slide 5</a></li>
<li class="dropdown" data-dropdown="dropdown">
<a href="#" class="dropdown-toggle">Slide 6</a>
<ul class="dropdown-menu">
<li><a href="#6.1">Example 1</a></li>
<li><a href="#6.2">Example 2</a></li>
<li><a href="#6.3">Example 3</a></li>
</ul>
</li>
<li><a href="#7">Slide 7</a></li>
<li><a href="#8">Slide 8</a></li>
<li class="dropdown" data-dropdown="dropdown">
<a href="#" class="dropdown-toggle">Slide 9</a>
<ul class="dropdown-menu">
<li><a href="#9.1">Example 1</a></li>
<li><a href="#9.2">Example 2</a></li>
<li><a href="#9.3">Example 3</a></li>
</ul>
</li>
<li class="dropdown" data-dropdown="dropdown">
<a href="#" class="dropdown-toggle">More ...</a>
<ul class="dropdown-menu">
<li><a href="#10">Slide 10</a></li>
<li><a href="#11">Slide 11</a></li>
<li><a href="#12">Slide 12</a></li>
<li><a href="#13">Slide 13</a></li>
<li><a href="#14">Slide 14</a></li>
<li><a href="#15">Slide 15</a></li>
<li class="divider"></li>
<li><a href="#16">Slide 16</a></li>
<li><a href="#17">Slide 17</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<!-- Masthead (blueprinty thing)
================================================== -->
<header class="jumbotron masthead" id="intro">
<div class="inner">
<div class="container">
<h1>Why Know Node.js?</h1>
<center><h2>Node.js - An Overview from 15 Feet (in 15 slides)</h2></center>
<center><h3>David J. Kordsmeier (@dkords) <br/>CTO, Razortooth Communications, LLC</h3></center>
<p class="lead">
Learning Node.js should be as natural to a Javascript or PHP developer as a bird flying. This presentation will cover just the basics for Node.js learners. If you've been looking for a reason to learn Node.js, or trying to justify use of Node.js for a project, you are in the right place.
</p>
<p><strong>Expert alert:</strong> If you are already fluent in Node.js or have spent time building some simple projects with Node.js, you are beyond Node.js learner. Please consider letting someone else take your spot in this class.</p>
</div><!-- /container -->
</div>
</header>
<div class="container"><!-- Don't leave this out, or layout is screwed -->
<!-- Slide 1 - Agenda
================================================== -->
<section id="1">
<div class="page-header">
<h1>Agenda - <small>Today, Tomorrow, and The Next Day</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>My server IP: 192.168.1.10</h3>
</div>
<div class="span-one-third">
<h3>Public Lab Server IP: 192.168.1.16</h3>
</div>
<div class="span-one-third">
GIT the code! <code>git clone git@github.com:truedat101/whyknownode-bootstrap.git</code> or download the <a href="assets/whyknownode-bootstrap.git.tar.gz">tarball</a>
</div>
</div>
<div class="row">
<div class="span-one-third">
<h3>Class Structure</h3>
<p>Classroom is set up to be a live lab. You can follow along this presentation in one tab, and then jump over to the Web IDE in another tab, or drop into the console and run your own examples. Typically it is difficult to get set up on Windows and sometimes tricky on other platforms. So we have set up this tutorial as a sort of classroom for you.</p>
<ul>
<li>I'll be using a closed network. <large><span class="label warning">192.168.1.10</span></large> is my server</li>
<li>Given that show wifi/networks really are bad, I opted not to do anything on the "Cloud"</li>
<li>Use the show WiFi if you need to get to the Internet</li>
<li>Progressive examples are hard to follow, so I'll try not to do anything that requires your full attention the entire time.</li>
<li>Instead, you'll work on lots of small examples</li>
<li>I can share code snippets to you easily (I will demonstrate), and you can grab the git repo or copy paste of the this site</li>
<li>I will provide a chat room with ability to share content to you</li>
<li>This is a massive experiment :). Bear with me. I'd love feedback at the end on how you liked the toolchain. I am attempting to roll this out in various pilot projects.</li>
<li>For anyone interested, the entire classroom will be running on a Microcloud of ARM-based Node.js servers. I can get you set up if your environment isn't functioning. I think that is pretty AWESOME.</li>
</ul>
</div>
<div class="span-one-third">
<h3>Part 1 - Why Know Node.js?</h3>
<p>This slide deck is intended to get you started. We'll spend ~60 minutes running/racing through the material.</p>
<img src="images/browsers.png" alt="Tested and supported in Chrome, Safari, Internet Explorer, and Firefox">
<ul>
<li>Slide 1 - Agenda</li>
<li>Slide 2 - Get Node</li>
<li>Slide 3 - Ok, So What is it?</li>
<li>Slide 4 - Do something! Say Hello World</li>
<li>Slide 5 - kNOw thy REPL</li>
<li>Slide 6 - Start me up (a web server)</li>
<li>Slide 7 - Creating a REST-ful JSON service</li>
<li>Slide 8 - Templating (like a rock star)</li>
<li>Slide 9 - Let's build a Chat Server :)</li>
<li>Slide 10 - What is this require?</li>
<li>Slide 11 - Event Emitters and you</li>
<li>Slide 12 - Data Persistence - Simple, Fast (but lossy), or Reliable</li>
<li>Slide 13 - Testing It</li>
<li>Slide 14 - Performance &amp; Scaling</li>
<li>Slide 15 - Debugging</li>
</ul>
<h3>Additonal Tips</h3>
<ul>
<li>Try out everything</li>
<li>Ask every question you have</li>
<li>Please let someone else have your seat if you already know the basics of Node.js. I really promise I won't cover *ANY* new ground.</li>
<li>Please use a Modern browser. IE doesn't qualify. Safari/Chrome/FF are perfect.</li>
<li>Try out things on your tablet or mobile too!</li>
</ul>
</div>
<div class="span-one-third">
<h3>Part 2 - Tour de Node</h3>
<p><span class="label important">If there is time, which is doubtful</span>, We'll take a walk through some of the most popular, most "depended upon" NPM modules out there. You will have an opportunity to vote on which Modules you'd like to dig into, or we can talk on Node.js API thingys. We've got about 20-30 minutes for this section. It's not enough time .... so don't blame me. I'll try to organize a full day conference to cover some of these more advanced topics where there will be real speakers who build this stuff.</p>
<ol>
<li><span class="label">Underscore</span></li>
<li><span class="label">Coffee-script</span></li>
<li><span class="label">Express</span></li>
<li><span class="label">Request</span></li>
<li><span class="label">Connect</span></li>
<li><span class="label">Optimist</span></li>
<li><span class="label">Colors</span></li>
<li><span class="label">Socket.io</span></li>
<li><span class="label">Uglify-js</span></li>
<li><span class="label">Async</span></li>
<li><span class="label">Redis</span></li>
<li><span class="label">JSDom</span></li>
<li><span class="label">Jade</span></li>
<li><span class="label">Vows</span></li>
<li><span class="label">Mime</span></li>
<li><span class="label">Now.js (by my Popular Choice)</span></li>
<li><span class="label">backbone.js (by my Popular Choice)</span></li>
<li><span class="label">DNode (by my Popular Choice)</span></li>
<li><span class="label">Browserify (by my Popular Choice)</span></li>
<li><span class="label">Hook.io (by my Popular Choice)</span></li>
<li><span class="label">Cli (by my Popular Choice)</span></li>
</ol>
</div>
</div><!-- /row -->
<div class="row">
<div class="span12">
<h3>Tools</h3>
<p>Below are the tools you'll be using for the class. You are free to reproduce this environment for yourself, but we recommend just using what is provided.</p>
<ul>
<!-- Here's what we need
* Node v0.4.12)
* nodemon
* Nide (npm)
* This presentation
* Repl server
* web console log (clifton/beaver)
* nodemon
* forever
* ssh access
* epochedu ?
* tuttiserver ?
* Node.js docs
* webrepl (npm)
-->
<li>Node.js Version > 4.5 , go to <a href="http://nodejs.org">nodejs.org</a> for downloads.</li>
<li>You want to grab <a href="http://www.npmjs.org">NPM</a>. Sorry I can't really help too much with this, as its behavior changes frequently.</li>
<li>Once you have NPM, have npm get everything you need for development: <code>npm install .</code></li>
<li><large><a href="/">This page - on port 8000</a></large>.</li>
<li><a href="docs/api/index.html">Node.js docs</a> are hosted locally if you need them.</li>
<li><a href="http://192.168.1.10:8001">REPL service - Port 8001</a></li>
<li><a href="http://192.168.1.10:8002">NIDE - Port 8002</a>. This is a really nice Web IDE built in 48-hours at Node.ko by someone who knows what they are doing. If you don't like Web IDEs, you might actually like this one.</li>
<li>Beaver logs - Telnet to Port 8003.</li>
<li>This project: <code>git clone git@github.com:truedat101/whyknownode-bootstrap.git</code>. Fork it, send me bugs and suggestions.</li>
</ul>
</div>
</div><!-- /row -->
</section>
<!-- Slide 2 - Get Node
================================================== -->
<section id="2">
<div class="page-header">
<h1>Get <small>Node.js</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Get It</h3>
<fieldset>
<p class="normalText">Fork it on github: <a href="http://github.com/joyent/node">node</a>. Download the <a href="assets/node.git.zip">zipfile locally (older version)</a> if you don't use git or if you can't reach the Interweb.</p>
</fieldset>
</div>
<div class="span-two-thirds">
<h3>Build/Install</h3>
<p class="normalText"><a href="http://howtonode.org/how-to-install-nodejs">There are many ways to install Node.js. This can be easy or complicated.</a></p>
<ul>
<li>
<a href="https://icewalker2g.wordpress.com/2011/07/23/node-js-on-windows-who-needs-npm/">For Windows Users</a>
</li>
<li>For Mac Users: Make sure you have a gcc toolchain installed. Using homebrew, or macports, you can install node.js directly. Using fink, make sure you have openssl.</li>
<li>For Linux Users: Make sure you have openssl installed + a gcc toolchain. The debian package is called: <a href="http://packages.debian.org/search?searchon=sourcenames&keywords=nodejs">nodejs</a> (surprise). </a></li>
<li>My favorite way: Use NVM. Pick the version you want, nvm will build and install for you in your local env. It can switch between installed versions, and keeps NPM state clean between envs.</li>
<li>For ARM devices - Come talk to me</li>
<li>Android - It's been done, I haven't tried it, but I think this is worth doing</li>
<li>iOS - Not possible except on Jailbroken devices, at least, not for any kind of legal distribution</li>
<ul>
</div>
</div><!-- /row -->
</section>
<!-- Slide 3 - So What is it?
================================================== -->
<section id="3">
<div class="page-header">
<h1>So What is it? <small>Node.js - an explanation for regular folk</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Architecture</h3>
<p>Node.js is a Javascript-language runtime based on Google's V8 that provides a set of foundation libraries for Javascript application development. At the core is the V8 Virtual Machine which compiles Javascript into native machine code. It is <a href="http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=v8">fast</a>. Because V8 was designed for in-browser embedding, it is small and efficient in resource utilization. The fact that Node.js provides the "foundation libraries" makes it's design somewhat akin to complete language runtimes like Python or JavaSE. It additionally provides tools to allow execution of code at the command line or in an interactive shell. By implementing a <a href="http://www.commonjs.org/specs/modules/1.0/">Common.js-based module system</a>, it sets itself apart from other Javascript runtimes in consistency and the broad community of software available</p>
</p>
</div>
<div class="span-one-third">
<h3>Middleware</h3>
<p>The fact that Node.js has earned the defacto #1 spot in Server-Side Javascript creates a lot of confusion. Is it a server? Can you only use it for developing web apps? The answer is that you can use it for whatever you'd like. It doesn't have to be limited to Server-Side applications. It can be embedded into clients, as seen in WebOS. It can be put into the cloud. But it is not a server, by itself. Think of Node.js as scaffolding. Use the "best parts", the things you like and need to build whatever you like. It scales up into the cloud quite well if you know what you are doing, but is not inherently "faster", other than the fact that operations appear to complete more quickly since calls are asynchronous, and the notion of thread management goes out the window, so all activity in your application is governed by an event loop. This makes for some interesting behavior when servicing lots of requests, and out of the box yields some nice figures. It scales down nicely as well, since the VM is small, it can fit into embedded devices. As a platform it can be extended.
<img src="images/browsers.png" alt="Tested and supported in Chrome, Safari, Internet Explorer, and Firefox">
</div>
<div class="span-one-third">
<h3>Enabler for "Realtime Web" - <small>it's like elmers glue for the web</small></h3>
<p>Where to use it?</p>
<ul>
<li><span class="label">Everywhere! </span> - it slices, it dices</li>
<li>Multiuser applications</li>
<li>Connection oriented services</li>
<li>Any restful web service</li>
<li>As a backend for a native Mobile app (iOS or Android)</li>
<li>Anywhere you'd consider using PHP, toss PHP, port your code to Node</li>
<li>Anywhere you'd might consider using Java for no good reason</li>
<li>If you are having trouble scaling your ruby clusters</li>
<li>When you need to raplidly prototype something and you already know Javascript pretty well</li>
</ul>
</div>
</div><!-- /row -->
</section>
<!-- Slide 4 - Do something! Say Hello World
================================================== -->
<section id="4">
<div class="page-header">
<h1>Do Something! <small>Say Hello World</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Application Structure</h3>
<p><span class="label">Important</span> - If you already write Javascript Code for a living, you will know that control doesn't typically flow sequentially from top to bottom of a "program" written in Javascript. The code you write for Node.js will be much the same. Event loops and function callbacks are the name of the game.
<h4>Create a .js file, code away</h4>
<p>Quite often in client side development, you focus on creating little code fragments, that may be dropped into <code>script</code> tags or live in their own .js files. While you create lots of little code fragments in lots of little files, you'll want to start thinking more in terms of modular lego building blocks in terms of what goes into your Node apps. This is a style thing. You will usually be creating either a server side application, or reusable libraries. In the latter case, your code should be organized using your preferred best practices. There isn't a right way, other than make it maintainable. For libraries, it's best to follow a more object oriented approach for maintainability, testability, and resuability.</p>
<h4>Package Imports</h4>
<p>Tyipcally at the top of your program, you will have something like <code>var net = require("net");</code>. This call to <code>require</code> is a global function, which manages your package namespaces in the context of your application. Import as many as you need. Using chaining, you can instantiate a reference to the "class" you need, such as: <code>var exec = require(child_process").exec;</code></p>
</div>
<div class="span-one-third">
<h3>Hello World</h3>
<p>Our simple example prints hello world on your screen.</p>
<pre class="prettyprint linenums">
// Taken from: http://nodejs.org/#about
var http = require(&#x27;http&#x27;);
http.createServer(function (req, res) {
res.writeHead(200, {&#x27;Content-Type&#x27;: &#x27;text/plain&#x27;});
res.end(&#x27;Hello World\n&#x27;);
}).listen(1337, &quot;0.0.0.0&quot;); // Note, don't everyone use this port. Use 0.0.0.0 to accept connections on any IP
</pre>
<p>To try it out, copy the code from <a href="helloworld.js">helloworld.js</a> into the file called lab.js, set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, hello.js, and run it: <code>node hello.js</code>.
</div>
<div class="span-one-third">
<h3>Extra Credit</h3>
<p>Some things to try out if you have time:</p>
<ul>
<li>Log to the console</li>
<li>Dump the headers from your web server incoming request</li>
<li>Print some system state to the screen - hint: see process library</li>
<li>Restyle the page so that it looks different</li>
</ul>
</div>
</div><!-- /row -->
</section>
<!-- Slide 5 - Know Thy REPLSlide 5 -
================================================== -->
<section id="5">
<div class="page-header">
<h1>Know Thy REPL - <small></small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>What is it?</h3>
<p class="normalText">REPL stands for Read-Evaluate-Processing-Loop. For us, we can use the "repl", as a sort of command line interpreter, not unlike Python. Why bother? It is very helpful for trying things out. Node's REPL has completion, and supports a few meta commands to help you out. It's not perfect and it gets goofed up sometimes. But it's cooler than not having it.</p>
</div>
<div class="span-one-third">
<h3>Usage</h3>
<p class="normalText">
<span class="label success">~:node </span></br>
&gt; <span class="label">.help<br/>
.break Sometimes you get stuck, this gets you out<br/>
.clear Break, and also clear the local context<br/>
.exit Exit the repl<br/> .help Show repl options<br/></span> </p>
</div>
<div class="span-one-third">
<h3>Cool Tricks</h3>
<p>Here are a few notable things you can do with the Node.js REPL</p>
<ul>
<li>Hit <code>&lt;tab&gt;</code> to perform completion</li>
<li>Run it from any path on your system. Your CWD is ., so you can load code in the current directory by doing something like: <code>var fooclazz = require('./fooclazz');</li>
<li>Try out code snippets. Read the stack traces. Load libraries from the node_modules directory.</li>
</ul>
</div>
</div><!-- /row -->
<div class="row">
<div class="span12">
<h3>Try it now.</h3>
<p>Hit <a href="MYSERVERIP:9001">MYSERVERIP:9001</a> to try out the webrepl. You can also do this on your own server instance using the webrepl service. Try out code snippets. Read the stack traces. Load libraries from the node_modules directory. Verify paths. Try out regular expressions. Query object properties. Validate JSON. This tool is *NOT* extremely secure, so don't ever put this on your website as you will have access to host OS processes. Yikes! Be gentle.</p>
<ul class="media-grid">
<li>
<a href="MYSERVERIP:9001"><img src="images/webrepl_screenshot.png" alt="Simple three-column layout with hero unit"></a>
</li>
</ul>
</div>
</div><!-- /row -->
</section>
<!-- Slide 6.1 - Start me up (a web server)
================================================== -->
<section id="6.1">
<div class="page-header">
<h1>Start Me Up <small>(a web server)</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 1 - Serve a single Route</h3>
<p>The most simple web server you can write, to build upon our Hello World example, is to serve up a route with some proper HTML and a well-formed header in the response. This won't be extremely useful in production, but you will learn quickly how to 'upgrade' this version to support more routes.</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example1-ws.js">example1-ws.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, ws.js, and run it: <code>node ws.js</code>.</p>
</div>
<div class="span-two-thirds">
<pre class="prettyprint linenums">
var http = require(&#x27;http&#x27;),
url = require(&#x27;url&#x27;);
http.createServer(function (req, res) {
var uri = url.parse(req.url).pathname;
console.log(uri);
if (uri == &#x27;/foo&#x27;) {
var body = &#x27;&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; \
&quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt; \
&lt;html lang=&quot;en&quot;&gt; \
&lt;head&gt; \
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt; \
&lt;title&gt;foo&lt;/title&gt; \
&lt;/head&gt; \
&lt;body&gt; \
&lt;h1&gt;Foo&lt;/h1&gt; \
&lt;/body&gt; \
&lt;/html&gt;&#x27;;
res.writeHead(200, {&#x27;Content-Type&#x27;: &#x27;text/html&#x27;});
res.write(body);
res.end();
}
}).listen(8124, &quot;0.0.0.0&quot;);
console.log(&#x27;Server running at http://127.0.0.1:8124/&#x27;);
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 6.2 - Start me up (a web server)
================================================== -->
<section id="6.2">
<div class="page-header">
<h1>Start Me Up <small>(a web server)</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 2 - Serve Up Static Content</h3>
<p>Example 1 is instructive, but what happens when you want to serve up content from the disk? It needs to get loaded and returned with the correct size and mime type. This example gives you something that starts to become useful when you want to quickly serve up content.</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example2-ws.js">example2-ws.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, ws.js, and run it: <code>node ws.js</code>.
</div>
<div class="span-two-thirds">
<pre class="prettyprint linenums">
var createServer = require(&#x27;http&#x27;).createServer,
url = require(&#x27;url&#x27;),
fs = require(&#x27;fs&#x27;),
path = require(&#x27;path&#x27;),
sys = require(&#x27;sys&#x27;);
var host = &#x27;0.0.0.0&#x27;,
port = 8124;
var webserver = createServer(function (req, res) {
var uri = url.parse(req.url).pathname;
var filename = path.join(process.cwd(), uri);
try {
if (req.method === &quot;GET&quot; || req.method === &quot;PUT&quot; || req.method === &quot;HEAD&quot;) { // Handle basic request methods
// Add your own routes here if you want
path.exists(filename, function(exists) {
if (!exists) {
res.writeHead(404, {&quot;Content-Type&quot;: &quot;text/plain&quot;});
res.write(&quot;404 Not Found\n&quot;);
res.end();
return;
}
fs.readFile(filename, &quot;binary&quot;, function(err, file) {
if (err) {
handleError(err, res);
return;
}
console.log(&#x27;Silly web server serving: &#x27; + filename);
res.writeHead(200);
res.write(file, &quot;binary&quot;);
res.end();
return;
});
});
}
} catch(e) {
sys.err(&#x27;Caught server-side exception: &#x27; + e.name + &#x27; message: &#x27; + e.message);
handleError(e.message, res);
return;
}
console.log(uri);
var handleError = function(errMessage, response) {
response.writeHead(500, {&#x27;Content-Type&#x27;: &#x27;text/plain&#x27;});
response.write(errMessage);
response.end();
}
});
webserver.listen(port, host);
console.log(&#x27;Server running at http://&#x27; + webserver.address().address + &#x27;:&#x27; + port.toString());
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 6.3
================================================== -->
<section id="6.3">
<div class="page-header">
<h1>Start Me Up <small>(a web server)</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 3 - Authenticity of Content</h3>
<p>Example 2 is a good first step towards a generic server. How about securing some content? Realistically we can't even come close to the many years of security built into servers like Apache HTTP server or Tomcat. It is still helpful to kick the tires on some of the security oriented APIs in the Node.js stack, which arguably are one of the areas that needs attention before Node.js can be accepted into the enterprise. <span class="label">Our final project in the web server world is to generate an index file for the default route, very similar to the Apache WS default index listing. Instead of just listing the files and dates, let's list the file, date, size, and SHA-256.</span></p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example3-ws.js">example3-ws.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, ws.js, and run it: <code>node ws.js</code>.
</div>
<div class="span-two-thirds">
<pre class="prettyprint linenums">
var createServer = require(&#x27;http&#x27;).createServer,
url = require(&#x27;url&#x27;),
fs = require(&#x27;fs&#x27;),
path = require(&#x27;path&#x27;),
sys = require(&#x27;sys&#x27;),
crypto = require(&#x27;crypto&#x27;);
var host = &#x27;0.0.0.0&#x27;,
port = 8124;
var webserver = createServer(function (req, res) {
var uri = url.parse(req.url).pathname;
var filename = path.join(process.cwd(), uri);
try {
if (req.method === &quot;GET&quot; || req.method === &quot;PUT&quot; || req.method === &quot;HEAD&quot;) { // Handle basic request methods
// Add your own routes here if you want
path.exists(filename, function(exists) {
if (!exists) {
res.writeHead(404, {&quot;Content-Type&quot;: &quot;text/plain&quot;});
res.write(&quot;404 Not Found\n&quot;);
res.end();
return;
}
console.log(filename + &#x27; exists&#x27;);
fs.stat(filename, function(err, stat) {
if (err) {
handleError(err, res);
return;
}
if (stat.isFile()) {
console.log(filename + &#x27; is a file&#x27;);
fs.readFile(filename, &quot;binary&quot;, function(err, file) {
if (err) {
handleError(err, res);
return;
}
console.log(&#x27;Silly web server serving: &#x27; + filename);
res.writeHead(200);
res.write(file, &quot;binary&quot;);
res.end();
return;
});
} else {
console.log(&#x27;No file path specified, generate index&#x27;);
handleIndex(res);
return;
}
});
});
}
} catch(e) {
handleError(e.message, res);
return;
}
console.log(uri);
var handleError = function(errMessage, response) {
sys.err(&#x27;Caught server-side exception: &#x27; + errMessage);
response.writeHead(500, {&#x27;Content-Type&#x27;: &#x27;text/plain&#x27;});
response.write(errMessage);
response.end();
}
var handleIndex = function(response) {
fs.readdir(process.cwd(), function(err, data) {
if (err) {
handleError(&#x27;Could not read CWD, response&#x27;);
return;
}
console.log(data);
response.writeHead(200, {&#x27;Content-Type&#x27;: &#x27;text/html&#x27;});
response.write(&#x27;&lt;html&gt;&lt;head&gt;&lt;title&gt;Index of /&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&#x27;);
response.write(&#x27;&lt;h1&gt;Index of /&lt;/h1&gt;&#x27;);
response.write(&#x27;&lt;ul&gt;&#x27;);
for (var i = 0; i &lt; data.length; i++) {
console.log(&#x27;about to stat &#x27; + data[i]);
// XXX PlEASE SHOOT ME, I cheated and used some synchronous calls ... I was in async hell for too long, fix this
var stat = fs.statSync(data[i]);
console.log(data[i]);
console.log(&#x27;stat of &#x27; + data[i] + &#x27; completed&#x27;);
if (!stat) response.write(&#x27;&lt;li&gt;Unable to stat file &#x27; + data[i]+ &#x27;&lt;/li&gt;&#x27;);
// Generate the URL
var fileurl = &#x27;/&#x27; + data[i];
// Get the timestamp
var modified = stat.mtime;
// If it is a file:
var isFile = stat.isFile();
// if (!isFile) fname = &#x27;[&#x27; + fname + &#x27;]&#x27;;
// * get the file size
var size = stat.size;
// * generate the SHA-256 file checksum
if (isFile) {
var shasum = crypto.createHash(&#x27;sha256&#x27;); // XXX This is dependent on your OpenSSL ! Make sure you&#x27;ve at least got it
var d = fs.readFileSync(data[i]);
var digest;
if (err) {
digest = &#x27;Could not compute SHA-256 Checksum on &#x27;;
} else {
shasum.update(d);
digest = shasum.digest(&#x27;hex&#x27;);
}
// Write the data to the response stream
response.write(&#x27;&lt;li&gt;&lt;a href=&quot;&#x27; + fileurl + &#x27;&quot;&gt;&#x27; + data[i] + &#x27;&lt;/a&gt; - Modified: &#x27; + modified + &#x27; size: &#x27; + size + &#x27; bytes - digest: &#x27; + digest);
if (data.length == (i + 1)) {
response.write(&#x27;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;&#x27;);
response.end();
}
} else {
response.write(&#x27;&lt;li&gt;[&#x27; + data[i] + &#x27;] - Modified: &#x27; + modified + &#x27; size: &#x27; + size + &#x27; bytes - digest: N/A&#x27;);
if (data.length == (i + 1)) {
response.write(&#x27;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;&#x27;);
response.end();
}
}
}
});
}
});
webserver.listen(port, host);
console.log(&#x27;Server running at http://&#x27; + webserver.address().address + &#x27;:&#x27; + port.toString());
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Template2 - 19 lines Use for long code examples
================================================== -->
<!--
<section id="template2">
<div class="page-header">
<h1>Start Me Up <small>(a web server)</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 3 - Authenticity of Content</h3>
<p>Example 2 is a good first step towards a generic server. How about securing some content? Realistically we can't even come close to the many years of security built into servers like Apache HTTP server or Tomcat. It is still helpful to kick the tires on some of the security oriented APIs in the Node.js stack, which arguably are one of the areas that needs attention before Node.js can be accepted into the enterprise. <span class="label">Our final project in the web server world is to generate an index file for the default route, very similar to the Apache WS default index listing. Instead of just listing the files and dates, let's list the file, date, size, and SHA-256.</span></p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example3-ws.js">example3-ws.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, ws.js, and run it: <code>node ws.js</code>.
</div>
<div class="span-two-thirds">
<pre class="prettyprint linenums">
</pre>
</div>
</div><!-- /row -->
</section>
-->
<!-- Slide 7 - Creating a REST-ful JSON service
================================================== -->
<section id="7">
<div class="page-header">
<h1>Creating a REST-ful JSON Service <small> - It's ez and fun.</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 1 - Static JSON Service</h3>
<p>This example walks through <span class="label warning">R</span><small>ead</small> of a CRUD oriented service. In other languages, you need to think through sytnax to perform the business logic, and then explicitly convert the response into JSON, often times with some pain spent managing string delimeter escapes or other mechanisms for converting internal data structures into the appropriately formed response. Worse, some languages don't have libraries that meet modern Web Standards. In Javascript, we are already there. Node.js provides a few nice global APIs to handle JSON-String conversions, in addition to the mechanisms supported in the language.
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example1-rest.js">example1-rest.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, rest.js, and run it: <code>node rest.js</code>.
<pre class="prettyprint linenums">
var http = require(&#x27;http&#x27;),
url = require(&#x27;url&#x27;);
http.createServer(function (req, res) {
var uri = url.parse(req.url).pathname;
var method = req.method;
var body = {};
var reqData = &#x27;&#x27;;
console.log(uri + &#x27; on request method = &#x27; + method);
// This is a useless service to serve up the bacon
// Test using wget:
// wget -v http://localhost:8124/porkserver
// Note: we don&#x27;t check what request method is used. If we are really restful, we should. Don&#x27;t do it this way
if (uri == &#x27;/porkserver&#x27;) {
var porks = [&#x27;bacon&#x27;, &#x27;spam&#x27;, &#x27;hotdog&#x27;, &#x27;sausage&#x27;, &#x27;chops&#x27;, &#x27;lichon&#x27;];
var selection = {&#x27;pork&#x27;: porks[Math.round(Math.random()*porks.length)]};
res.writeHead(200, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(selection).length});
res.write(JSON.stringify(selection));
res.end();
return;
} else {
// Not implemented yet
body[&#x27;error&#x27;] = &#x27;method not implemented for &#x27; + uri;
responseCode = 500;
res.writeHead(responseCode, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(body).length });
res.write(JSON.stringify(body));
res.end();
return;
}
}).listen(8124, &quot;0.0.0.0&quot;);
console.log(&#x27;Server running at http://127.0.0.1:8124/&#x27;);
</pre>
</div>
<div class="span-two-thirds">
<h3>Example 2 - With Arguments</h3>
<p>Typically we'll post arguments of some form to our web services. With GET requests, we'd pass in query string parameters. With the POST method, we pass in our data to the server through request attributes. In a robust example, we can use the HTTP response to eloquently manage error conditions in addition to the expected input.</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example2-rest.js">example2-rest.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, rest.js, and run it: <code>node rest.js</code>.
<p>For extra Credit:
<ul>
<li>Complete the <span class="label warning">UD</span> of the CRUD example</li>
<li>Add some more request parameters to process</li>
<li>Record and report total response time</li>
</ul>
<pre class="prettyprint linenums">
var http = require(&#x27;http&#x27;),
url = require(&#x27;url&#x27;);
var kvdb = {&#x27;salad&#x27;:{&#x27;cost&#x27;: &#x27;2.99&#x27;, &#x27;isveggie&#x27;: true}, &#x27;cheese pizza&#x27;: {&#x27;cost&#x27;: &#x27;4.99&#x27;, &#x27;isveggie&#x27;: true}};
http.createServer(function (req, res) {
var uri = url.parse(req.url).pathname;
var method = req.method;
var body = {};
var reqData = &#x27;&#x27;;
console.log(uri + &#x27; on request method = &#x27; + method);
// This is a useless service to serve up the bacon
// Test using wget:
// wget -v http://localhost:8124/porkserver
if (uri == &#x27;/porkserver&#x27;) {
var porks = [&#x27;bacon&#x27;, &#x27;spam&#x27;, &#x27;hotdog&#x27;, &#x27;sausage&#x27;, &#x27;chops&#x27;, &#x27;lichon&#x27;];
var selection = {&#x27;pork&#x27;: porks[Math.round(Math.random()*porks.length)]};
res.writeHead(200, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(selection).length});
res.write(JSON.stringify(selection));
res.end();
return;
} else if (RegExp(&#x27;/menu/[\\w\\.\\-]+&#x27;).test(uri)) { // JS has regex built in, so we can build more interesting routes
//
// Menu Service
//
// Menu Item = {
// &#x27;cost&#x27;: &lt;COST&gt;,
// &#x27;isveggie&#x27;: &lt;false|true&gt;
// }
// GET key - get the menu item with key name
var key = uri.split(&#x27;/&#x27;)[2]; // Assume only 2 path elements
var responseCode = 200;
if (method === &#x27;GET&#x27;) {
//
// Get something from the service, use wget to test:
// wget -v http://localhost:8124/menu/salad
console.log(&#x27;menu service GET&#x27;);
if (kvdb[key]) {
body[key] = kvdb[key];
}
res.writeHead(responseCode, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(body).length });
res.write(JSON.stringify(body));
res.end();
return;
} else if (method === &#x27;POST&#x27;) {
//
// Add in your own menu items with curl:
// curl -X POST http://localhost:8124/menu/bar -H &quot;Content-Type: aplication/json&quot; -d &quot;{\&quot;key\&quot;:\&quot;okra\&quot;, \&quot;cost\&quot;: \&quot;2.99\&quot;, \&quot;isveggie\&quot;: \&quot;true\&quot;}&quot;
//
console.log(&#x27;menu service POST&#x27;);
// This is a simple approach for basic cases. If we do file uploads, we&#x27;ll need to do something different
// And apologies for this being sort of goofy, it&#x27;s just meant to demonstrate Node, not best rest-ful design
req.on(&#x27;data&#x27;, function(chunk) {
console.log(&quot;Received body data:&quot;);
reqData += chunk.toString();
console.log(reqData);
});
req.on(&#x27;end&#x27;, function() {
// We should validate this is proper JSON
console.log(&#x27;Done with menu post of &#x27; + reqData);
try {
body = JSON.parse(reqData); // If it&#x27;s valid, echo it back in the response.
kvdb[body.key] = { &#x27;isveggie&#x27;: body.isveggie, &#x27;cost&#x27;: body.cost}; // Store in our DB
} catch(e) {
body[&#x27;error&#x27;] = &#x27;invalid json request received&#x27;;
responseCode = 500;
}
res.writeHead(responseCode, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(body).length });
res.write(JSON.stringify(body));
res.end();
return;
});
} else {
// Not implemented yet
body[&#x27;error&#x27;] = &#x27;method not implemented for &#x27; + uri;
responseCode = 500;
res.writeHead(responseCode, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(body).length });
res.write(JSON.stringify(body));
res.end();
return;
}
} else {
// Not implemented yet
body[&#x27;error&#x27;] = &#x27;method not implemented for &#x27; + uri;
responseCode = 500;
res.writeHead(responseCode, {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;, &quot;Content-Length&quot;: JSON.stringify(body).length });
res.write(JSON.stringify(body));
res.end();
return;
}
}).listen(8124, &quot;0.0.0.0&quot;);
console.log(&#x27;Server running at http://127.0.0.1:8124/&#x27;);
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 8 - Templating
================================================== -->
<section id="8">
<div class="page-header">
<h1>Templating <small>(like a rock star)</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>The JResig Way</h3>
<p>In one of his blog posts or books (I've forgotten the exact point place of publication, John Resig created a nice little templating engine using JQuery and some common design patterns we already use and know. This is a 'nodified' version of that example.</p>
<h3>Get it</h3>
<p>While not an official NPM module, it was great to see someone read the "Templating" section of <span class="label notice">Secrets of the Javascript Ninja</span> and wrote a module for it. The code is on github in <span class="label">tmpl-node</span>. It's out of date, but here's a flavor of what you can do with it.</p>
<pre class="prettyprint linenums">
var tmpl = require(&#x27;tmpl-node&#x27;);
tmpl.load(&quot;./myTemplates/&quot;, function(tmpl){}); // Load the templates
//
// Snipet from your web server
//
function( req, res ) {
res.sendHeader(200, {&quot;Content-Type&quot;: &quot;text/html&quot;});
res.render( &quot;page.html&quot;, req, GLOBAL ); // tmpl-node extends the HTTP Server Request object
}
</pre>
</div>
<div class="span-one-third">
<h3>HAML influenced - Jade</h3>
<p>I can't say I 'get' HAML or it's motivations. Sorry if I offend. But I'd guess that if you are into things Ruby, this is where you pick up. So why not drag these concepts kicking and screaming into the world of Node.js? Jade looks like your best starting point, and draws on HAML for its design. Again, I won't provide a complete example, but check out the little snippet below. Honestly, I feel like relearning some way of doing HTML is torture ... I have a hard time remembering CSS, JS, HTML5 + groceries and everything else.
</p>
<pre class="prettyprint linenums">
!!! 5
html(lang=&quot;en&quot;)
head
title= pageTitle
body
h1 I dream in Jade
</pre>
</div>
<div class="span-one-third">
<h3>Mustache Influenced - Mu.js</h3>
<p>Mustache is often referenced in the world of templating. Billed as "logic-less" templates, this approach seems to fit well with what you already know about HTML and Javascript. There is a nice little module called Mu which implements Mustache for Node.js. It hasn't been updated in awhile, but you can grab it and try it out. </p>
<pre class="prettyprint linenums">
&lt;!-- In your template --&gt;
Hello {{name}} world!
{{#gotmilk}}
{{name}} drinks milk.
{{/gotmilk}}
// In your Hash
{
&quot;name&quot;: &quot;Bart&quot;,
&quot;gotmilk&quot;: true
}
</pre>
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 9.1 - Example 1
================================================== -->
<section id="9.1">
<div class="page-header">
<h1>Let's Build a Chat Server <small> - using string, duct tape, a stick of gum, and some cans</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 1 - Chatting me up</h3>
<p>One of the early CS Networking examples you will learn is to write an echo service. This is typically done using UNIX sockets. Since Node.js has a pretty solid networking stack, we can use the same principles to make an echo server. For the examples that follow, we'll skip the Unix and go straight for Socket.io. First pass is to echo back whatever we type in. Of course, you could just be passing the contents of the chat message back onto the DOM, never sending any data over the network. To prove this is not the case, add a route to observe all messages sent up to your server.</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example1-chat.js">example1-chat.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, chat.js, and run it: <code>node chat.js</code>.
</div>
<div class="span-two-thirds">
<pre class="prettyprint linenums">
// Original example is found http://nodejs.org/docs/v0.4.12/api/net.html#net.createServer
var net = require(&#x27;net&#x27;);
var server = net.createServer(function(socket) {
});
server.on(&#x27;connection&#x27;, function(socket) {
console.log(&#x27;Client connected from &#x27; + socket.remoteAddress + &#x27; on &#x27; + socket.address().address);
socket.write(new Date() + &#x27; - Connected from &#x27; + socket.remoteAddress + &#x27; on &#x27; + socket.address().address);
socket.pipe(socket);
});
server.listen(8124, &#x27;0.0.0.0&#x27;); // Allow connections from any host
console.log(new Date() + &#x27; - Started echo server on &#x27; + server.address().address);
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 9.2 - Example 2
================================================== -->
<section id="9.2">
<div class="page-header">
<h1>Let's Build a Chat Server <small> - using string, duct tape, a stick of gum, and some cans</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 2 - P2P Chat</h3>
<p>Let's step it up a notch. We will build a server that sends broadcast messages to all connected clients. Nothing fancy, but we'll add a simple UI. <span class="label">Using the contents of the lab directory, and the previous tutorials, we have enough to build on. We will need (1) to serve up a web page, and (2) create a chat server. Make it as fancy as you like. We've got Twitter's Bootstrap project in the lab directory, making some nice styling possible. I created a project called Jumbosocket (hosted on github) which creates the web server + socket.io service so it is easy to get a project started without any decision making about which web server to use.</span></p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example2-chat.js">example2-chat.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. You will also need to modify or replace the code in chat.html to create your web client, chat.html To run it on your server, hit the local server instance running on http://yourserverip:yourlabport/chat.html. On your own laptop, you can simply put this into a file, chat.js, and run it: <code>node chat.js</code>.
</div>
<div class="span-two-thirds">
<p>Since the code is lengthy, we'll just post the html: chat.html below. The associated javascript is avalable in the file <a href="example2-chat.js">example2-chat.js</a>.</p>
<pre class="prettyprint linenums">
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;title&gt;Let&#x27;s Build a Chat Server&lt;/title&gt;
&lt;meta name=&quot;description&quot; content=&quot;&quot;&gt;
&lt;meta name=&quot;author&quot; content=&quot;&quot;&gt;
&lt;!-- Le HTML5 shim, for IE6-8 support of HTML elements --&gt;
&lt;!--[if lt IE 9]&gt;
&lt;script src=&quot;http://html5shim.googlecode.com/svn/trunk/html5.js&quot;&gt;&lt;/script&gt;
&lt;![endif]--&gt;
&lt;!-- Le styles --&gt;
&lt;link href=&quot;css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link href=&quot;css/docs.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link href=&quot;js/libs/google-code-prettify/prettify.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;!-- Le fav and touch icons --&gt;
&lt;link rel=&quot;shortcut icon&quot; type=&quot;image/x-icon&quot; href=&quot;ico/favicon.ico&quot;&gt;
&lt;link rel=&quot;apple-touch-icon&quot; href=&quot;ico/bootstrap-apple-57x57.png&quot;&gt;
&lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;72x72&quot; href=&quot;ico/bootstrap-apple-72x72.png&quot;&gt;
&lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;114x114&quot; href=&quot;assets/ico/bootstrap-apple-114x114.png&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;!-- Topbar
================================================== --&gt;
&lt;div class=&quot;topbar&quot; data-scrollspy=&quot;scrollspy&quot; &gt;
&lt;div class=&quot;topbar-inner&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;a class=&quot;brand&quot; href=&quot;#&quot;&gt;Why Know Node.js?&lt;/a&gt;
&lt;ul class=&quot;nav&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#example2&quot;&gt;Chat Example 2 - Group Chat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#example3&quot;&gt;Chat Example 3 - Group Canvas Funk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- Masthead (blueprinty thing)
================================================== --&gt;
&lt;header class=&quot;jumbotron masthead&quot; id=&quot;intro&quot;&gt;
&lt;div class=&quot;inner&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;h1&gt;Let&#x27;s Build a Chat Server &lt;small&gt; - using string, duct tape, a stick of gum, and some cans&lt;/small&gt;&lt;/h1&gt;
&lt;p class=&quot;lead&quot;&gt;
Two examples of chat style apps, made easy by Node.
&lt;/p&gt;
&lt;/div&gt;&lt;!-- /container --&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;div class=&quot;container&quot;&gt;&lt;!-- Don&#x27;t leave this out, or layout is screwed --&gt;
&lt;!-- Chat Example 2
================================================== --&gt;
&lt;section id=&quot;example2&quot;&gt;
&lt;div class=&quot;page-header&quot;&gt;
&lt;h1&gt;Chat! &lt;small&gt;Example 2&lt;/small&gt;&lt;/h1&gt;
&lt;/div&gt;
&lt;!-- Block messages --&gt;
&lt;div class=&quot;row&quot; id=&quot;ex2-chat&quot;&gt;
&lt;div class=&quot;span4&quot;&gt;
&lt;div class=&quot;well&quot;&gt;
&lt;a href=&quot;#&quot; class=&quot;btn large primary&quot; id=&quot;ex2-send&quot;&gt;Send&lt;/a&gt;
&lt;a href=&quot;#&quot; class=&quot;btn large&quot; id=&quot;ex2-clear&quot;&gt;Clear&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;span12&quot; id=&quot;ex2-chat-div&quot;&gt;
&lt;div class=&quot;clearfix&quot;&gt;&lt;input class=&quot;span11&quot; id=&quot;ex2-chat-msg&quot; name=&quot;&quot; type=&quot;text&quot; placeholder=&quot;Enter something funny or useless&quot; /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;!-- /row --&gt;
&lt;/section&gt;
&lt;/div&gt;&lt;!-- /container --&gt;
&lt;footer class=&quot;footer&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;p class=&quot;pull-right&quot;&gt;&lt;a href=&quot;#&quot;&gt;Back to top&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
Designed and built with all the love in the world &lt;a href=&quot;http://twitter.com/twitter&quot; target=&quot;_blank&quot;&gt;@twitter&lt;/a&gt; by &lt;a href=&quot;http://twitter.com/mdo&quot; target=&quot;_blank&quot;&gt;@mdo&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/fat&quot; target=&quot;_blank&quot;&gt;@fat&lt;/a&gt;.&lt;br /&gt;
Code licensed under the &lt;a href=&quot;http://www.apache.org/licenses/LICENSE-2.0&quot; target=&quot;_blank&quot;&gt;Apache License v2.0&lt;/a&gt;. Documentation licensed under &lt;a href=&quot;http://creativecommons.org/licenses/by/3.0/&quot;&gt;CC BY 3.0&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/footer&gt;
&lt;!-- &lt;script src=&quot;http://code.jquery.com/jquery-1.5.2.min.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;window.jQuery || document.write(&#x27;&lt;script src=&quot;js/libs/jquery-1.6.2.min.js&quot;&gt;&lt;\/script&gt;&#x27;)&lt;/script&gt;
&lt;!-- &lt;script src=&quot;http://autobahn.tablesorter.com/jquery.tablesorter.min.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;js/libs/google-code-prettify/prettify.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;$(function () { prettyPrint() })&lt;/script&gt;
&lt;script src=&quot;js/libs/bootstrap-alerts.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/libs/bootstrap-modal.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/libs/bootstrap-dropdown.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/libs/bootstrap-twipsy.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/libs/bootstrap-scrollspy.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/application.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/socket.io/socket.io.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;!-- &lt;script src=&quot;/js/js-common.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;js/libs/smoothie.js&quot;&gt;&lt;/script&gt;
&lt;!-- scripts concatenated and minified via ant build script--&gt;
&lt;script src=&quot;js/plugins.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/script.js&quot;&gt;&lt;/script&gt;
&lt;!-- We&#x27;ll just dump our Socket.io handler here, rather than in some .js file. Could easily go into the script.js file --&gt;
&lt;script&gt;
$(document).ready(function() {
$().alert(); // Bootstrap, wrap all alerts with close functionality
var socket = io.connect();
// You can use these things to track some stats about your session, we don&#x27;t really need this for our purposes
var connectcount = 0;
var disconnectcount = 0;
var messagecount = 0;
var sentmessagecount = 0;
var nick = &quot;foo&quot;; // Set this with a login modal
socket.on(&#x27;connect&#x27;, function(){
connectcount = connectcount + 1;
$(&#x27;#connectstats&#x27;).text(connectcount);
});
socket.on(&#x27;disconnect&#x27;, function(){
disconnectcount = disconnectcount + 1;
$(&#x27;#disconnectstats&#x27;).text(disconnectcount);
});
socket.on(&#x27;message&#x27;, function(message){
// XXX Need to figure out what is my session ID. Anyone know how to get at this?
if (message.op) {
if (message.op == &#x27;ex2&#x27;) { // Handle Example2 Messages
$(&#x27;#ex2-chat-div&#x27;).append(&#x27;&lt;div class=&quot;alert-message error fade in&quot; data-alert=&quot;alert&quot;&gt; \
&lt;a class=&quot;close&quot; href=&quot;#&quot;&gt;&amp;times;&lt;/a&gt; \
&lt;p&gt;&lt;span class=&quot;label&quot;&gt;&#x27; + message.timestamp + &#x27; &lt;/span&gt;&lt;strong&gt;@&#x27; + message.nick + &#x27;&lt;/strong&gt;: &#x27; + message.msg + &#x27;&lt;/p&gt; \
&lt;/div&gt;&#x27;);
}
}
console.log(message);
messagecount = messagecount + 1;
$(&#x27;#messagestats&#x27;).text(messagecount);
});
/* Chat Message format
{ &#x27;msg&#x27; : &lt;DATA&gt;,
&#x27;op&#x27; : &#x27;ex2&#x27;
&#x27;nick&#x27; : &lt;some name&gt;,
&#x27;timestamp&#x27; : &lt;server timestamp&gt; (only on server)
}
*/
$(&#x27;#ex2-send&#x27;).click(function() {
var msg = $(&#x27;#ex2-chat-msg&#x27;).val();
if (msg) {
socket.json.send({&#x27;msg&#x27;: msg, &#x27;nick&#x27;: nick, &#x27;op&#x27;: &#x27;ex2&#x27;});
$(&#x27;#ex2-chat-msg&#x27;).val(&#x27;&#x27;);
sentmessagecount = sentmessagecount + 1;
$(&#x27;#sentmessagestats&#x27;).text(sentmessagecount);
return false;
}
});
$(&#x27;#ex2-clear&#x27;).click(function() {
$(&#x27;#ex2-chat-msg&#x27;).val(&#x27;&#x27;);
return false;
});
});
&lt;/script&gt;
&lt;!-- end scripts--&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 9.3 -
================================================== -->
<section id="9.3">
<div class="page-header">
<h1>Let's Build a Chat Server <small> - using string, duct tape, a stick of gum, and some cans</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 3 - Chat? Why's it got to be chat?</h3>
<p>Example 2 (Socket.io Chat) has been done and done again in the blogosphere as each blogger tries to pick up Socket.io for the first time. It is important to remember that Socket.io isn't just 'about' chat, it is 'about' providing a common client and server side api for socket oriented communicaiton. That means we can pump bytes over the wire, JSON, text, or anything else you can pump into a stream of bytes. This next example tries to show a small use case for Socket.io that builds upon the Chat server concept. <span class="label">This exercise is to use the HTML5 Canvas tag and allow users to navigate through a maze, sharing location to all the other 'players' in the session. This is *really* basic, just to give a flavor for other things that can be done with the API. The possibilities are pretty mind boggling.</span>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example3-chat.js">example3-chat.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. It builds on the previous example, and also demonstrates that we can multiplex different apps over the same client connection. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport/chat.html . On your own laptop, you can simply put this into a file, chat.js, and run it: <code>node chat.js</code>.
</div>
<p>The code snippet below should placed into the HTML from the previous example can be dropped into the #example3 section of chat.html.</p>
<div class="span-two-thirds">
<pre class="prettyprint linenums">
SNIPPET FROM socket.on('message', function(message){
} else if (message.op == &#x27;ex3&#x27;) {
var statemap = message.statemap;
var cursor = &#x27;\u2708&#x27;;
if (statemap) {
// For now we&#x27;ll do this inefficent loop and redraw everything every time
context.clearRect(0, 0, canvas.width, canvas.height);
// Attribution: correct answer on stackoverflow:
// http://stackoverflow.com/questions/587881/how-to-iterate-over-every-property-of-an-object-in-javascript-using-prototype
for (var prop in statemap) {
if (statemap.hasOwnProperty(prop)) {
var state = statemap[prop].state;
context.font = &quot;48px sans serif&quot;;
context.fillStyle = state.hexcolor;
context.fillText(cursor, state.mouseX, state.mouseY);
}
}
console.log(&#x27;Received state update&#x27;);
}
}
SNIPPET FROM $(document).ready(function(){})
canvas.addEventListener(&quot;mousemove&quot;, function(ev){
var mouseX = ev.offsetX,
mouseY = ev.offsetY,
msg = {&#x27;state&#x27;: {&#x27;mouseX&#x27;: mouseX, &#x27;mouseY&#x27;: mouseY}};
message = &quot;ex3 mouse Position: &quot; + mouseX +
&quot;,&quot; +
mouseY;
socket.json.send({&#x27;msg&#x27;: msg, &#x27;nick&#x27;: nick, &#x27;op&#x27;: &#x27;ex3&#x27;});
console.log(message);
}, false);
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 10 - What's this Require?
================================================== -->
<section id="10">
<div class="page-header">
<h1>What is this require?</h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Common.js</h3>
<p>Common.js is a specification that defines a proposals for how to handle module namespaces, module loading, and packaging of modules. It existed as a concept for many years, without an unified implementation among the various Server-Side Javascript projects. There is probably some history as to why this didn't stick until Node.js came along, but we won't worry about the details.</p>
<p>Read more on <a href="http://wiki.commonjs.org/wiki/CommonJS">http://wiki.commonjs.org/wiki/CommonJS</a></p>
</div>
<div class="span-one-third">
<h3>Who Moved My Modules?</h3>
<p>Node.js makes the business of SSJS manageable by providing a module loading mechanism, packaging, and namespacing that is (1) easy to understand (2) standardized (3) adopted widely. The best place to go for understanding is the Node.js doc book itself. <span class="label">This is worth reading</span>. Without reading this, you will find it can be tricky to understand where the heck the modules go when you install them, differences between local and global, and what folders and search path conventions are used. So please, hurry over to <a href="http://nodejs.org/docs/v0.4.12/api/modules.html#modules">#Modules</a> and read more.
</div>
<div class="span-one-third">
<h3>Through understanding comes enlightenment</h3>
<p>Without this key piece, Node.js would be a hairball of JS code wrapped in bacon and tied up with spahgehtti. Modules and Package management make the platform actually useable and useful in a way that more mature Open Source platforms even struggle with. Everyone looks to Ruby for inspiration (i.e. Let's take the good parts, and move on...). And indeed many great ideas have come together to help make this platform explode. Your next step for advanced study should be to look into how to write your own Node.js packages, as a way of understanding further.</p>
</div><!-- /row -->
</section>
<!-- Slide 11 - Event Emitters and You
================================================== -->
<section id="11">
<div class="page-header">
<h1>Event Emitters <small>and you.</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Rationale</h3>
<p>Events are behind everything you do in Node.js. If you plan to use Node for anything non-trivial, you will need to deal with Events. If you plan to extend an existing module, you will likely need to deal with events. and if you plan to write new modules from scratch, there are some good reasons to use the Events module.</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example1-events.js">example1-events.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, events.js, and run it: <code>node events.js</code>.</p>
<pre class="prettyprint linenums">
//
// Straight forward use of event emitters, and very typical
// Attribution below:
// http://nodejs.org/docs/v0.4.12/api/child_processes.html
var util = require(&#x27;util&#x27;),
spawn = require(&#x27;child_process&#x27;).spawn,
ls = spawn(&#x27;ls&#x27;, [&#x27;-lh&#x27;, &#x27;.&#x27;]);
ls.stdout.on(&#x27;data&#x27;, function (data) {
console.log(&#x27;stdout: &#x27; + data);
});
ls.stderr.on(&#x27;data&#x27;, function (data) {
console.log(&#x27;stderr: &#x27; + data);
});
ls.on(&#x27;exit&#x27;, function (code) {
console.log(&#x27;child process exited with code &#x27; + code);
});
</pre>
</div>
<div class="span-one-third">
<h3>Custom Emitter</h3>
<p>You can roll your own custom EventEmitter event. It's easy. When to do this, vs. subclass the EventEmitter object, is open for discussion. See the next example for more on this.</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example2-events.js">example2-events.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, events.js, and run it: <code>node events.js</code>.</p>
<pre class="prettyprint linenums">
//
// Helpful resource and some inspiration here:
// http://elegantcode.com/2011/02/21/taking-baby-steps-with-node-js-implementing-events/
//
var events = require(&#x27;events&#x27;);
var eventEmitter = new events.EventEmitter();
eventEmitter.on(&#x27;gameover&#x27;, function(finalscore) {
// We could handle end of game scenarios at this point
console.log(JSON.stringify(finalscore));
});
// Later in your code, or you can emit an event
eventEmitter.emit(&#x27;gameover&#x27;, {&#x27;score&#x27;: {&#x27;red&#x27;: &#x27;3&#x27;, &#x27;blue&#x27;: &#x27;5&#x27;}, &#x27;status&#x27;: &#x27;blue wins&#x27;});
</pre>
</div>
<div class="span-one-third">
<h3>Subclassing the EventEmitter object</h3>
<p>There is an open choice as to whether or not to subclass the EventEmitter object or to just screate your own custom events. It comes down to what you are trying to do. If you are creating a new module from scratch that needs to emit events in Node.js 'style', it makes sence to go through the process of subclassing EventEmitter. You will need to dig through the docs a bit to get a feel for the how, and of course, bring your JSfu. This example is completely contrived. <span class="label">Exercise is to pretend you have a machine that discovers alien life every so often, call it ITES, and it is using a huge array of telescopes and radars to discover aliens. And it does a good job, and emits occurences of alien life discovery in your lifetime :).</span></p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example3-events.js">example3-events.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. To run it on your server, hit the local server instance running on http://yourserverip:yourlabport. On your own laptop, you can simply put this into a file, events.js, and run it: <code>node events.js</code>.</p>
<pre class="prettyprint linenums">
var EventEmitter = process.EventEmitter;
var ITES = exports.ITES = function(seed) {
this.seed = seed;
console.log(&#x27;ITES constructor&#x27;);
}
ITES.prototype.__proto__ = EventEmitter.prototype;
ITES.prototype.sendReportToStarCommand = function() {
console.log(&#x27;found aliens&#x27;);
this.emit(&#x27;foundaliens&#x27;, { &#x27;type&#x27;: &#x27;zergs&#x27;, &#x27;coordinates&#x27;: { &#x27;x&#x27;: Math.random()*this.seed%1000000, &#x27;y&#x27;: Math.random()*this.seed%1000000, &#x27;z&#x27;: Math.random()*this.seed%1000000}});
}
// Start a search for alien life.
// alienfilter (optional) - discard any results that match alienfilter
// timeout (optional) - Number of Milliseconds to run, if not present, run forever
ITES.prototype.findAliens = function(alienfilter, timeout) {
var probability = 0.19; // % chance of finding an alien
var working = true;
var diceroll;
if (timeout) {
console.log(&#x27;Setting timeout for &#x27; + timeout/1000 + &#x27; seconds&#x27;);
setTimeout(function() {
working = false;
console.log(&#x27;Done searching for aliens after &#x27; + timeout/1000 + &#x27; seconds&#x27;);
}, timeout);
}
console.log(&#x27;findAliens now, estimated probability is &#x27; + probability*100 + &#x27; %&#x27;);
// XXX Don&#x27;t ever do things this way, this is just to get a quick and dirty example, please forgive me
while(working) {
for (var i = 0; i &lt; 100000000; i++) {
diceroll = Math.random();
}
console.log(&#x27;diceroll is &#x27; + diceroll);
if (diceroll &lt;= probability) {
this.sendReportToStarCommand();
}
console.log(new Date() + &#x27; - Any aliens yet?&#x27;);
}
console.log(&quot;Done searching for aliens, goodbye&quot;);
}
var itesinstance = new ITES(1231244909);
itesinstance.on(&#x27;foundaliens&#x27;, function(report) {
console.log(&#x27;Your ITES tax dollars at work ...&#x27;);
console.log(JSON.stringify(report));
});
itesinstance.findAliens(&#x27;protoss&#x27;);
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 12 - Data Persistence - Simple, Fast (but lossy), or Reliable
================================================== -->
<section id="12">
<div class="page-header">
<h1>Data Persistence <small> - Simple, Fast (but lossy), or Reliable</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Example 1 - Simple, Slow - SQlite</h3>
<p>SQLite is an engineering marvel. Spend some time and look at the source code. It's a small Virtual Machine. The code is broken up into a series of small, very modular C files. The "build" puts these files together into a single 100K or so file that is easy to compile and nearly dependency free. The resulting binary is small. The SQL syntax is EZ. It's built into browser, phones, and maybe even on your desktop. For Node.js, SQLite isn't a great match, given performance characteristics of SQLite. But for starting out, it's the easiest SQL oriented server to set up or embed. SQLite is an engineering marvel. Spend some time and look at the source code. It's a small Virtual Machine. The code is broken up into a series of small, very modular C files. The "build" puts these files together into a single 100K or so file that is easy to compile and nearly dependency free. The resulting binary is small. The SQL syntax is EZ.
</p>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example1-db.js">example1-db.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. On your own laptop, you can simply put this into a file, db.js, and run it: <code>node db.js</code>.</p>
<pre class="prettyprint linenums">
var Store = require(&#x27;supermarket&#x27;);
var sys = require(&#x27;sys&#x27;);
// This is a wrapper around SQLite
// If you are curious, take a look at the node-supermarket project on Github
// and look at the package.json.
Store(&#x27;my.db&#x27;, function(error, db) {
db.set(&#x27;pkrumins&#x27;, &#x27;rocks&#x27;, function(error) {
sys.log(&#x27;Now we just stored some data&#x27;);
db.get(&#x27;pkrumins&#x27;, function(error, value, key) {
sys.log(&#x27;Are these the values you are looking for, pkrumins: &#x27; + value);
});
});
sys.log(&#x27;And now we shall carry about our business&#x27;);
});
</pre>
</div>
<div class="span-one-third">
<h3>Example 2 - Fast, Unreliable</h3>
<p>SQLite is a great place to start, and it's nice to have something that feels Node-ish. We can do better though. You don't want to use SQLite for anything beyond toy code or if you are stuck in a disconnected browser. Node.js is really best 'paired' with a NOSQL database. Pick your poison. There are a lot of options. The databases that stand out are (in order):</p>
<ul>
<li>Redis</li>
<li>MongoDB</li>
<li>CouchDBli>
</ul>
<h3>Try it out</h3>
<p>To try it out, copy the code from <a href="example2-db.js">example2-db.js</a> into the file called lab.js (it's ok to blow away everything that's in there), set the port by changing the value of <span class="label important">yourlabport</span> and save. On your own laptop, you can simply put this into a file, db.js, and run it: <code>node db.js</code>.</p>
<pre class="prettyprint linenums">
var redis = require(&quot;redis&quot;),
clientA = redis.createClient(6379, &#x27;127.0.0.1&#x27;, {}), // Use the host IP offered by your instructor
mydata = {&#x27;book&#x27;: &#x27;1984&#x27;, &#x27;author&#x27;: &#x27;Orwell&#x27;, &#x27;year&#x27;: &#x27;1948&#x27;}; // Sample JSON data
clientA.on(&quot;error&quot;, function(err) {
console.log(&quot;Error was: &quot; + err);
});
clientA.HMSET(&#x27;423.53&#x27;, mydata, function() { // Wow, you can push JSON right in, callback is optional
console.log(&#x27;Done setting data&#x27;);
clientA.hgetall(&#x27;423.53&#x27;, function(err, obj) {
console.dir(obj);
});
});
</pre>
</div>
<div class="span-one-third">
<h3>Example 3 - Reliable, Synchronous</h3>
<p>Most developers already have a huge investment in traditional SQL databases. These NoSQL and Object DBs are still a bit of novelty in the enterprise. That may change. You will still likely need an interface into your legacy database systems. You can use the 'mysql' module to get yourself access to the world of mysql. Since this 'pairing' doesn't go well with Node.js heritage, I will just reference a small code snippet. You can try it out as you please.</p>
<pre class="prettyprint linenums">
var mysql = require(&#x27;mysql&#x27;);
var client = mysql.createClient({
user: &#x27;mysql&#x27;,
password: &#x27;strongpassword&#x27;
});
client.query(&#x27;USE mysql&#x27;); // A simple command, select the default db
</pre>
</div>
</div><!-- /row -->
</section>
<!-- Slide 13 - Testing It
================================================== -->
<section id="13">
<div class="page-header">
<h1>Testing It <small> - you got to check yo' self, before you wreck someone else </small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Topic is too huge to cover today</h3>
<p><span class="label important">Under Contruction</span> There is no way I can do this topic justice in a few hours. Not even in a day. And there are people, wierd sort of like developer types who actually test first. And iterate. So rather than tease you with something I myself should do more of, I'll give you a raincheck. We need to host a full day of testing techniques to cover Node, JS, TDD, BDD, and every little buzzword you can put together.</p>
</div>
<div class="span-two-thirds">
<h3>A Good Starting Point</h3>
<ul>
<li>QUnit - Frankly, they live TDD with some rediculous # of tests built just to test JQuery. So take a look at what they are doing first</li>
<li>Foounit - mocking, async, CI, suites</li>
<li>Jasmine - TDD gold standard</li>
<li>Zombie - headless browser testing, scawy!</li>
<li>Vows - async BDD</li>
</ul>
</div>
</div><!-- /row -->
</section>
<!-- Slide 14 - Performance &amp; Scaling
================================================== -->
<section id="14">
<div class="page-header">
<h1>Performance &amp; Scaling <small>(Node scales right?)</small></h1>
</div>
<div class="row">
<div class="span-two-thirds">
<h3>Yes and No</h3>
<p>Let's get one thing clear. Node.js isn't faster than <em>_X_</em> and doesn't scale better than <em>_Y_</em>. Node.js has characteristics which lend itself well to "realtime" web application development, and out of the box, it does perform pretty well, scaling up very nicely ... to a point. While you can rely on your event loop heavily and "forget" about concurrency to some degree, you still have to worry about memory utilization, reliability, failover, disk i/o, CPU utilization, session recovery, failover, and, well, basically everything you have to worry about whether you do Java, Haskell, Erlang, Ruby, or PHP. So it isn't enough to just say Node.js scales well, and be suspicious of anyone who says that and mentions "awesome" in the same breath. Uh, I am guilty...</p>
</div>
<div class="span-one-third">
<h3>How To Scale</h3>
<p>Send me $19.95 and I will send you my secret recipe. Just kidding. This is another huge topic, and frankly, the platform is in very early stages (barely 3). My one suggestion: Hire a good ops person. They will know what to do. You of course must be performance minded and worry about shaving milliseconds here and there, and you still have to make your client side well behaved so that the user perceives the application is snappy and performant</p>
</div>
</div><!-- /row -->
</section>
<!-- Slide 15 - Debugging
================================================== -->
<section id="15">
<div class="page-header">
<h1>Debugging <small>(or falling off a ladder and landing on your feet)</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Tools</h3>
<p>Sorry, there is only one tool: vi. Seriously, there aren't many tools for Node.js. The usual collection of profilers, IDEs, debuggers, text editors with built in completion, and code lint, don't exist in a cohesive, well integrated way. You will need to wait a bit longer for these things to emerge. When the enterprise adopts Node.js (let's say IBM starts providing Node.js services), then you'll start to see more serious tools. For now, try out Cloud 9 IDE or something like NIDE (which I demonstrated here).
<div class="span-two-thirds">
<h3>Strategies</h3>
<p>If you are doing web development, actively, you have likely developed some strategies for debugging your work. There is no single thing that works all of the time. I like to say debugging web apps is like falling off a ladder, or worse, having it yanked out from under you (a very disconcerting feeling). Finding your way back to the ground involves falling, maybe crashing, but crashing gracefully, and then getting back up again. Your favorite tools like Firebug are still useful for Node.js. But Node itself has a way to go. It has a debugger, but there isn't the tools integration. If you are used to doing stepwise debugging in VS, it's just not there yet. Be patient. I am still in this learning phase where I am trying myself to learn the best strategies for debugging my Node.js apps so I can get reasonable line number reporting when exceptions occur, in stead of bubbling up the exception to a point where you've lost the context of why it happened.
</div>
</div><!-- /row -->
</section>
<!-- TEMPLATE 59 lines
================================================== -->
<!--
<section id="template">
<div class="page-header">
<h1>About Bootstrap <small>Brief history, browser support, and more</small></h1>
</div>
<div class="row">
<div class="span-one-third">
<h3>Point 1</h3>
<p>Engineers at Twitter have historically used almost any library they were familiar with to meet front-end requirements. Bootstrap began as an answer to the challenges that presented. With the help of many awesome folks, Bootstrap has grown significantly.</p>
<p>Read more on <a href="https://dev.twitter.com/blog/bootstrap-twitter">dev.twitter.com &rsaquo;</a></p>
<p>
<a href="http://twitter.com/twbootstrap" class="twitter-follow-button">Follow @twbootstrap</a>
<script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script>
</p>
</div>
<div class="span-one-third">
<h3>Point 2</h3>
<p>Bootstrap is tested and supported in major modern browsers like Chrome, Safari, Internet Explorer, and Firefox.</p>
<img src="images/browsers.png" alt="Tested and supported in Chrome, Safari, Internet Explorer, and Firefox">
<ul>
<li>Latest Safari</li>
<li>Latest Google Chrome</li>
<li>Firefox 4+</li>
<li>Internet Explorer 7+</li>
<li>Opera 11</li>
</ul>
</div>
<div class="span-one-third">
<h3>Point 3</h3>
<p>Bootstrap comes complete with compiled CSS, uncompiled, and example templates.</p>
<ul>
<li><span class="label">New in 1.3</span> <a href="./javascript.html">Javascript plugins</a></li>
<li>All original .less files</li>
<li>Fully <a href="../bootstrap.css">compiled</a> and <a href="../bootstrap.min.css">minified</a> CSS</li>
<li>Complete styleguide documentation</li>
<li>Three example pages with different layouts</li>
</ul>
</div>
</div><!-- /row -->
<div class="row">
<div class="span12">
<h3>Examples</h3>
<p>Need some quick templates? Check out these basic examples we've put together:</p>
<ul class="media-grid">
<li>
<a href="../examples/hero.html"><img src="images/example-diagram-01.png" alt="Simple three-column layout with hero unit"></a>
</li>
<li>
<a href="../examples/fluid.html"><img src="images/example-diagram-02.png" alt="Fluid layout with static sidebar"></a>
</li>
<li>
<a href="../examples/container-app.html"><img src="images/example-diagram-03.png" alt="Simple hanging container for apps"></a>
</li>
</ul>
</div>
</div><!-- /row -->
</section>
-->
</div><!-- /container --><!-- Don't delete this or you will feel pain -->
<footer class="footer">
<div class="container">
<p class="pull-right"><a href="#">Back to top</a></p>
<p>
Site built using Bootstrap (<a href="http://twitter.com/twitter" target="_blank">@twitter</a> by <a href="http://twitter.com/mdo" target="_blank">@mdo</a> and <a href="http://twitter.com/fat" target="_blank">@fat</a>).<br />
Node.js Code &amp; Presentation licensed under the <a href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank">CC-BY-SA</a> unless cited otherwise.
</p>
</div>
</footer>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.2.min.js"><\/script>')</script>
<!-- <script src="http://autobahn.tablesorter.com/jquery.tablesorter.min.js"></script> -->
<script src="js/libs/google-code-prettify/prettify.js"></script>
<script>$(function () { prettyPrint() })</script>
<script src="js/libs/bootstrap-dropdown.js"></script>
<script src="js/libs/bootstrap-twipsy.js"></script>
<script src="js/libs/bootstrap-scrollspy.js"></script>
<script src="js/application.js"></script>
<!-- <script src="/socket.io/socket.io.js" type="text/javascript"></script> -->
<script src="js/libs/smoothie.js"></script>
<!-- scripts concatenated and minified via ant build script-->
<script src="js/plugins.js"></script>
<script src="js/script.js"></script>
<!-- end scripts-->
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.