You are on page 1of 67

Node.jsNode.

js
Node.jsNode.js&NPM
Node.jsNode.js
Node.jsNode.js
Node.jsNode.jsI/O
Node.jsBuffer
Node.jsConnect
Node.jsConnect

Node.js
2013
InfoQTop10
Node.js

Node.js
InfoQ
Node.jsIO
Node.jsNode.js
JavascriptNode.js
InfoQ
Qcon2013
Node.jsNode.js
Node.js

Node.js
WebJS
WebNode.js

Node.js
Node.jsInfoQ
Node.js

Node.js
Node.js

Node.js
13, 2011
Node.js2009
githubRailsNode.jsSRyan Dalh
JoyentWindowsNode.js
InfoQNode.jsQcon
Node.js
Node.jsNode.js
Node.jsNode.js

Node.jsNode.js
Node.js

Node.jsNode.js
NodeJSNodejs
Node.jsNodeNode.js
NodeNode
Node.jsjs
Node

Node.jsJSJS
Node.jsJavascript
Node.jsC++Javascript

C++Node.jsRyan DahlRuby
Node.jsRuby
V8C++Javascript.js
Node.jsJavascriptJavascript
Javascript
JavascriptJavascriptWeb
JavascriptNode.js
Javascript*nuxWindows
JavascriptNode.js

#node helloworld.js
Node.jsGoogle ChromeV8
APIJavascript
Node.js
Javascript

Node.js

socketNode.js
API
Netnet.Socketconnectdata
endtimeoutdrainerrorcloseNode.js

Node.js

Node.js

Node.js
Node.js

HTTPDNSNETUDPHTTPSTLS
Webhelloworld.js

var http = require('http');


http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/pla
in'});
res.end('Hello World\n');
}).listen(80, "127.0.0.1");
http
http://helloworld.cnodejs.net/80
http200Content-Type'
text/plain'Hello World

Node.jshttp
API
createServer
Javascripthttp
Node.js

Node.js
Node.js

Node.jsRyan DahlNode.js
C++V8Ruby
Node.js
JavascriptNode.js

httpNode.js

Node.js
CPUJava
OutOfMemory

Node.js

RHEL 5.2CPU 2.2GHz4G


Node.jsMemCache100
50
100
socket30MQPS16700

CPU95%
qps16700
30MV822MCPU95%
Node.js
Node.js
Node.jsCPU
Ryan DahlNode.js
Node.js
Node.jsCPU

Node.jsJavascript

1. Javascript
Web
Node.js
JavascriptNode.js
2. Javascript
helloworld

var hostRequest = http.request(requestOptions,f


unction(response) {
var responseHTML ='';
response.on('data', function (chunk) {
responseHTML = responseHTML + chunk;
});
response.on('end',function(){
console.log(responseHTML);
// do something useful
});

});
endresponseHTML
JavascriptresponseHTML
dataend

3. JavascriptJavacriptPython
RubyJavascript
V8Node.js

Node.js
20092Ryan DahlV8Web

20095Ryan DahlGitHubNode.js
Node.js
20091120104JSConfNode.js
2010Node.jsJoyentRyan Dahl
JoyentNode.js
20117Node.jsWindows

Node.js
Node.jsRuby/Rails
Node.js
LinkedInNodeJS
LinkedInKiran Prasad
NodeJS

LinkedIn
Node
Node

API
Ruby on Rails
Node1515
4
YammerNode
Javascript
YammerAPIAJAXYammerJim PattersonNode

Node
NodeRuby
Nodejavascript

Node
Ruby/Rails
GitHubNodeNodeNodeLoad
tarballzip
GitHubRuby
Resquegit
archive
Ruby Sinatramemcache flag
3Sinatra3
Resque workerGitHubNodeNode
RubyNodegit
Node
Nodesocket.io
Node
Node

MyFOX MySQL
SQLMyFOXSQL

MyFOXCPUIO
MyFOXPHPPHPMySQL
nginxdirzzle

HTTPcurl_multi_get MyFOX
Node.jsMyFOX
Node.js
CPU
TIME_WAIT

MyFOX
Node.js

Node.js
2Node.js
Node.js

