SlideShare uma empresa Scribd logo
1 de 107
Baixar para ler offline
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 using JavaScript on the server-side.
V8 JavaScript Runtime
Node.js
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
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
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
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) {
});
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
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);
}
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...
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
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
THE EVENT LOOP
Known Events
requestChecking
for
Events
connection
close
Event Queue
close
request
Events processed one at a time
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.");
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.");
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
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
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 ‘click’ event is triggered
attach
$("p").on("click", function(){ ... });
EVENTS
EVENTS IN NODE
EventEmitter
Many objects in Node emit events
net.Server
request
event
EventEmitter
fs.readStream
data
event
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
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
EVENTS
HTTP ECHO SERVER
http.createServer(function(request, response){ ... });
But what is really going on here?
http://nodejs.org/api/
EVENTS
BREAKING IT DOWN
http.createServer(function(request, response){ ... });
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
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(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
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
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);
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
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);
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() {
});
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 solves this problem
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(){
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
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%
progress: 9%
progress: 12%
progress: 13%
...
progress: 99%
progress: 100%
Outputs:
• HTTP Server
• File System
We’re going to need:
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 = require('http');
http.createServer(function(request, response) {
request.pipe(newFile);
}).listen(8080);
response.end('uploaded!');
request.on('end', function() {
});
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'];
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
How does ‘require’ return the libraries?
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
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”
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.";
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
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?
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
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.
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
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
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 into the node_modules directory
{
"name": "My App",
"version": "1",
"dependencies": {
"connect": "1.8.7"
}
}
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
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
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 route URLs to callbacks
• Middleware (from Connect)
• Environment based configuration
• Redirection helpers
• File Uploads
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
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);
});
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, 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>
EXP RESS
EXPRESS TEMPLATES
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
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.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
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
SOCKET.IO
CHATTR HELLO WORLD
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
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
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
SOCKET.IO
BROADCASTING MESSAGES
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
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
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', 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
});
});
});
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
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
...
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 is a key-value store
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
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, 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
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";
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);
});
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
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
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
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
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("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
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);
}
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);
});
});
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();
}
P E R S I S T I N G D A T A
WELCOME TO CHATTR

Mais conteúdo relacionado

Mais procurados

How to stay sane during your Vagrant journey
How to stay sane during your Vagrant journeyHow to stay sane during your Vagrant journey
How to stay sane during your Vagrant journeyJakub Wadolowski
 
Automating the Network
Automating the NetworkAutomating the Network
Automating the NetworkPuppet
 
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоIaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоSigma Software
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.jsorkaplan
 
Consul - service discovery and others
Consul - service discovery and othersConsul - service discovery and others
Consul - service discovery and othersWalter Liu
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.jsjacekbecela
 
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetPuppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetMarc Cluet
 
Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)Timothy Appnel
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Reusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesReusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesYevgeniy Brikman
 
Puppet in the Pipeline
Puppet in the PipelinePuppet in the Pipeline
Puppet in the PipelinePuppet
 
AWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp VaultAWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp VaultGrzegorz Adamowicz
 
A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices Nebulaworks
 
Amazon EC2 Container Service in Action
Amazon EC2 Container Service in ActionAmazon EC2 Container Service in Action
Amazon EC2 Container Service in ActionRemotty
 
WebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! FrameworkWebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! FrameworkFabio Tiriticco
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabricandymccurdy
 
Controlling multiple VMs with the power of Python
Controlling multiple VMs with the power of PythonControlling multiple VMs with the power of Python
Controlling multiple VMs with the power of PythonYurii Vasylenko
 
Host Health Monitoring with Docker Run
Host Health Monitoring with Docker RunHost Health Monitoring with Docker Run
Host Health Monitoring with Docker RunNoah Zoschke
 

Mais procurados (20)

How to stay sane during your Vagrant journey
How to stay sane during your Vagrant journeyHow to stay sane during your Vagrant journey
How to stay sane during your Vagrant journey
 
