Your SlideShare is downloading. ×
0
INTRO TO NODE.JS- L E V E L O N E -
INTRO TO NODE.JS
WHAT IS NODE.JS?
It’s fast because it’s mostly C code
Allows you to build scalable network
applications u...
INTRO TO NODE.JS
WHAT COULD YOU BUILD?
• Websocket Server
• Fast File Upload Client
• Ad Server
• Any Real-Time Data Apps
...
INTRO TO NODE.JS
WHAT IS NODE.JS NOT?
• A Web Framework
• For Beginners It’s very low level
• Multi-threaded
You can think...
INTRO TO NODE.JS
OBJECTIVE: PRINT FILE CONTENTS
This is a “Callback”
Read file from Filesystem, set equal to “contents”
Pr...
console.log(contents);
INTRO TO NODE.JS
BLOCKING VS NON-BLOCKING
var contents = fs.readFileSync('/etc/hosts');
console.log...
fs.readFile('/etc/hosts', function(err, contents) {
console.log(contents);
});
INTRO TO NODE.JS
CALLBACK ALTERNATE SYNTAX
...
INTRO TO NODE.JS
BLOCKING VS NON-BLOCKING
blocking
0s
non-blocking
10s5s
0s 10s5s
fs.readFile('/etc/hosts', callback);
fs....
hello.js
NODE.JS HELLO DOG
$ curl http://localhost:8080
Hello, this is dog.
How we require modules
Status code in header
R...
THE EVENT LOOP
var http = require('http');
http.createServer(function(request, response) {
}).listen(8080);
console.log('L...
INTRO TO NODE.JS
WHY JAVASCRIPT?
“JavaScript has certain characteristics that make it very
different than other dynamic la...
THE EVENT LOOP
Known Events
requestChecking
for
Events
connection
close
Event Queue
close
request
Events processed one at ...
INTRO TO NODE.JS
WITH LONG RUNNING PROCESS
Represent long running process
var http = require('http');
http.createServer(fu...
INTRO TO NODE.JS
TWO CALLBACKS HERE
var http = require('http');
http.createServer(function(request, response) {
response.w...
TWO CALLBACKS TIMELINE
0s 10s5s
Request comes in, triggers request event
Request Callback executes
setTimeout registered
R...
WITH BLOCKING TIMELINE
0s 10s5s
Request comes in, triggers request event
Request Callback executes
setTimeout executed
Req...
INTRO TO NODE.JS
• Calls out to web services
TYPICAL BLOCKING THINGS
• Reads/Writes on the Database
• Calls to extensions
EVENTS- L E V E L T W O -
EVENTS
EVENTS IN THE DOM
The DOM
The DOM triggers Events
click
events
you can listen for those events
submit
hover
When ‘c...
EVENTS
EVENTS IN NODE
EventEmitter
Many objects in Node emit events
net.Server
request
event
EventEmitter
fs.readStream
da...
EVENTS
CUSTOM EVENT EMITTERS
var logger = new EventEmitter();
logger.emit('error', 'Spilled Milk');
ERR: Spilled Milk
logg...
EVENTS
EVENTS IN NODE
EventEmitter
Many objects in Node emit events
net.Server
request
event
When ‘request’ event is emitt...
EVENTS
HTTP ECHO SERVER
http.createServer(function(request, response){ ... });
But what is really going on here?
http://no...
EVENTS
BREAKING IT DOWN
http.createServer(function(request, response){ ... });
http.createServer(function(request, response){ ... });
EVENTS
ALTERNATE SYNTAX
var server = http.createServer();
function(...
STREAMS- L E V E L T H R E E -
S T R E A M S
WHAT ARE STREAMS?
Start Processing
Immediately
Streams can be readable, writeable, or both
S T R E A M S
STREAMING RESPONSE
Our clients receive "Dog is running."
"Dog is done."
(5 seconds later)
http.createServer(...
S T R E A M S
HOW TO READ FROM THE REQUEST?
EventEmitter
Readable Stream data
events
emit
Lets print what we receive from ...
S T R E A M S
LETS CREATE AN ECHO SERVER
http.createServer(function(request, response) {
request.on('data', function(chunk...
S T R E A M S
LETS CREATE AN ECHO SERVER!
http.createServer(function(request, response) {
}).listen(8080)
request.pipe(res...
S T R E A M S
READING AND WRITING A FILE
var fs = require('fs');
var file = fs.createReadStream("readme.md");
var newFile ...
S T R E A M S
UPLOAD A FILE
var fs = require('fs');
var newFile = fs.createWriteStream("readme_copy.md");
var http = requi...
THE AWESOME STREAMING
client storage
server
original file
transferred file
non-blocking
0s 10s5s
BACK PRESSURE!
client storage
server
original file
transferred file
Writable stream slower
than readable stream
Using pipe...
THINK OF A MILK JUG
milkStream.pause();
milkStream.resume();
});
Once milk jug is drained
PIPE SOLVES BACKPRESSURE
readStream.resume();
});
Pause when writeStream is full
writeStream.on('drain', function(){
readS...
S T R E A M S
FILE UPLOADING PROGRESS
S T R E A M S
FILE UPLOADING PROGRESS
$ curl --upload-file file.jpg http://localhost:8080
progress: 3%
progress: 6%
progre...
S T R E A M S
DOCUMENTATION http://nodejs.org/api/
Stability Scores
S T R E A M S
REMEMBER THIS CODE?
var fs = require('fs');
var newFile = fs.createWriteStream("readme_copy.md");
var http =...
S T R E A M S
REMEMBER THIS CODE?
var newFile = fs.createWriteStream("readme_copy.md");
http.createServer(function(request...
S T R E A M S
SHOWING PROGRESS
MODULES- L E V E L F O U R -
MODULES
REQUIRING MODULES
http.js
How does it find these files?
var http = require('http');
var fs = require('fs'); fs.js
...
MODULES
LETS CREATE OUR OWN MODULE
custom_hello.js custom_goodbye.js
app.js
exports = hello;
var hello = require('./custom...
MODULES
EXPORT MULTIPLE FUNCTIONS
my_module.js
app.js
var foo = function() { ... }
var bar = function() { ... }
exports.fo...
MODULES
MAKING HTTP REQUESTS
app.js
logs response body
begins request
var http = require('http');
var options = {
host: 'l...
MODULES
ENCAPSULATING THE FUNCTION
app.jsvar http = require('http');
var makeRequest = function(message) {
var options = {...
MODULES
CREATING & USING A MODULE
make_request.jsvar http = require('http');
var makeRequest = function(message) {
}
expor...
MODULES
REQUIRE SEARCH
var make_request = require('make_request')
/Home/eric/my_app/app.js
• /Home/eric/my_app/node_module...
MODULES
NPM: THE USERLAND SEA
Package manager for node
• Comes with node
• Module Repository
• Dependency Management
• Eas...
MODULES
INSTALLING A NPM MODULE
$ npm install request https://github.com/mikeal/request
In /Home/my_app
Home my_app reques...
MODULES
LOCAL VS GLOBAL
Global npm modules can’t be required
$ npm install coffee-script -g
Install modules with executabl...
MODULES
FINDING MODULES
npm registry
$ npm search request
npm command line
github search
toolbox.no.de
MODULES
DEFINING YOUR DEPENDENCIES
my_app/package.json
version number
$ npm install
my_app connectnode_modules
Installs in...
MODULES
DEPENDENCIES
my_app connectnode_modules
Installs sub-dependencies
connect node_modules qs
connect node_modules mim...
MODULES
SEMANTIC VERSIONING
"connect": "1.8.7" 1 8 7
Major Minor Patch
. .
http://semver.org/
"connect": "~1.8.7" >=1.8.7 ...
EXPRESS- L E V E L F I V E -
EXP RESS
EXPRESS
“Sinatra inspired web development framework for Node.js --
insanely fast, flexible, and simple”
• Easy ro...
EXP RESS
INTRODUCING EXPRESS
$ npm install express
var express = require('express');
var app = express.createServer();
app...
EXP RESS
EXPRESS ROUTES
app.js
route definition
get the last 10 tweets for screen_name
pipe the request to response
var re...
EXP RESS
EXPRESS ROUTES
EXP RESS
EXPRESS + HTML
EXP RESS
EXPRESS TEMPLATES
app.js
tweets.ejs
app.get('/tweets/:username', function(req, response) {
...
request(url, funct...
EXP RESS
EXPRESS TEMPLATES
EXP RESS
TEMPLATE LAYOUTS
<!DOCTYPE html>
<html>
<head>
<title>Tweets</title>
</head>
<body>
<%- body %>
</body>
</html>
<...
EXP RESS
EXPRESS TEMPLATES
SOCKET.IO- L E V E L S I X -
SOCKET.IO
CHATTR
SOCKET.IO
WEBSOCKETS
browser traditional server
Traditional request/response cycle
Using duplexed websocket connection
SOCKET.IO
WEBSOCKETS
browser socket.io
SOCKET.IO
SOCKET.IO FOR WEBSOCKETS
var socket = require('socket.io');
var app = express.createServer();
var io = socket.li...
SOCKET.IO
SENDING MESSAGES TO CLIENT
io.sockets.on('connection', function(client) {
});
console.log('Client connected...')...
SOCKET.IO
CHATTR HELLO WORLD
SOCKET.IO
SENDING MESSAGES TO SERVER
io.sockets.on('connection', function(client) {
});
var server = io.connect('http://lo...
SOCKET.IO
CHATTR HELLO WORLD
SOCKET.IO
BROADCASTING MESSAGES
clients
server
app.js
socket.broadcast.emit("message", 'Hello');
SOCKET.IO
BROADCASTING MESSAGES
io.sockets.on('connection', function(client) {
});
<script>
</script>
app.js
index.html
cl...
SOCKET.IO
BROADCASTING MESSAGES
SOCKET.IO
SAVING DATA ON THE SOCKET
io.sockets.on('connection', function(client) {
});
var server = io.connect('http://loc...
SOCKET.IO
SAVING DATA ON THE CLIENT
io.sockets.on('connection', function(client) {
});
app.js
client.on('join', function(n...
SOCKET.IO
SAVING DATA ON THE CLIENT
PERSISTING DATA- L E V E L S E V E N -
P E R S I S T I N G D A T A
RECENT MESSAGES
});
});
});
P E R S I S T I N G D A T A
RECENT MESSAGES
io.sockets.on('connection', function(client) {
client.on('join', f...
});
});
});
P E R S I S T I N G D A T A
STORING MESSAGES
io.sockets.on('connection', function(client) {
client.on("message...
P E R S I S T I N G D A T A
EMITTING MESSAGES
io.sockets.on('connection', function(client) {
});
app.js
client.on('join', ...
P E R S I S T I N G D A T A
RECENT MESSAGES
P E R S I S T I N G D A T A
PERSISTING STORES
• MongoDB
• CouchDB
• PostgreSQL
• Memcached
• Riak
All non-blocking!
Redis ...
P E R S I S T I N G D A T A
REDIS DATA STRUCTURES
Strings SET, GET, APPEND, DECR, INCR...
Hashes HSET, HGET, HDEL, HGETALL...
P E R S I S T I N G D A T A
REDIS COMMAND DOCUMENTATION
P E R S I S T I N G D A T A
NODE REDIS
client.get("message1", function(err, reply){
console.log(reply);
});
P E R S I S T I N G D A T A
REDIS
key value
"hello, y...
P E R S I S T I N G D A T A
REDIS LISTS: PUSHING
Add a string to the “messages” list
client.lpush("messages", message, fun...
P E R S I S T I N G D A T A
REDIS LISTS: RETRIEVING
Using LPUSH & LTRIM
trim keeps first two strings
and removes the rest
...
P E R S I S T I N G D A T A
CONVERTING MESSAGES TO REDIS
var storeMessage = function(name, data){
messages.push({name: nam...
P E R S I S T I N G D A T A
CONVERTING STOREMESSAGE
var storeMessage = function(name, data){
}
var redisClient = redis.cre...
P E R S I S T I N G D A T A
OUTPUT FROM LIST
client.on('join', function(name) {
});
messages.forEach(function(message) {
c...
P E R S I S T I N G D A T A
OUTPUT FROM LIST
client.on('join', function(name) {
});
messages.forEach(function(message) {
c...
P E R S I S T I N G D A T A
IN ACTION
P E R S I S T I N G D A T A
CURRENT CHATTER LIST
Sets are lists of unique data
client.sadd("names", "Dog");
client.sadd("n...
P E R S I S T I N G D A T A
ADDING CHATTERS
client.on('join', function(name){
client.broadcast.emit("add chatter", name);
...
P E R S I S T I N G D A T A
ADDING CHATTERS (CONT)
client.on('join', function(name){
client.broadcast.emit("add chatter", ...
P E R S I S T I N G D A T A
REMOVING CHATTERS
client.on('disconnect', function(name){ app.js
index.html
client.get('nickna...
P E R S I S T I N G D A T A
WELCOME TO CHATTR
About Node.js
Upcoming SlideShare
Loading in...5
×

About Node.js

1,511

Published on

Published in: Technology, Business

Transcript of "About Node.js"

  1. 1. INTRO TO NODE.JS- L E V E L O N E -
  2. 2. INTRO TO NODE.JS WHAT IS NODE.JS? It’s fast because it’s mostly C code Allows you to build scalable network applications using JavaScript on the server-side. V8 JavaScript Runtime Node.js
  3. 3. INTRO TO NODE.JS WHAT COULD YOU BUILD? • Websocket Server • Fast File Upload Client • Ad Server • Any Real-Time Data Apps Like a chat server
  4. 4. INTRO TO NODE.JS WHAT IS NODE.JS NOT? • A Web Framework • For Beginners It’s very low level • Multi-threaded You can think of it as a single threaded server
  5. 5. INTRO TO NODE.JS OBJECTIVE: PRINT FILE CONTENTS This is a “Callback” Read file from Filesystem, set equal to “contents” Print contents • Blocking Code • Non-Blocking Code Do something else Read file from Filesystem whenever you’re complete, print the contents Do Something else
  6. 6. console.log(contents); INTRO TO NODE.JS BLOCKING VS NON-BLOCKING var contents = fs.readFileSync('/etc/hosts'); console.log(contents); console.log('Doing something else'); • Blocking Code • Non-Blocking Code console.log('Doing something else'); Stop process until complete fs.readFile('/etc/hosts', function(err, contents) { });
  7. 7. fs.readFile('/etc/hosts', function(err, contents) { console.log(contents); }); INTRO TO NODE.JS CALLBACK ALTERNATE SYNTAX var callback = function(err, contents) { console.log(contents); } fs.readFile('/etc/hosts', callback); Same as
  8. 8. INTRO TO NODE.JS BLOCKING VS NON-BLOCKING blocking 0s non-blocking 10s5s 0s 10s5s fs.readFile('/etc/hosts', callback); fs.readFile('/etc/inetcfg', callback); var callback = function(err, contents) { console.log(contents); }
  9. 9. hello.js NODE.JS HELLO DOG $ curl http://localhost:8080 Hello, this is dog. How we require modules Status code in header Response body Close the connection Listen for connections on this port $ node hello.js Run the server var http = require('http'); http.createServer(function(request, response) { response.writeHead(200); response.write("Hello, this is dog."); response.end(); }).listen(8080); console.log('Listening on port 8080...'); Listening on port 8080...
  10. 10. THE EVENT LOOP var http = require('http'); http.createServer(function(request, response) { }).listen(8080); console.log('Listening on port 8080...'); Starts the Event Loop when finished ... Known Events request Checking for Events Run the Callback
  11. 11. INTRO TO NODE.JS WHY JAVASCRIPT? “JavaScript has certain characteristics that make it very different than other dynamic languages, namely that it has no concept of threads. Its model of concurrency is completely based around events.” - Ryan Dahl
  12. 12. THE EVENT LOOP Known Events requestChecking for Events connection close Event Queue close request Events processed one at a time
  13. 13. INTRO TO NODE.JS WITH LONG RUNNING PROCESS Represent long running process var http = require('http'); http.createServer(function(request, response) { }).listen(8080); response.writeHead(200); response.write("Dog is done."); response.end(); setTimeout(function(){ }, 5000); 5000ms = 5 seconds response.write("Dog is running.");
  14. 14. INTRO TO NODE.JS TWO CALLBACKS HERE var http = require('http'); http.createServer(function(request, response) { response.writeHead(200); request timeout }).listen(8080); response.write("Dog is done."); response.end(); setTimeout(function(){ }, 5000); response.write("Dog is running.");
  15. 15. TWO CALLBACKS TIMELINE 0s 10s5s Request comes in, triggers request event Request Callback executes setTimeout registered Request comes in, triggers request event Request Callback executes setTimeout registered triggers setTimeout event setTimeout Callback executes triggers setTimeout event setTimeout Callback request timeout
  16. 16. WITH BLOCKING TIMELINE 0s 10s5s Request comes in, triggers request event Request Callback executes setTimeout executed Request comes in, waits for server Request comes in triggers setTimeout event setTimeout Callback executed Wasted Time Request Callback executes
  17. 17. INTRO TO NODE.JS • Calls out to web services TYPICAL BLOCKING THINGS • Reads/Writes on the Database • Calls to extensions
  18. 18. EVENTS- L E V E L T W O -
  19. 19. EVENTS EVENTS IN THE DOM The DOM The DOM triggers Events click events you can listen for those events submit hover When ‘click’ event is triggered attach $("p").on("click", function(){ ... });
  20. 20. EVENTS EVENTS IN NODE EventEmitter Many objects in Node emit events net.Server request event EventEmitter fs.readStream data event
  21. 21. EVENTS CUSTOM EVENT EMITTERS var logger = new EventEmitter(); logger.emit('error', 'Spilled Milk'); ERR: Spilled Milk logger.emit('error', 'Eggs Cracked'); var EventEmitter = require('events').EventEmitter; error warn info listen for error event logger.on('error', function(message){ console.log('ERR: ' + message); }); ERR: Eggs Cracked events
  22. 22. EVENTS EVENTS IN NODE EventEmitter Many objects in Node emit events net.Server request event When ‘request’ event is emitted function(request, response){ .. } emit attach
  23. 23. EVENTS HTTP ECHO SERVER http.createServer(function(request, response){ ... }); But what is really going on here? http://nodejs.org/api/
  24. 24. EVENTS BREAKING IT DOWN http.createServer(function(request, response){ ... });
  25. 25. http.createServer(function(request, response){ ... }); EVENTS ALTERNATE SYNTAX var server = http.createServer(); function(request, response){ ... });server.on('request', This is how we add Same as function(){ ... });server.on('close', add event listeners
  26. 26. STREAMS- L E V E L T H R E E -
  27. 27. S T R E A M S WHAT ARE STREAMS? Start Processing Immediately Streams can be readable, writeable, or both
  28. 28. S T R E A M S STREAMING RESPONSE Our clients receive "Dog is running." "Dog is done." (5 seconds later) http.createServer(function(request, response) { }).listen(8080); response.writeHead(200); response.write("Dog is done."); response.end(); setTimeout(function(){ }, 5000); response.write("Dog is running."); readable stream writable stream
  29. 29. S T R E A M S HOW TO READ FROM THE REQUEST? EventEmitter Readable Stream data events emit Lets print what we receive from the request. http.createServer(function(request, response) { request.on('data', function(chunk) { console.log(chunk.toString()); }); response.end(); }).listen(8080) request.on('end', function() { }); response.writeHead(200); end
  30. 30. S T R E A M S LETS CREATE AN ECHO SERVER http.createServer(function(request, response) { request.on('data', function(chunk) { }); response.end(); }).listen(8080) request.on('end', function() { }); response.writeHead(200); response.write(chunk); request.pipe(response);
  31. 31. S T R E A M S LETS CREATE AN ECHO SERVER! http.createServer(function(request, response) { }).listen(8080) request.pipe(response); $ curl -d 'hello' http://localhost:8080 Hello on client response.writeHead(200); cat 'bleh.txt' | grep 'something' Kinda like on the command line
  32. 32. S T R E A M S READING AND WRITING A FILE var fs = require('fs'); var file = fs.createReadStream("readme.md"); var newFile = fs.createWriteStream("readme_copy.md"); require filesystem module file.pipe(newFile);
  33. 33. S T R E A M S UPLOAD A FILE var fs = require('fs'); var newFile = fs.createWriteStream("readme_copy.md"); var http = require('http'); http.createServer(function(request, response) { request.pipe(newFile); }).listen(8080); $ curl --upload-file readme.md http://localhost:8080 uploaded! response.end('uploaded!'); request.on('end', function() { });
  34. 34. THE AWESOME STREAMING client storage server original file transferred file non-blocking 0s 10s5s
  35. 35. BACK PRESSURE! client storage server original file transferred file Writable stream slower than readable stream Using pipe solves this problem
  36. 36. THINK OF A MILK JUG milkStream.pause(); milkStream.resume(); }); Once milk jug is drained
  37. 37. PIPE SOLVES BACKPRESSURE readStream.resume(); }); Pause when writeStream is full writeStream.on('drain', function(){ readStream.on('data', function(chunk) { writeStream.write(chunk); }); var buffer_good = if (!buffer_good) readStream.pause(); returns false if kernel buffer full Resume when ready to write again readStream.pipe(writeStream); All encapsulated in
  38. 38. S T R E A M S FILE UPLOADING PROGRESS
  39. 39. S T R E A M S FILE UPLOADING PROGRESS $ curl --upload-file file.jpg http://localhost:8080 progress: 3% progress: 6% progress: 9% progress: 12% progress: 13% ... progress: 99% progress: 100% Outputs: • HTTP Server • File System We’re going to need:
  40. 40. S T R E A M S DOCUMENTATION http://nodejs.org/api/ Stability Scores
  41. 41. S T R E A M S REMEMBER THIS CODE? var fs = require('fs'); var newFile = fs.createWriteStream("readme_copy.md"); var http = require('http'); http.createServer(function(request, response) { request.pipe(newFile); }).listen(8080); response.end('uploaded!'); request.on('end', function() { });
  42. 42. S T R E A M S REMEMBER THIS CODE? var newFile = fs.createWriteStream("readme_copy.md"); http.createServer(function(request, response) { request.pipe(newFile); }).listen(8080); ... request.on('data', function(chunk) { uploadedBytes += chunk.length; var progress = (uploadedBytes / fileBytes) * 100; response.write("progress: " + parseInt(progress, 10) + "%n"); }); var uploadedBytes = 0; var fileBytes = request.headers['content-length'];
  43. 43. S T R E A M S SHOWING PROGRESS
  44. 44. MODULES- L E V E L F O U R -
  45. 45. MODULES REQUIRING MODULES http.js How does it find these files? var http = require('http'); var fs = require('fs'); fs.js How does ‘require’ return the libraries?
  46. 46. MODULES LETS CREATE OUR OWN MODULE custom_hello.js custom_goodbye.js app.js exports = hello; var hello = require('./custom_hello'); hello(); exports defines what require returns var hello = function() { console.log("hello!"); } exports.goodbye = function() { console.log("bye!"); } var gb = require('./custom_goodbye'); gb.goodbye(); require('./custom_goodbye').goodbye(); If we only need to call once
  47. 47. MODULES EXPORT MULTIPLE FUNCTIONS my_module.js app.js var foo = function() { ... } var bar = function() { ... } exports.foo = foo exports.bar = bar var myMod = require('./my_module'); myMod.foo(); myMod.bar(); my_module.js foo bar var baz = function() { ... } baz “private”
  48. 48. MODULES MAKING HTTP REQUESTS app.js logs response body begins request var http = require('http'); var options = { host: 'localhost', port: 8080, path: '/', method: 'POST' } var request = http.request(options, function(response){ response.on('data', function(data){ console.log(data); }); }); request.end(); request.write(message); finishes request var message = "Here's looking at you, kid.";
  49. 49. MODULES ENCAPSULATING THE FUNCTION app.jsvar http = require('http'); var makeRequest = function(message) { var options = { host: 'localhost', port: 8080, path: '/', method: 'POST' } var request = http.request(options, function(response){ response.on('data', function(data){ console.log(data); }); }); request.end(); } makeRequest("Here's looking at you, kid."); request.write(message); Text
  50. 50. MODULES CREATING & USING A MODULE make_request.jsvar http = require('http'); var makeRequest = function(message) { } exports = makeRequest; ... app.jsvar makeRequest = require('./make_request'); makeRequest("Here's looking at you, kid"); makeRequest("Hello, this is dog"); Where does require look for modules?
  51. 51. MODULES REQUIRE SEARCH var make_request = require('make_request') /Home/eric/my_app/app.js • /Home/eric/my_app/node_modules/ var make_request = require('./make_request') var make_request = require('../make_request') var make_request = require('/Users/eric/nodes/make_request') • /Home/eric/node_modules/make_request.js • /Home/node_modules/make_request.js • /node_modules/make_request.js look in same directory look in parent directory Search in node_modules directories
  52. 52. MODULES NPM: THE USERLAND SEA Package manager for node • Comes with node • Module Repository • Dependency Management • Easily publish modules • “Local Only” “Core” is small. “Userland” is large.
  53. 53. MODULES INSTALLING A NPM MODULE $ npm install request https://github.com/mikeal/request In /Home/my_app Home my_app requestnode_modules Installs into local node_modules directory var request = require('request'); In /Home/my_app/app.js Loads from local node_modules directory
  54. 54. MODULES LOCAL VS GLOBAL Global npm modules can’t be required $ npm install coffee-script -g Install modules with executables globally $ coffee app.coffee var coffee = require('coffee-script'); $ npm install coffee-script var coffee = require('coffee-script'); global Install them locally
  55. 55. MODULES FINDING MODULES npm registry $ npm search request npm command line github search toolbox.no.de
  56. 56. MODULES DEFINING YOUR DEPENDENCIES my_app/package.json version number $ npm install my_app connectnode_modules Installs into the node_modules directory { "name": "My App", "version": "1", "dependencies": { "connect": "1.8.7" } }
  57. 57. MODULES DEPENDENCIES my_app connectnode_modules Installs sub-dependencies connect node_modules qs connect node_modules mime connect node_modules formidable No conflicting modules! "dependencies": { "connect": "1.8.7" } my_app/package.json
  58. 58. MODULES SEMANTIC VERSIONING "connect": "1.8.7" 1 8 7 Major Minor Patch . . http://semver.org/ "connect": "~1.8.7" >=1.8.7 <1.9.0 Considered safe "connect": "~1.8" >=1.8 <2.0.0 API could change "connect": "~1" >=1.0.0 <2.0.0 Dangerous Ranges
  59. 59. EXPRESS- L E V E L F I V E -
  60. 60. EXP RESS EXPRESS “Sinatra inspired web development framework for Node.js -- insanely fast, flexible, and simple” • Easy route URLs to callbacks • Middleware (from Connect) • Environment based configuration • Redirection helpers • File Uploads
  61. 61. EXP RESS INTRODUCING EXPRESS $ npm install express var express = require('express'); var app = express.createServer(); app.get('/', function(request, response) { response.sendfile(__dirname + "/index.html"); }); app.listen(8080); $ curl http://localhost:8080/ > 200 OK root route current directory
  62. 62. EXP RESS EXPRESS ROUTES app.js route definition get the last 10 tweets for screen_name pipe the request to response var request = require('request'); var url = require('url'); app.get('/tweets/:username', function(req, response) { var username = req.params.username; options = { protocol: "http:", host: 'api.twitter.com', pathname: '/1/statuses/user_timeline.json', query: { screen_name: username, count: 10} } var twitterUrl = url.format(options); request(twitterUrl).pipe(response); });
  63. 63. EXP RESS EXPRESS ROUTES
  64. 64. EXP RESS EXPRESS + HTML
  65. 65. EXP RESS EXPRESS TEMPLATES app.js tweets.ejs app.get('/tweets/:username', function(req, response) { ... request(url, function(err, res, body) { var tweets = JSON.parse(body); response.render('tweets.ejs', {tweets: tweets, name: username}); }); }); <h1>Tweets for @<%= name %></h1> <ul> <% tweets.forEach(function(tweet){ %> <li><%= tweet.text %></li> <% }); %> </ul>
  66. 66. EXP RESS EXPRESS TEMPLATES
  67. 67. EXP RESS TEMPLATE LAYOUTS <!DOCTYPE html> <html> <head> <title>Tweets</title> </head> <body> <%- body %> </body> </html> <h1>Tweets for @<%= name %></h1> <ul> <% tweets.forEach(function(tweet){ %> <li><%= tweet.text %></li> <% }); %> </ul> tweets.ejs layout.ejs
  68. 68. EXP RESS EXPRESS TEMPLATES
  69. 69. SOCKET.IO- L E V E L S I X -
  70. 70. SOCKET.IO CHATTR
  71. 71. SOCKET.IO WEBSOCKETS browser traditional server Traditional request/response cycle
  72. 72. Using duplexed websocket connection SOCKET.IO WEBSOCKETS browser socket.io
  73. 73. SOCKET.IO SOCKET.IO FOR WEBSOCKETS var socket = require('socket.io'); var app = express.createServer(); var io = socket.listen(app); Abstracts websockets with fallbacks io.sockets.on('connection', function(client) { }); console.log('Client connected...'); <script src="/socket.io/socket.io.js"></script> var server = io.connect('http://localhost:8080'); <script> </script> $ npm install socket.io app.js index.html
  74. 74. SOCKET.IO SENDING MESSAGES TO CLIENT io.sockets.on('connection', function(client) { }); console.log('Client connected...'); <script src="/socket.io/socket.io.js"></script> var server = io.connect('http://localhost:8080'); <script> </script> app.js index.html client.emit('messages', { hello: 'world' }); server.on('messages', function (data) { }); alert(data.hello); emit the ‘messages’ event on the client listen for ‘messages’ events
  75. 75. SOCKET.IO CHATTR HELLO WORLD
  76. 76. SOCKET.IO SENDING MESSAGES TO SERVER io.sockets.on('connection', function(client) { }); var server = io.connect('http://localhost:8080'); <script> </script> app.js index.html client.on('messages', function (data) { }); console.log(data); $('#chat_form').submit(function(e){ var message = $('#chat_input').val(); socket.emit('messages', message); }); listen for ‘messages’ events emit the ‘messages’ event on the server
  77. 77. SOCKET.IO CHATTR HELLO WORLD
  78. 78. SOCKET.IO BROADCASTING MESSAGES clients server app.js socket.broadcast.emit("message", 'Hello');
  79. 79. SOCKET.IO BROADCASTING MESSAGES io.sockets.on('connection', function(client) { }); <script> </script> app.js index.html client.on('messages', function (data) { }); ... broadcast message to all other clients connected client.broadcast.emit("messages", data); server.on('messages', function(data) { insertMessage(data) }); insert message into the chat
  80. 80. SOCKET.IO BROADCASTING MESSAGES
  81. 81. SOCKET.IO SAVING DATA ON THE SOCKET io.sockets.on('connection', function(client) { }); var server = io.connect('http://localhost:8080'); <script> </script> app.js index.html client.on('join', function(name) { client.set('nickname', name); }); set the nickname associated with this client server.on('connect', function(data) { $('#status').html('Connected to chattr'); nickname = prompt("What is your nickname?"); server.emit('join', nickname); }); notify the server of the users nickname
  82. 82. SOCKET.IO SAVING DATA ON THE CLIENT io.sockets.on('connection', function(client) { }); app.js client.on('join', function(name) { client.set('nickname', name); }); set the nickname associated with this client client.on('messages', function(data){ }); client.broadcast.emit("chat", name + ": " + message); client.get('nickname', function(err, name) { }); get the nickname of this client before broadcasting message broadcast with the name and message
  83. 83. SOCKET.IO SAVING DATA ON THE CLIENT
  84. 84. PERSISTING DATA- L E V E L S E V E N -
  85. 85. P E R S I S T I N G D A T A RECENT MESSAGES
  86. 86. }); }); }); P E R S I S T I N G D A T A RECENT MESSAGES io.sockets.on('connection', function(client) { client.on('join', function(name) { client.set('nickname', name); client.broadcast.emit("chat", name + " joined the chat"); }); client.on("messages", function(message){ client.get("nickname", function(error, name) { client.broadcast.emit("messages", name + ": " + message); app.js
  87. 87. }); }); }); P E R S I S T I N G D A T A STORING MESSAGES io.sockets.on('connection', function(client) { client.on("messages", function(message){ client.get("nickname", function(error, name) { app.js storeMessage(name, message); var messages = []; store messages in array var storeMessage = function(name, data){ messages.push({name: name, data: data}); if (messages.length > 10) { messages.shift(); } } add message to end of array if more than 10 messages long, remove the last one when client sends a message call storeMessage
  88. 88. P E R S I S T I N G D A T A EMITTING MESSAGES io.sockets.on('connection', function(client) { }); app.js client.on('join', function(name) { }); messages.forEach(function(message) { client.emit("messages", message.name + ": " + message.data); }); iterate through messages array and emit a message on the connecting client for each one ...
  89. 89. P E R S I S T I N G D A T A RECENT MESSAGES
  90. 90. P E R S I S T I N G D A T A PERSISTING STORES • MongoDB • CouchDB • PostgreSQL • Memcached • Riak All non-blocking! Redis is a key-value store
  91. 91. P E R S I S T I N G D A T A REDIS DATA STRUCTURES Strings SET, GET, APPEND, DECR, INCR... Hashes HSET, HGET, HDEL, HGETALL... Lists LPUSH, LREM, LTRIM, RPOP, LINSERT... Sets SADD, SREM, SMOVE, SMEMBERS... Sorted Sets ZADD, ZREM, ZSCORE, ZRANK... data structure commands
  92. 92. P E R S I S T I N G D A T A REDIS COMMAND DOCUMENTATION
  93. 93. P E R S I S T I N G D A T A NODE REDIS
  94. 94. client.get("message1", function(err, reply){ console.log(reply); }); P E R S I S T I N G D A T A REDIS key value "hello, yes this is dog" var redis = require('redis'); var client = redis.createClient(); client.set("message1", "hello, yes this is dog"); client.set("message2", "hello, no this is spider"); commands are non-blocking $ npm install redis
  95. 95. P E R S I S T I N G D A T A REDIS LISTS: PUSHING Add a string to the “messages” list client.lpush("messages", message, function(err, reply){ console.log(reply); }); "1” var message = "Hello, no this is spider"; client.lpush("messages", message, function(err, reply){ console.log(reply); }); "2” replies with list length Add another string to “messages” var message = "Hello, this is dog";
  96. 96. P E R S I S T I N G D A T A REDIS LISTS: RETRIEVING Using LPUSH & LTRIM trim keeps first two strings and removes the rest Retrieving from list client.lrange("messages", 0, -1, function(err, messages){ console.log(messages); }) ["Hello, no this is spider", "Oh sorry, wrong number"] replies with all strings in list var message = "Oh sorry, wrong number"; client.lpush("messages", message, function(err, reply){ client.ltrim("messages", 0, 1); });
  97. 97. P E R S I S T I N G D A T A CONVERTING MESSAGES TO REDIS var storeMessage = function(name, data){ messages.push({name: name, data: data}); if (messages.length > 10) { messages.shift(); } } Let’s use the List data-structure app.js
  98. 98. P E R S I S T I N G D A T A CONVERTING STOREMESSAGE var storeMessage = function(name, data){ } var redisClient = redis.createClient(); var message = JSON.stringify({name: name, data: data}); redisClient.lpush("messages", message, function(err, response) { redisClient.ltrim("messages", 0, 10); }); keeps newest 10 items app.js need to turn object into string to store in redis
  99. 99. P E R S I S T I N G D A T A OUTPUT FROM LIST client.on('join', function(name) { }); messages.forEach(function(message) { client.emit("messages", message.name + ": " + message.data); }); app.js
  100. 100. P E R S I S T I N G D A T A OUTPUT FROM LIST client.on('join', function(name) { }); messages.forEach(function(message) { client.emit("messages", message.name + ": " + message.data); }); redisClient.lrange("messages", 0, -1, function(err, messages){ messages = messages.reverse(); message = JSON.parse(message); }); app.js reverse so they are emitted in correct order parse into JSON object
  101. 101. P E R S I S T I N G D A T A IN ACTION
  102. 102. P E R S I S T I N G D A T A CURRENT CHATTER LIST Sets are lists of unique data client.sadd("names", "Dog"); client.sadd("names", "Spider"); client.sadd("names", "Gregg"); client.srem("names", "Spider"); client.smembers("names", function(err, names){ console.log(names); }); ["Dog", "Gregg"] reply with all members of set add & remove members of the names set
  103. 103. P E R S I S T I N G D A T A ADDING CHATTERS client.on('join', function(name){ client.broadcast.emit("add chatter", name); redisClient.sadd("chatters", name); }); app.js notify other clients a chatter has joined add name to chatters set index.htmlserver.on('add chatter', insertChatter); var insertChatter = function(name) { var chatter = $('<li>'+name+'</li>').data('name', name); $('#chatters').append(chatter); }
  104. 104. P E R S I S T I N G D A T A ADDING CHATTERS (CONT) client.on('join', function(name){ client.broadcast.emit("add chatter", name); redisClient.sadd("chatters", name); }); app.js notify other clients a chatter has joined add name to chatters set emit all the currently logged in chatters to the newly connected client redisClient.smembers('names', function(err, names) { names.forEach(function(name){ client.emit('add chatter', name); }); });
  105. 105. P E R S I S T I N G D A T A REMOVING CHATTERS client.on('disconnect', function(name){ app.js index.html client.get('nickname', function(err, name){ client.broadcast.emit("remove chatter", name); redisClient.srem("chatters", name); }); }); remove chatter when they disconnect from server server.on('remove chatter', removeChatter); var removeChatter = function(name) { $('#chatters li[data-name=' + name + ']').remove(); }
  106. 106. P E R S I S T I N G D A T A WELCOME TO CHATTR
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×