[1] http://nodejs.org/
[2] http://beakkon.com/geek/node.js/why-node.js-single-thread-event-loopjavascript
[3] http://www.tbdata.org/archives/1285
[4] http://www.infoq.com/interviews/node-ryan-dahl
[5] http://www.infoq.com/cn/news/2011/08/enterprise-nodejs
[6] http://www.infoq.com/cn/news/2010/11/nodejs-joyent
[7] http://www.infoq.com/cn/news/2011/06/node-exe
[8] http://nodenode.com/post/1176414531/node-js-a-short-history
[9] http://www.infoq.com/cn/news/2011/05/nodeparty-hangzhou
http://www.infoq.com/cn/articles/what-is-nodejs

Node.js
Node.js

Node.js&NPM
02, 2011
Node&NPMNode
NPM

Node.js
Node.js
0.4.x0.6.x
0.6.xNode.js0.6.10.6
http://nodejs.org/#download

WindowsNode.js
Node.jsWindowsCygwin
MinGWPOSIX20116
JoyentNode.jsWindows
http://www.infoq.com/cn/news/2011/06/node-exe
0.6.xNode.jsWindows
CygwinMinGW
Linux
http://www.infoq.com/news/2011/11/Nodejs-Windows
WindowsWindows7Node.js

Windows
http://nodejs.org/dist/v0.6.1/node-v0.6.1.msi

Node.jsmsi

node -v
:

v0.6.1
node.exeC:\Program Files (x86)\nodejs\
PATH

Windows
Windows
Node.jsC++JavaScriptgyp
http://code.google.com/p/gyp/ Python
WindowsNode.jsgypVisual Studio Solution
VC++

1. PythonNode.js2.63.0
http://python.org/
2. VC++ Visual Studio 2010VC++ 2010 Express
VS2010http://msdn.microsoft.com/enus/vstudio/hh388567
Node.js0.6.1http://nodejs.org/dist/v0.6.1/nodev0.6.1.tar.gz
vcbuild.bat release
Releasenode.exe
node -v

v0.6.1

v0.6.1
WiXhttp://wix.sourceforge.net/
vcbuild.bat msi releaseRelasenode.msi

Unix/LinuxNode.js
Node.jsv0.x.xUnix/Linux
Node
Unix/Linux

WindowsNode.jsgyp
makeUnix/Linux

1. Pythongypshellpython
python2.6
3.0
2. Unix/LinuxC++
GCC/G++
makeg++
a. Debian/Ubuntuapt-get
b. RedHat/centOSyum
c. Mac OS Xxcode
3. Node.jsOpenSSL
libssl-devapt-get install libssl-dev

wget http://nodejs.org/dist/v0.6.1/node-v0.6.1.ta

r.gz
tar zxvf node-v0.6.1.tar.gz
cd node-v0.6.1
./configure
wget./
configureNodejs
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for program gcc or cc : /usr/bin/gcc
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for gcc : ok
Checking for library dl : yes
Checking for openssl : yes
Checking for library util : yes
Checking for library rt : yes
Checking for fdatasync(2) with c++ : yes
'configure' finished successfully (7.350s)
configure

make
make install
Nodejsmakemake installsudo

node -v

v0.6.1

Nodejsmake uninstall

*nixWindowsNodejsNodejs
example.js

var http = require('http');


http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/pla
in'});
res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1
337/');

node example.js
http://127.0.0.1:1337Hello World

NPM
NPMNode Package ManagerrubygemPython
PyPLsetuptoolsPHPpearNPM
NodejsNodejs
NPM
5112NodejsNodejs
Nodejs
NPMNPMNodejs
NPM

Unix/LinuxNPM
NPMhttp://npmjs.org/NPM

curl http://npmjs.org/install.sh | sh
curl http://npmjs.org/install.shcurl
shell| sh
sudo

curl http://npmjs.org/install.sh | sudo sh


npm

Usage: npm <command>


where <command> is one of:
adduser, apihelp, author, bin, bugs, c, cache, co
mpletion,
config, deprecate, docs, edit, explore, faq, find
, get,
help, help-search, home, i, info, init, install,
la, link,
list, ll, ln, ls, outdated, owner, pack, prefix,
prune,
publish, r, rb, rebuild, remove, restart, rm, roo
t,
run-script, s, se, search, set, show, star, start
, stop,
submodule, tag, test, un, uninstall, unlink, unpu
blish,
unstar, up, update, version, view, whoami
underscorenpm

