第1页
Building Servers with Node.js
Travis Swicegood
#nodetalk
Licensed under Creative Commons, Attribution, Share-Alike
第2页
Hi, I’m Travis
building servers with node.js
some rights reserved
第3页
#nodetalk
building servers with node.js
some rights reserved
第4页
What’s this talk about?
building servers with node.js
some rights reserved
第5页
What is Node.js?
building servers with node.js
some rights reserved
第6页
Servers
building servers with node.js
some rights reserved
第7页
GTD
building servers with node.js
some rights reserved
第8页
Is it Right For Me?
building servers with node.js
some rights reserved
第9页
What is Node.js?
building servers with node.js
some rights reserved
第10页
Evented I/O Networking
Toolkit
building servers with node.js
some rights reserved
第11页
What’s “evented?”
building servers with node.js
some rights reserved
第12页
Some Code
building servers with node.js
some rights reserved
第13页
Standard Data Store
var db = new Database({host: "localhost"}); db.connect(); var result = db.find({name: "a-post"}); // do something with result
building servers with node.js
some rights reserved
第14页
Evented Data Store
var db = new Database({host: "localhost"}); db.connect(function(conn) {
conn.find({name: "a-post"}, function(result) { // do something with result
}); });
building servers with node.js
some rights reserved
第15页
Event Loop
building servers with node.js
some rights reserved
第16页
An Analogy
building servers with node.js
some rights reserved
第17页
A rabbi, a priest, and a cowboy walk
into a bar.
building servers with node.js
some rights reserved
第18页
Take 1 Simple Bartender
building servers with node.js
some rights reserved
第19页
Rabbi
building servers with node.js
some rights reserved
第20页
Priest
building servers with node.js
some rights reserved
第21页
Cowboy…
building servers with node.js
some rights reserved
第22页
… he starts to talk
building servers with node.js
some rights reserved
第23页
Bartender is now blocked
building servers with node.js
some rights reserved
第24页
Take 2 Evented Bartender
building servers with node.js
some rights reserved
第25页
Rabbi
building servers with node.js
some rights reserved
第26页
Priest
building servers with node.js
some rights reserved
第27页
Cowboy…
building servers with node.js
some rights reserved
第28页
… he starts to talk
building servers with node.js
some rights reserved
第29页
Bartender starts filling orders
building servers with node.js
some rights reserved
第30页
Fixing Take 1
building servers with node.js
some rights reserved
第31页
Add more bartenders
building servers with node.js
some rights reserved
第32页
Limit time with each client
building servers with node.js
some rights reserved
第33页
Respond to Events
building servers with node.js
some rights reserved
第34页
Who uses this?
building servers with node.js
some rights reserved
第35页
Nginx
building servers with node.js
some rights reserved
第36页
Memcached
building servers with node.js
some rights reserved
第37页
Most NoSQL
building servers with node.js
some rights reserved
第38页
Servers
building servers with node.js
some rights reserved
第39页
Basic Socket Server
building servers with node.js
some rights reserved
第40页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第41页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第42页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第43页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第44页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第45页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第46页
Echo Server
var net = require("net"); net.createServer(function(socket) {
socket.on("data", function(data) { socket.write("You said: " + data); socket.end();
}); socket.write("Please say something:\n"); }).listen(1234); console.log("Listening on 1234");
building servers with node.js
some rights reserved
第47页
Storing State
building servers with node.js
some rights reserved
第48页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第49页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第50页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第51页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第52页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第53页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第54页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第55页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第56页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第57页
Personalized Echo Server
net.createServer(function(socket) { var name = false; socket.on("data", function(data) { if (!name) { name = data.toString('utf8').trim(); socket.write("Thanks, " + name + "\n"); socket.write("Please say something:\n"); } else { socket.write(name + ", you said: " + data); socket.end(); } }); socket.write("Please tell me your name: ");
}).listen(1234);
building servers with node.js
some rights reserved
第58页
Web Servers
building servers with node.js
some rights reserved
第59页
Hello World
building servers with node.js
some rights reserved
第60页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第61页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第62页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第63页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第64页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第65页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第66页
Something’s Different
building servers with node.js
some rights reserved
第67页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第68页
Hello World
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end(); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第69页
Any idea why?
building servers with node.js
some rights reserved
第70页
Hello World
var http = require("http"); http.createServer(function(request, response) {
setTimeout(function() { response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>Hello, World!</h1>"); response.end();
}, 1000); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第71页
Hello World
var http = require("http"); http.createServer(function(request, response) {
db.find({"slug": "a-blog-post"}, function(post) { response.writeHead(200, {"Content-Type": "text/html"}); response.write("<h1>" + post.title + "</h1>"); response.write(post.body); response.end();
}); }).listen(4321); console.log("Now listening on port 4321");
building servers with node.js
some rights reserved
第72页
Grokking the Request
building servers with node.js
some rights reserved
第73页
Output the Request
building servers with node.js
some rights reserved
第74页
Output the Request
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"}); response.write(require("util").inspect(request)); response.end(); }).listen(4321); console.log("Listening on 4321");
building servers with node.js
some rights reserved
第75页
Output the Request
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"}); response.write(require("util").inspect(request)); response.end(); }).listen(4321); console.log("Listening on 4321");
building servers with node.js
some rights reserved
第76页
Output the Request
$ curl -s http://localhost:4321/ { socket:
{ bufferSize: 0, fd: 7, type: 'tcp4', allowHalfOpen: true, _readWatcher: { socket: [Circular], callback: [Function: onReadable] }, readable: true, _writeQueue: [], _writeQueueEncoding: [], _writeQueueFD: [],
… and so on, and so on …
building servers with node.js
some rights reserved
第77页
Output the Request
$ curl -s http://localhost:4321/ … way down around line 148 …
url: '/', method: 'GET',
building servers with node.js
some rights reserved
第78页
Output the Request
$ curl -s http://localhost:4321/say?msg=Hello | grep "url:" url: '/say?msg=Hello',
building servers with node.js
some rights reserved
第79页
Parsing the URL
building servers with node.js
some rights reserved
第80页
Parsing the URL
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"}); var parsedUrl = require("url").parse(request.url); response.write(require("util").inspect(parsedUrl)); response.end(); }).listen(4321); console.log("Listening on 4321");
building servers with node.js
some rights reserved
第81页
Parsing the URL
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: 'msg=Hello', pathname: '/say' }
building servers with node.js
some rights reserved
第82页
Parsing the URL
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: 'msg=Hello', pathname: '/say' }
building servers with node.js
some rights reserved
第83页
Parsing the URL
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: 'msg=Hello', pathname: '/say' }
building servers with node.js
some rights reserved
第84页
Parsing the URL
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: 'msg=Hello', pathname: '/say' }
building servers with node.js
some rights reserved
第85页
Parsing the URL
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: 'msg=Hello', pathname: '/say' }
building servers with node.js
some rights reserved
第86页
Parsing the Query
building servers with node.js
some rights reserved
第87页
Parsing the Query
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: 'msg=Hello', pathname: '/say' }
building servers with node.js
some rights reserved
第88页
Parsing the Query
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"}); var parsedUrl = require("url").parse(request.url, true); response.write(require("util").inspect(parsedUrl)); response.end(); }).listen(4321); console.log("Listening on 4321");
building servers with node.js
some rights reserved
第89页
Parsing the Query
var http = require("http"); http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"}); var parsedUrl = require("url").parse(request.url, true); response.write(require("util").inspect(parsedUrl)); response.end(); }).listen(4321); console.log("Listening on 4321");
building servers with node.js
some rights reserved
第90页
Parsing the Query
$ curl -s http://localhost:4321/say?msg=Hello { href: '/say?msg=Hello',
search: '?msg=Hello', query: { msg: 'Hello' }, pathname: '/say' }
building servers with node.js
some rights reserved
第91页
Receiving Data
building servers with node.js
some rights reserved
第92页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第93页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第94页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第95页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第96页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第97页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第98页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第99页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第100页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第101页
Receiving Data
function(request, response) { var raw = ""; request.on("data", function(chunk) { raw += chunk; }); request.on("end", function() { var data = JSON.parse(raw), obj = {message: data.message.split("").reverse().join("")}; response.writeHead(200, {"Content-Type": "application/json"}); response.write(JSON.stringify(obj)); response.end(); });
}
building servers with node.js
some rights reserved
第102页
Something is Wrong
building servers with node.js
some rights reserved
第103页
Can’t handle Errors
$ node json-reverse.js Listening on 4321
undefined:0 ^ SyntaxError: Unexpected end of input
at Object.parse (native) at IncomingMessage.<anonymous> (/Book/code/servers/jsonreverse.js:8:21) at IncomingMessage.emit (events.js:39:17) at HTTPParser.onMessageComplete (http.js:111:23) at Socket.ondata (http.js:945:22) at Socket._onReadable (net.js:654:27) at IOWatcher.onReadable [as callback] (net.js:156:10)
building servers with node.js
some rights reserved
第104页
Fault-Tolerance
building servers with node.js
some rights reserved
第105页
Quick Refactor
var handleResponse = function(response, code, message) { response.writeHead(code, {"Content-Type": "application/json"}); response.write(message); response.end();
};
building servers with node.js
some rights reserved
第106页
Fault Tolerant Reverse
request.on("end", function() { if (!raw) { handleResponse(response, 400, "Requires more data"); return; } try { var data = JSON.parse(raw); } catch(e) { handleResponse(response, 400, "Invalid JSON"); return; } if (!data.message) { handleResponse(response, 400, "Requires a message"); return; }
var obj = {message: data.message.split("").reverse().join("") }; handleResponse(response, 200, JSON.stringify(obj)) });
building servers with node.js
some rights reserved
第107页
Fault Tolerant Reverse
request.on("end", function() { if (!raw) { handleResponse(response, 400, "Requires more data"); return; } try { var data = JSON.parse(raw); } catch(e) { handleResponse(response, 400, "Invalid JSON"); return; } if (!data.message) { handleResponse(response, 400, "Requires a message");
building servers with node.js
some rights reserved
第108页
Fault Tolerant Reverse
request.on("end", function() { if (!raw) { handleResponse(response, 400, "Requires more data"); return; } try { var data = JSON.parse(raw); } catch(e) { handleResponse(response, 400, "Invalid JSON"); return; } if (!data.message) { handleResponse(response, 400, "Requires a message");
building servers with node.js
some rights reserved
第109页
Fault Tolerant Reverse
// earlier code } catch(e) {
handleResponse(response, 400, "Invalid JSON"); return; } if (!data.message) { handleResponse(response, 400, "Requires a message"); return; }
var obj = {message: data.message.split("").reverse().join("") }; handleResponse(response, 200, JSON.stringify(obj)) });
building servers with node.js
some rights reserved
第110页
Fault Tolerant Reverse
// earlier code } catch(e) {
handleResponse(response, 400, "Invalid JSON"); return; } if (!data.message) { handleResponse(response, 400, "Requires a message"); return; }
var obj = {message: data.message.split("").reverse().join("") }; handleResponse(response, 200, JSON.stringify(obj)) });
building servers with node.js
some rights reserved
第111页
GTD
building servers with node.js
some rights reserved
第112页
Libraries Help
building servers with node.js
some rights reserved
第113页
Express
visionmedia/express
building servers with node.js
some rights reserved
第114页
Hello World
var app = express.createServer(); app.get('/', function(req, res){
res.send('Hello World'); }); app.listen(3000);
building servers with node.js
some rights reserved
第115页
Socket.IO
http://socket.io/
building servers with node.js
some rights reserved
第116页
Push from the Server
var http = require('http'), io = require('socket.io');
var server = http.createServer(function(req, res){ // your normal server code res.writeHead(200, {'Content-Type': 'text/html'}); res.end('<h1>Hello world</h1>'); }); server.listen(80); // socket.io var socket = io.listen(server); socket.on('connection', function(client){ // new client is here! client.on('message', function(){ … }) client.on('disconnect', function(){ … }) });
building servers with node.js
some rights reserved
第117页
Socket.IO
// socket.io var socket = io.listen(server); socket.on('connection', function(client){ // new client is here! client.on('message', function(){ … }) client.on('disconnect', function(){ … }) });
building servers with node.js
some rights reserved
第118页
Sending to Client
// socket.io var socket = io.listen(server); socket.on('connection', function(client) {
// send a message back to the client client.send({msg: "Thanks for connecting…"}); // broadcast a message to everyone client.broadcast({msg: "Another one connected!"}); });
building servers with node.js
some rights reserved
第119页
CoffeeScript
jashkenas/coffee-script
building servers with node.js
some rights reserved
第120页
Remember this code?
request.on("end", function() { if (!raw) { handleResponse(response, 400, "Requires more data"); return; } try { var data = JSON.parse(raw); } catch(e) { handleResponse(response, 400, "Invalid JSON"); return; } if (!data.message) { handleResponse(response, 400, "Requires a message"); return; }
var obj = {message: data.message.split("").reverse().join("") }; handleResponse(response, 200, JSON.stringify(obj)) });
building servers with node.js
some rights reserved
第121页
In CoffeeScript
request.on "end", () -> return handleResponse response, 400, "Requires more data" unless raw
try data = JSON.parse raw
catch e return handleResponse response, 400, "Requires more data"
return handleResponse response, 400, "Requires a message" unless data.message
obj = message: data.message.split("").reverse().join("")
handleResponse response, 200, JSON.stringify obj
building servers with node.js
some rights reserved
第122页
Vows
cloudhead/vows http://vowjs.org/
building servers with node.js
some rights reserved
第123页
No Samples
building servers with node.js
some rights reserved
第124页
Is it Right For Me?
building servers with node.js
some rights reserved
第125页
It Depends
building servers with node.js
some rights reserved
第126页
The Checklist
building servers with node.js
some rights reserved
第127页
Control the Stack
building servers with node.js
some rights reserved
第128页
Comfortable with Change
building servers with node.js
some rights reserved
第129页
Full Control Over App Logic
building servers with node.js
some rights reserved
第130页
Lots of Small Independent
Pieces
building servers with node.js
some rights reserved
第131页
Then Maybe
building servers with node.js
some rights reserved
第132页
Where to?
building servers with node.js
some rights reserved
第133页
nodejs.org
building servers with node.js
some rights reserved
第134页
#Node.js (freenode)
building servers with node.js
some rights reserved
第135页
Travis Swicegood
travisswicegood.com @tswicegood
travis@domain51.com http://joind.in/2810
building servers with node.js
some rights reserved