Automating the Network
Automating the NetworkAutomating the Network
Automating the Network
 
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоIaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
Consul - service discovery and others
Consul - service discovery and othersConsul - service discovery and others
Consul - service discovery and others
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetPuppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and Puppet
 
Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Reusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesReusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modules
 
Puppet in the Pipeline
Puppet in the PipelinePuppet in the Pipeline
Puppet in the Pipeline
 
AWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp VaultAWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp Vault
 
Designing net-aws-glacier
Designing net-aws-glacierDesigning net-aws-glacier
Designing net-aws-glacier
 
A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices
 
Amazon EC2 Container Service in Action
Amazon EC2 Container Service in ActionAmazon EC2 Container Service in Action
Amazon EC2 Container Service in Action
 
WebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! FrameworkWebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! Framework
 
Docker in practice
Docker in practiceDocker in practice
Docker in practice
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabric
 
Controlling multiple VMs with the power of Python
Controlling multiple VMs with the power of PythonControlling multiple VMs with the power of Python
Controlling multiple VMs with the power of Python
 
Host Health Monitoring with Docker Run
Host Health Monitoring with Docker RunHost Health Monitoring with Docker Run
Host Health Monitoring with Docker Run
 

Semelhante a About Node.js

Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsRichard Lee
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
node.js: Javascript's in your backend
node.js: Javascript's in your backendnode.js: Javascript's in your backend
node.js: Javascript's in your backendDavid Padbury
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimizationxiaojueqq12345
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkAarti Parikh
 
Introduction to NodeJS with LOLCats
Introduction to NodeJS with LOLCatsIntroduction to NodeJS with LOLCats
Introduction to NodeJS with LOLCatsDerek Anderson
 
WebTalk - Implementing Web Services with a dedicated Java daemon
WebTalk - Implementing Web Services with a dedicated Java daemonWebTalk - Implementing Web Services with a dedicated Java daemon
WebTalk - Implementing Web Services with a dedicated Java daemonGeert Van Pamel
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...Tom Croucher
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareAlona Mekhovova
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.xYiguang Hu
 
Make BDD great again
Make BDD great againMake BDD great again
Make BDD great againYana Gusti
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...Tom Croucher
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Baruch Sadogursky
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA PresentationRob Tweed
 

Semelhante a About Node.js (20)

Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
node.js: Javascript's in your backend
node.js: Javascript's in your backendnode.js: Javascript's in your backend
node.js: Javascript's in your backend
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimization
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talk
 
Introduction to NodeJS with LOLCats
Introduction to NodeJS with LOLCatsIntroduction to NodeJS with LOLCats
Introduction to NodeJS with LOLCats
 
WebTalk - Implementing Web Services with a dedicated Java daemon
WebTalk - Implementing Web Services with a dedicated Java daemonWebTalk - Implementing Web Services with a dedicated Java daemon
WebTalk - Implementing Web Services with a dedicated Java daemon
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
NodeJS
NodeJSNodeJS
NodeJS
 
Make BDD great again
Make BDD great againMake BDD great again
Make BDD great again
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA Presentation
 
Rack
RackRack
Rack
 
Event driven programming -- Node.JS
Event driven programming -- Node.JSEvent driven programming -- Node.JS
Event driven programming -- Node.JS
 
NodeJS
NodeJSNodeJS
NodeJS
 

Mais de Artemisa Yescas Engler

Maestría en Ciencias de la Computación - Tec de Mty - Campus Guadalajara
Maestría en Ciencias de la Computación - Tec de Mty - Campus GuadalajaraMaestría en Ciencias de la Computación - Tec de Mty - Campus Guadalajara
Maestría en Ciencias de la Computación - Tec de Mty - Campus GuadalajaraArtemisa Yescas Engler
 
Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...
Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...
Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...Artemisa Yescas Engler
 
Reading Summary - Effective Software Defect Tracking + Pragmatic Unit Testing
Reading Summary - Effective Software Defect Tracking + Pragmatic Unit TestingReading Summary - Effective Software Defect Tracking + Pragmatic Unit Testing
Reading Summary - Effective Software Defect Tracking + Pragmatic Unit TestingArtemisa Yescas Engler
 