npm install underscore

underscore@1.2.2 ./node_modules/underscore

npm install
CNode@fire9
NPM

npm --registry "http://npm.hacknodejs.com/" insta


ll underscore

npm config set registry "http://npm.hacknodejs.com/"


registry
http://registry.npmjs.vitecho.com

WindowsNPM
NodejsLinuxNPM
WindowsNodejsWindowsNPM
WindowsWindowsNPM

GIT
githubsubmodule
git
http://code.google.com/p/msysgit/downloads/listmsysgit
WindowsgitGit-1.7.7.1preview20111027.exe

NPM
CMDmsysgitNPM
npm

git clone --recursive git://github.com/isaacs/npm


.git
cd npm
node cli.js install npm -gf

node.exenode.msi
PATHnpmPATH
npmcmd

npm install underscore

underscore@1.2.2 ./node_modules/underscore
WindowsNPM
LinuxNPM

http://nodejs.org/
https://github.com/joyent/node/wiki/Installation
http://npmjs.org/doc/README.html#Installing-on-WindowsExperimental

@SAPMobile Web App


NodeJSJavaScript
NodeJSNodeJS
Github: http://github.com/JacksonTian
http://www.infoq.com/cn/articles/nodejs-npm-install-config

Node.js
Node.js

Node.js
26, 2011
Node.jsNode.js
Node.js

Node.js
Node.jsNode.js
Node.js

CommonJS
NetscapeJavaScriptRhino
JavaScript

JavaScriptJavaScript
JavaScriptJavaScript
JavaScript
APIJavaScript

JavaScript
JavaScriptAPI
IOAPI
JavaScriptWeb Server

JavaScript
CommonJShttp://www.commonjs.org
JavaScriptWeb

CommonJSNode.js
Node.jsrequireNPM
CommonJS
Node.jsrequireNPM

Node.js
Node.js

var PI = Math.PI;
exports.area = function (r) {
return PI * r * r;
};
exports.circumference = function (r) {
return 2 * PI * r;
};
circle.jsapp.js

var circle = require('./circle.js');


console.log( 'The area of a circle of radius 4 is
' + circle.area(4));
require
requireexports
Node.jsAPI
Node.js

Node.js
Node.js
Node.js

require
lib

node app.js
Node.js
module
runMain

// bootstrap main module.


Module.runMain = function () {
// Load the main module--the command line arg
ument.
Module._load(process.argv[1], null, true);
};
_load

var module = new Module(id, parent);

module.load(filename);
3
Node.js

.jsfsjs
.nodeC/C++Addondlopen
.jsonJSON.parse
jsNode.jsjs
jsapp.jsapp.js

(function (exports, require, module, __filename,


__dirname) {
var circle = require('./circle.js');
console.log('The area of a circle of radius 4
is ' + circle.area(4));
});
vmrunInThisContexteval
function
moduleexportsrequiremodule

requireapp.js
Node.jsAPI__filename__dirnamemodule
exports__filename__dirname
module
exportsmodule{}
null
requirerequire
load

loadmodulemoduleexports
circle.jsexports
lib/module.js

require
Node.js43require

require
http
http/http.js/http.node/http.jsonrequire(http)

Node.jsrequire

require

httpfspath

./mod../mod
/pathtomodule/mod
mod
module pathNode.js

pathsmodulepath.js

console.log(module.paths);
node modulepath.js

[ '/home/jackson/research/node_modules',
'/home/jackson/node_modules',
'/home/node_modules',
'/node_modules' ]
Windows

[ 'c:\\nodejs\\node_modules', 'c:\\node_modules'
]
module pathnode_modules
node_modules
node_modules
module pathnode
../../lib/nodeHOMENODE_PATH
NODE_PATHHOME.node_libraries
.node_modules

[NODE_PATHHOME/.node_modulesHOME/.node_librari

[NODE_PATHHOME/.node_modulesHOME/.node_librari
esexecPath/../../lib/node]

require
node_modules

1. module path
2.

3. .js.json.node

4. require
package.jsonmain
5. 3

6. module path

15
7. 16module path

8.
Node.js

JavaScriptCommonJS
http://wiki.commonjs.org/wiki/Packages/1.0 NPM
CommonJS
require
CommonJS

package.json
bin

JavaScriptlib
doc
test
requireNode.js
package.json
mainNode.js
requiremain
CommonJSpackage.json

nameNPM
description
versionhttp://semver.org/
x.y.z
keywordsNPM
maintainersnameemail
webJSON
contributors
patchmergemaster

patchnameemail

"contributors": [{
"name": "Jackson Tian",
"email": "mail @gmail.com"
}, {
"name": "fengmk2",
"email": "mail2@gmail.com"
}],

bugsbugURL
mailto:mailxx@domainhttp://url
licenses

"licenses": [{
"type": "GPLv2",
"url": "http://www.example.com/licenses/gpl.h
tml",
}]

repositories
dependenciesNPM

Expresspackage.json

{
"name": "express",
"description": "Sinatra inspired web developm
ent framework",
"version": "3.0.0alpha1-pre",
"author": "TJ Holowaychuk
bin
scriptsenginesdevDependenciesauthorscripts

88

NPM
scripts
scripts

"scripts": {
"install": "install.js",
"uninstall": "uninstall.js",
"build": "build.js",
"doc": "make-doc.js",
"test": "test.js",
}
JavaScriptCommonJS
NPMNPM5000+

npm publish <folder>


npm adduserNPM
NPMpackage.json
NPM

npm install <package>


NPMgithub

npm install <package.json folder>


package.json
require('package')

Node.jsrequire
NPMhttp://www.infoq.com/cn/articles/msh-using-npm-

manage-node.js-dependence

Node.js
script
JavaScriptNode.jsNode.js

JavaScript

underscore

(function () {
// Establish the root object, `window` in the
browser, or `global` on the server.
var root = this;
var _ = function (obj) {
return new wrapper(obj);
};
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && modu
le.exports) {
exports = module.exports = _;
}
exports._ = _;
} else if (typeof define === 'function' && de
fine.amd) {
// Register as a named module with AMD.
define('underscore', function () {
return _;
});
} else {
root['_'] = _;
}
}).call(this);
functionthiscall

exports
_exportsdefine
AMD
http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition
thiswindow
_

JavaScript

if (typeof exports !== "undefined") {


exports.EventProxy = EventProxy;
} else {
this.EventProxy = EventProxy;
}
exportsexports

seajshttp://seajs.com/
oyehttp://www.w3cgroup.com/oye/

http://www.commonjs.org
http://npmjs.org/doc/README.html
http://www.infoq.com/cn/articles/msh-using-npm-manage-node.jsdependence
http://nodejs.org/docs/latest/api/modules.html

@SAPMobile Web App


NodeJSJavaScript

NodeJSNodeJS
Github:http://github.com/JacksonTian
http://www.infoq.com/cn/articles/nodejs-module-mechanism

Node.js
Node.jsNode.js

31, 2012
Node.jsNode.js
Node.js

Node.js
Node.jsGithubhttps://github.com/joyent/node
Evented I/O for V8 JavaScript
Node.jsV8IO
Evented
Node.jsJavaScript
RhinoRhino
JavaScriptJavaScript

DOMAjax
AjaxRhino

PHP
Ryan Dahl2009Node.jsJavaScript
Node.js

1. JavaScript
2. IO
JavaScript
V8Node.js
Node.jsGithub
NPM

Node.jsEvented I/O for V8 JavaScript


2011Ryan Dahl
http://bostinno.com/2011/01/31/node-js-interview-4-questions-with-creatorryan-dahl/

Node.jsEvent
http://nodejs.org/docs/latest/api/events.html Event
events.EventEmitter
addListener/ononceremoveListenerremoveAllListenersemit
DOM
DOMpreventDefault()
stopPropagation() stopImmediatePropagation()
hook
Node.js

var options = {
host: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST'
};
var req = http.request(options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.
headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function (e) {
console.log('problem with request: ' + e.mess

age);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
HTTP requesterrordata

10
Node.js

emitter.setMaxListeners(0);

Node.jsEventEmittererror
errorEventEmitter
error

event.EventEmitter
EventEmitterNode.js
EventEmitter

function Stream() {
events.EventEmitter.call(this);
}
util.inherits(Stream, events.EventEmitter);
Node.js

EventEmitter

Web
FacebookTwitter
Web
Node.js

api.getUser("username", function (profile) {


// Got the profile
});
api.getTimeline("username", function (timeline) {
// Got the timeline
});
api.getSkin("username", function (skin) {
// Got the skin
});
Node.js

Node.js

api.getUser("username", function (profile) {


api.getTimeline("username", function (timelin
e) {
api.getSkin("username", function (skin) {
// TODO
});
});
});
API


EventProxyhttps://github.com/JacksonTian/eventproxy

var proxy = new EventProxy();


proxy.all("profile", "timeline", "skin", function
(profile, timeline, skin) {
// TODO
});
api.getUser("username", function (profile) {
proxy.emit("profile", profile);
});
api.getTimeline("username", function (timeline) {
proxy.emit("timeline", timeline);
});
api.getSkin("username", function (skin) {
proxy.emit("skin", skin);
});
EventProxyNode.js
EventEmitterNode.jsEventEmitter
APIEventEmitterNode.js

allprofiletimelineskin

Jscexhttps://github.com/JeffreyZhao/jscex Jscex

Jscex

var data = $await(Task.whenAll({


profile: api.getUser("username"),
timeline: api.getTimeline("username"),

skin: api.getSkin("username")
}));
// data.profile, data.timeline, data.skin
// TODO
Jscex@http://blog.zhaojie.me/

Node.js

var select = function (callback) {


db.select("SQL", function (results) {
callback(results);
});
};

SQL

var status = "ready";


var select = function (callback) {
if (status === "ready") {
status = "pending";
db.select("SQL", function (results) {
callback(results);
status = "ready";
});
}
};
select
select

var proxy = new EventProxy();


var status = "ready";
var select = function (callback) {
proxy.once("selected", callback);
if (status === "ready") {
status = "pending";
db.select("SQL", function (results) {
proxy.emit("selected", results);
status = "ready";
});
}
};
EventProxyonce

SQL

Node.js

EventEmitterEventProxy
setMaxListeners(0)

http://nodejs.org/docs/latest/api/events.html
https://github.com/JacksonTian/eventproxy/blob/master/README.md
https://github.com/JeffreyZhao/jscex/blob/master/README-cn.md

@SAP
NodeJSMobile Web App
JavaScriptNodeJS
Githubhttp://github.com/JacksonTian

http://www.infoq.com/cn/articles/tyq-nodejs-event

Node.js
Node.js

Node.jsI/O
22, 2012
Node.jsNode.js

Node.jsNode.js
ABNode.jsNode.jsB

I/O

I/OI/O

I/OgetFileFromNetgetFile

getFile("file_path");
getFileFromNet("url");
mn
m + nI/O
I/OI/Omax(m, n)

I/O
I/O
I/OI/O
CPUCPUI/O

CPU

CPU
I/O

Web
mn
I/O
I/Omax(m, n)m
nm + n + max(m, n,
)I/O
Node.jsI/O

I/O
Node.js

I/OI/O/
/

I/O
I/OI/O
I/O
I/O

I/O

I/OI/O
I/O


I/O
I/O

CPU

read
select
poll
epoll
pselect
kqueue
readI/O
select
pollepoll
I/O
I/O
CPU
readCPU
selectread
select

I/OCPUselect

I/O
I/O
I/O

LinuxI/O
AIO
LinuxAIOI/O
O_DIRECT
http://forum.nginx.org/read.php?2,113524,113587#msg-113587
I/OI/OI/O
I/O
GlibcAIOhttp://www.ibm.com/developerworks/linux/library/lasync/bug
LinuxI/O
libevMarc Alexander LehmannI/O
libeiolibeioI/OI/O
WindowsWindows
IOIOCPIOCPI/O
I/OIOCP
IOCPNode.js
Node.jsI/OWindows*nix
Node.jslibuv
Node.jslibeio/libevIOCP
Node.jsunixwin

WindowsNode.jsI/OIOCP
JavaScript

Node.jsI/O
Node.js
I/O
fs.open
Node.jsI/O

fs.open = function(path, flags, mode, callback) {


callback = arguments[arguments.length - 1];
if (typeof(callback) !== 'function') {
callback = noop;
}
mode = modeNum(mode, 438 /*=0666*/);
binding.open(pathModule._makeLong(path),
stringToFlags(flags),
mode,
callback);
};
fs.open
I/O

JavaScriptfs.opennode_file.cclibuv
uv_fs_openlibuv

uv_fs_openNode.jsFSReqWrap
JavaScript
oncomplete_sym

req_wrap->object_->Set(oncomplete_sym, callback);
QueueUserWorkItemFSReqWrap

QueueUserWorkItem(&uv_fs_thread_proc, req, WT_EXE


CUTELONGFUNCTION)
QueueUserWorkItem

uv_fs_thread_proc
uv_fs_openfs__open

req->resultPostQueuedCompletionStatus
IOCP

PostQueuedCompletionStatus((loop)->iocp, 0, 0, &(
(req)->overlapped))
PostQueuedCompletionStatusIOCP

JavaScript

uv_fs_openWindows
Node.jsIOCPloop

uv_run(uv_default_loop());
IOCPGetQueuedCompletionStatus
pollloop
pending_reqs_tail loop
pending_reqs_tailresult
oncomplete_symJavaScript
I/O

Node.jsI/O
WindowsIOCP
GetQueuedCompletionStatusPostQueuedCompletionStatus
QueueUserWorkItem*nix
libeiolibev

nodejsIOhttp://cnodejs.org/blog/?p=244
linux AIO IO http://cnodejs.org/blog/?p=2426
libev http://cnodejs.org/blog/?p=2489
Node Roadmaphttp://nodejs.org/nodeconf.pdf
select(2)poll(2)epoll(7)
http://blog.dccmx.com/2011/04/select-poll-epoll-in-kernel/
I/O
http://www.ibm.com/developerworks/cn/linux/l-async/

@SAP
NodeJSMobile Web App
JavaScriptNodeJS
Githubhttp://github.com/JacksonTian
http://www.infoq.com/cn/articles/nodejs-asynchronous-io

Node.js
Node.jsBuffer

16, 2012
JSer
PHP

<? php
echo strlen("0123456789");
echo strlen("");
echo mb_strlen("", "utf-8");
echo "\n";
103010strlen
UnicodeJavaScript
length

console.log("0123456789".length); // 10
console.log("".length); /10
console.log("\u00bd".length); // 1

JavaScript String

Buffer
Node.js
BufferString

Buffer

data

var fs = require('fs');
var rs = fs.createReadStream('testdata.md');
var data = '';
rs.on("data", function (trunk){
data += trunk;
});
rs.on("end", function () {
console.log(data);
});

buffer
trunk

var rs = fs.createReadStream('testdata.md', {buff


erSize: 11});

Node.jsI/O

data += trunk
trunkBuffertoString

data = data.toString() + trunk.toString();

var rs = fs.createReadStream('testdata.md', {enco


ding: 'utf-8', bufferSize: 11});

Node.jsI/O

Node.jshexutf8asciibinarybase64ucs2
GBKGB2312

string_decoder

data += trunkdata = data.toString() + trunk.toString()


11
trunktrunk

console.log("".length);
console.log(new Buffer("").length)
;
toString()xxxxxx
encodingutf8

datastring_decoder
string_decoderBuffer(xx)
xxstring_decoder
xxBuffer

string_decoder
trunkstring_decoder
utf8

Buffer
Buffer
Node.jsgithubbuffer

var buffers = [];


var nread = 0;
readStream.on('data', function (chunk) {
buffers.push(chunk);
nread += chunk.length;
});
readStream.on('end', function () {
var buffer = null;
switch(buffers.length) {
case 0: buffer = new Buffer(0);
break;
case 1: buffer = buffers[0];
break;
default:
buffer = new Buffer(nread);
for (var i = 0, pos = 0, l = buffers.
length; i < l; i++) {
var chunk = buffers[i];
chunk.copy(buffer, pos);
pos += chunk.length;

}
break;
}
});

endBuffer
iconv

Buffer
Buffer

bufferhelper
BufferNPM

npm install bufferhelper


data += trunk
bufferHelper.concat(chunk)

var http = require('http');


var BufferHelper = require('bufferhelper');
http.createServer(function (request, response) {
var bufferHelper = new BufferHelper();
request.on("data", function (chunk) {
bufferHelper.concat(chunk);
});
request.on('end', function () {
var html = bufferHelper.toBuffer().toString()
;
response.writeHead(200);
response.end(html);

});
}).listen(8001);
Buffer

https://github.com/joyent/node/blob/master/lib/fs.js#L107
https://github.com/JacksonTian/bufferhelper

@SAP
NodeJSMobile Web App
JavaScriptNodeJS
Github http://github.com/JacksonTian
http://www.infoq.com/cn/articles/nodejs-about-buffer

Node.js
Node.jsConnect

05, 2012

Connect
Node.js

Node.jsWeb
ConnectWeb
ConnectNode18
ConnectNode.jsWeb
WebConnect

ConnectWeb

ConnectNPMMDO
Express
ConnectExpress


Node.jsWeb

var http = require('http');


http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain
'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
WebHTTP
Connect

function (req, res, next) {


//
}

res.end()

var app = connect();


// Middleware
app.use(connect.staticCache());
app.use(connect.static(__dirname + '/public'));
app.use(connect.cookieParser());
app.use(connect.session());

app.use(connect.query());
app.use(connect.bodyParser());
app.use(connect.csrf());
app.use(function (req, res, next) {
//
});
app.listen(3001);
ConncetuseConnect

Conncetuse

app.stack = [];
app.use = function(route, fn){
//
// add the middleware
debug('use %s %s', route || '/', fn.name || 'an
onymous');
this.stack.push({ route: route, handle: fn });
return this;
};
res.end()

Node.jsConnect


app.use()routefn

URL

app.use()
Connect/

Java

app.use()

multipart

URL

app.use("/upload", connect.multipart({ uploadDir:


path }));

MVC
Connect
Connect
MVC

Makefile //
app.js //
automation //
bin //
conf //

controllers //
helpers //
middlewares //
models //
node_modules //
package.json //
public //
images //
libs // JavaScript
scripts // JavaScript
styles //
test //
views //

Connect http://www.senchalabs.org/connect/
NPM http://search.npmjs.org/

@SAP
NodeJSMobile Web App
JavaScriptNodeJS
Githubhttp://github.com/JacksonTian
http://www.infoq.com/cn/articles/nodejs-connect-module

Node.js
Node.jsConnect

26, 2012
Connect
Connect
Connect
Connect

Node.js
Node.js
MIME
Connectstatic
3

var connect = require('connect');


var app = connect();
app.use(connect.static(__dirname + '/public'));
apache
NPMConnect

app.use()
app.use("/", middleware)

fs.stat

app.use('/public', connect.static(__dirname + '/p


ublic'));
Node.jsCDN

HTTPcache-

controlexpires
cache-controlexpires

0
maxAge

app.use('/public', connect.static(__dirname + '/p


ublic', {maxAge: 86400000}));
maxAgeYUI3CDN10

md5

http://some.url/some.js?md5
md5URL

md5
10

staticCache

app.use(connect.staticCache());
app.use(/public, connect.static(__dirname + '/p
ublic', {maxAge: 86400000}));

static(): 2700 rps


node-static: 5300 rps
static() + staticCache(): 7500 rps
node-staticConnect

Connect 3.0
Node.js

staticCachemaxObjectsmaxLength
128256kb
V8

CPUNode.js

V8JavaScript

JavaScript
V8

Node.js
Node.js
Node.js

1.
2.
3.
4.

Node.js

Connectvarnish
Redis

https://www.varnish-cache.org/releases
http://www.senchalabs.org/connect/static.html
http://www.senchalabs.org/connect/staticCache.html

@SAP
NodeJSMobile Web App
JavaScriptNodeJS
Githubhttp://github.com/JacksonTian
http://www.infoq.com/cn/articles/nodejs-8-connect-module-

part-2