Reading Summary - Business Modeling + Peer Code Review + SW Inspections
Reading Summary - Business Modeling + Peer Code Review + SW InspectionsReading Summary - Business Modeling + Peer Code Review + SW Inspections
Reading Summary - Business Modeling + Peer Code Review + SW InspectionsArtemisa Yescas Engler
 
Reading Summary - Software Requirements + Characteristics of Well Written Req...
Reading Summary - Software Requirements + Characteristics of Well Written Req...Reading Summary - Software Requirements + Characteristics of Well Written Req...
Reading Summary - Software Requirements + Characteristics of Well Written Req...Artemisa Yescas Engler
 
Reading Summary - Agile Documentation + Continuous Integration
Reading Summary - Agile Documentation + Continuous IntegrationReading Summary - Agile Documentation + Continuous Integration
Reading Summary - Agile Documentation + Continuous IntegrationArtemisa Yescas Engler
 
Reading Summary - Software Agile Development + Scrum
Reading Summary - Software Agile Development + Scrum Reading Summary - Software Agile Development + Scrum
Reading Summary - Software Agile Development + Scrum Artemisa Yescas Engler
 
Reading Summary - Teamwork + Team Structure + Configuration Management
Reading Summary - Teamwork + Team Structure + Configuration ManagementReading Summary - Teamwork + Team Structure + Configuration Management
Reading Summary - Teamwork + Team Structure + Configuration ManagementArtemisa Yescas Engler
 
Reading Summary - Team Motivation + Software Lifecycles Models
Reading Summary - Team Motivation + Software Lifecycles ModelsReading Summary - Team Motivation + Software Lifecycles Models
Reading Summary - Team Motivation + Software Lifecycles ModelsArtemisa Yescas Engler
 

Mais de Artemisa Yescas Engler (9)

Maestría en Ciencias de la Computación - Tec de Mty - Campus Guadalajara
Maestría en Ciencias de la Computación - Tec de Mty - Campus GuadalajaraMaestría en Ciencias de la Computación - Tec de Mty - Campus Guadalajara
Maestría en Ciencias de la Computación - Tec de Mty - Campus Guadalajara
 
Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...
Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...
Reading Summary - Static Analysis to find Bugs & ROI Models for Static Analys...
 
Reading Summary - Effective Software Defect Tracking + Pragmatic Unit Testing
Reading Summary - Effective Software Defect Tracking + Pragmatic Unit TestingReading Summary - Effective Software Defect Tracking + Pragmatic Unit Testing
Reading Summary - Effective Software Defect Tracking + Pragmatic Unit Testing
 
Reading Summary - Business Modeling + Peer Code Review + SW Inspections
Reading Summary - Business Modeling + Peer Code Review + SW InspectionsReading Summary - Business Modeling + Peer Code Review + SW Inspections
Reading Summary - Business Modeling + Peer Code Review + SW Inspections
 
Reading Summary - Software Requirements + Characteristics of Well Written Req...
Reading Summary - Software Requirements + Characteristics of Well Written Req...Reading Summary - Software Requirements + Characteristics of Well Written Req...
Reading Summary - Software Requirements + Characteristics of Well Written Req...
 
Reading Summary - Agile Documentation + Continuous Integration
Reading Summary - Agile Documentation + Continuous IntegrationReading Summary - Agile Documentation + Continuous Integration
Reading Summary - Agile Documentation + Continuous Integration
 
Reading Summary - Software Agile Development + Scrum
Reading Summary - Software Agile Development + Scrum Reading Summary - Software Agile Development + Scrum
Reading Summary - Software Agile Development + Scrum
 
Reading Summary - Teamwork + Team Structure + Configuration Management
Reading Summary - Teamwork + Team Structure + Configuration ManagementReading Summary - Teamwork + Team Structure + Configuration Management
Reading Summary - Teamwork + Team Structure + Configuration Management
 
Reading Summary - Team Motivation + Software Lifecycles Models
Reading Summary - Team Motivation + Software Lifecycles ModelsReading Summary - Team Motivation + Software Lifecycles Models
Reading Summary - Team Motivation + Software Lifecycles Models
 

Último

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 

Último (20)

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 

About Node.js

  • 1.
  • 2. INTRO TO NODE.JS- L E V E L O N E -
  • 3. 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
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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) { });
  • 8. 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
  • 9. 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); }
  • 10. 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...
  • 11. 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
  • 12. 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
  • 13. THE EVENT LOOP Known Events requestChecking for Events connection close Event Queue close request Events processed one at a time
  • 14. 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.");
  • 15. 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.");
  • 16. 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
  • 17. 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
  • 18. INTRO TO NODE.JS • Calls out to web services TYPICAL BLOCKING THINGS • Reads/Writes on the Database • Calls to extensions
  • 19. EVENTS- L E V E L T W O -
  • 20. 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(){ ... });
  • 21. EVENTS EVENTS IN NODE EventEmitter Many objects in Node emit events net.Server request event EventEmitter fs.readStream data event
  • 22. 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
  • 23. 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
  • 24. EVENTS HTTP ECHO SERVER http.createServer(function(request, response){ ... }); But what is really going on here? http://nodejs.org/api/
  • 26. 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
  • 27. STREAMS- L E V E L T H R E E -
  • 28. S T R E A M S WHAT ARE STREAMS? Start Processing Immediately Streams can be readable, writeable, or both
  • 29. 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
  • 30. 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
  • 31. 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);
  • 32. 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
  • 33. 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);
  • 34. 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() { });
  • 35. THE AWESOME STREAMING client storage server original file transferred file non-blocking 0s 10s5s
  • 36. BACK PRESSURE! client storage server original file transferred file Writable stream slower than readable stream Using pipe solves this problem
  • 37. THINK OF A MILK JUG milkStream.pause(); milkStream.resume(); }); Once milk jug is drained
  • 38. 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
  • 39. S T R E A M S FILE UPLOADING PROGRESS
  • 40. 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:
  • 41. S T R E A M S DOCUMENTATION http://nodejs.org/api/ Stability Scores
  • 42. 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() { });
  • 43. 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'];
  • 44. S T R E A M S SHOWING PROGRESS
  • 45. MODULES- L E V E L F O U R -
  • 46. 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?
  • 47. 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
  • 48. 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”
  • 49. 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.";
  • 50. 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
  • 51. 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?
  • 52. 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
  • 53. 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.
  • 54. 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
  • 55. 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
  • 56. MODULES FINDING MODULES npm registry $ npm search request npm command line github search toolbox.no.de
  • 57. 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" } }
  • 58. 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
  • 59. 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
  • 60. EXPRESS- L E V E L F I V E -
  • 61. 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
  • 62. 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
  • 63. 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); });
  • 66. 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>
  • 68. 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
  • 70. SOCKET.IO- L E V E L S I X -
  • 73. Using duplexed websocket connection SOCKET.IO WEBSOCKETS browser socket.io
  • 74. 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
  • 75. 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
  • 77. 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
  • 80. 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
  • 82. 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
  • 83. 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
  • 85. PERSISTING DATA- L E V E L S E V E N -
  • 86. P E R S I S T I N G D A T A RECENT MESSAGES
  • 87. }); }); }); 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
  • 88. }); }); }); 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
  • 89. 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 ...
  • 90. P E R S I S T I N G D A T A RECENT MESSAGES
  • 91. 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
  • 92. 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
  • 93. P E R S I S T I N G D A T A REDIS COMMAND DOCUMENTATION
  • 94. P E R S I S T I N G D A T A NODE REDIS
  • 95. 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
  • 96. 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";
  • 97. 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); });
  • 98. 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
  • 99. 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
  • 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); }); app.js
  • 101. 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
  • 102. P E R S I S T I N G D A T A IN ACTION
  • 103. 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
  • 104. 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); }
  • 105. 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); }); });
  • 106. 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(); }
  • 107. P E R S I S T I N G D A T A WELCOME TO CHATTR