├── 10 ├── cluster.js ├── for.js ├── length.js ├── map_for.js ├── server.js └── test.js ├── 11 ├── app.js ├── appctl.sh └── logger.js ├── .gitignore ├── 02 ├── addon │ ├── binding.gyp │ ├── hello.js │ └── src │ │ └── hello.cc ├── extensions.js └── module │ ├── hello.js │ └── package.json ├── 03 ├── next_tick.js ├── next_tick_set_immediate.js └── set_immediate.js ├── 04 ├── async │ ├── file1.txt │ ├── file2.txt │ ├── parallel.js │ └── waterfall.js ├── promise_a │ ├── file1.txt │ ├── file2.txt │ ├── promise.js │ ├── sequence.js │ └── smooth.js ├── step │ ├── file1.txt │ ├── file2.txt │ ├── group.js │ ├── parallel.js │ └── serial.js └── wind │ ├── file1.txt │ ├── file2.txt │ ├── parallel.js │ └── serial.js ├── 05 ├── closure01.js ├── closure02.js ├── closure03.js ├── delete.js ├── heap.js ├── in.txt ├── leak │ ├── diff.js │ ├── server.js │ └── server2.js ├── out.txt ├── out_of_heap.js ├── outofmemory.js ├── parse.js ├── stream.js ├── test01.js ├── test02.js └── try_catch.js ├── 06 ├── allocate.js ├── buf.js ├── decoder.js ├── demo.js ├── string.php ├── test.md ├── transfer.js └── unicode.js ├── 07 ├── http │ ├── client.js │ └── server.js ├── https │ ├── client.js │ ├── keys │ │ ├── ca.crt │ │ ├── client.crt │ │ ├── client.key │ │ ├── server.crt │ │ └── server.key │ └── server.js ├── tcp │ ├── client.js │ ├── echo.js │ └── server.js ├── tls │ ├── client.js │ ├── keys │ │ ├── ca.crt │ │ ├── ca.csr │ │ ├── ca.key │ │ ├── ca.srl │ │ ├── client.crt │ │ ├── client.csr │ │ ├── client.key │ │ ├── server.crt │ │ ├── server.csr │ │ └── server.key │ └── server.js ├── udp │ ├── client.js │ └── server.js └── websocket │ └── server.js ├── 08 ├── bagpipe │ ├── assets │ │ └── render.js │ ├── server.js │ └── views │ │ └── index.html ├── mime.js ├── server.js └── template.js ├── 09 ├── cluster.js ├── handle │ ├── 1 │ │ ├── child.js │ │ └── parent.js │ ├── 2 │ │ ├── child.js │ │ └── parent.js │ └── 3 │ │ ├── child.js │ │ └── parent.js ├── master.js ├── pm │ ├── master.js │ └── worker.js ├── signal.js ├── suicide │ ├── master.js │ └── worker.js └── worker.js └── B └── myscript.js /.gitignore: -------------------------------------------------------------------------------- 1 | examples/03/addon/build 2 | *.pdf 3 | .DS_Store 4 | v8.log 5 | node_modules 6 | *.pid 7 | *.log 8 | build -------------------------------------------------------------------------------- /02/addon/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | { 4 | 'target_name': 'hello', 5 | 'sources': [ 6 | 'src/hello.cc' 7 | ], 8 | 'conditions': [ 9 | ['OS == "win"', 10 | { 11 | 'libraries': ['-lnode.lib'] 12 | } 13 | ] 14 | ] 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /02/addon/hello.js: -------------------------------------------------------------------------------- 1 | var hello = require('./build/Release/hello.node'); 2 | 3 | console.log(hello.sayHello()); 4 | -------------------------------------------------------------------------------- /02/addon/src/hello.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace v8; 5 | // 实现预定义的方法 6 | Handle SayHello(const Arguments& args) { 7 | HandleScope scope; 8 | return scope.Close(String::New("Hello world!")); 9 | } 10 | 11 | // 给传入的目标对象添加sayHello方法 12 | void Init(Handle target) { 13 | target->Set(String::NewSymbol("sayHello"), FunctionTemplate::New(SayHello)->GetFunction()); 14 | } 15 | // 调用NODE_MODULE将注册方法定义到内存中。 16 | NODE_MODULE(hello, Init) 17 | -------------------------------------------------------------------------------- /02/extensions.js: -------------------------------------------------------------------------------- 1 | console.log(require.extensions); -------------------------------------------------------------------------------- /02/module/hello.js: -------------------------------------------------------------------------------- 1 | exports.sayHello = function () { 2 | return "Hello, world."; 3 | }; 4 | -------------------------------------------------------------------------------- /02/module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello_test_jackson", 3 | "version": "0.0.1", 4 | "description": "A hello world package", 5 | "main": "./hello.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": "", 10 | "keywords": [ 11 | "Hello", 12 | "world" 13 | ], 14 | "author": "Jackson Tian", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /03/next_tick.js: -------------------------------------------------------------------------------- 1 | process.nextTick(function () { 2 | console.log('延迟执行'); 3 | }); 4 | console.log('正常执行'); -------------------------------------------------------------------------------- /03/next_tick_set_immediate.js: -------------------------------------------------------------------------------- 1 | process.nextTick(function () { 2 | console.log('nextTick延迟执行1'); 3 | }); 4 | process.nextTick(function () { 5 | console.log('nextTick延迟执行2'); 6 | }); 7 | setImmediate(function () { 8 | console.log('setImmediate延迟执行1'); 9 | process.nextTick(function () { 10 | console.log('强势插入'); 11 | }); 12 | }); 13 | setImmediate(function () { 14 | console.log('setImmediate延迟执行2'); 15 | }); 16 | console.log('正常执行'); 17 | -------------------------------------------------------------------------------- /03/set_immediate.js: -------------------------------------------------------------------------------- 1 | setImmediate(function () { 2 | console.log('延迟执行'); 3 | }); 4 | console.log('正常执行'); -------------------------------------------------------------------------------- /04/async/file1.txt: -------------------------------------------------------------------------------- 1 | file1.txt 2 | -------------------------------------------------------------------------------- /04/async/file2.txt: -------------------------------------------------------------------------------- 1 | file2.txt 2 | -------------------------------------------------------------------------------- /04/async/parallel.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var async = require('async'); 3 | 4 | async.parallel([ 5 | function (callback) { 6 | fs.readFile('file1.txt', 'utf-8', callback); 7 | }, 8 | function (callback) { 9 | fs.readFile('file2.txt', 'utf-8', callback); 10 | } 11 | ], function (err, results) { 12 | console.log(results); 13 | // results => [file1.txt, file2.txt] 14 | }); 15 | -------------------------------------------------------------------------------- /04/async/waterfall.js: -------------------------------------------------------------------------------- 1 | var async = require('async'); 2 | 3 | async.waterfall([ 4 | function(callback){ 5 | console.log(arguments); 6 | setTimeout(function () { 7 | callback(null, 'one', 'two'); 8 | }, 20); 9 | }, 10 | function(arg1, arg2, callback){ 11 | console.log(arguments); 12 | setTimeout(function () { 13 | callback(null, 'three'); 14 | }, 10); 15 | }, 16 | function(arg1, callback){ 17 | console.log(arguments); 18 | // arg1 now equals 'three' 19 | callback(null, 'done'); 20 | } 21 | ], function (err, result) { 22 | // result now equals 'done' 23 | console.log(arguments); 24 | }); 25 | -------------------------------------------------------------------------------- /04/promise_a/file1.txt: -------------------------------------------------------------------------------- 1 | file2.txt 2 | -------------------------------------------------------------------------------- /04/promise_a/file2.txt: -------------------------------------------------------------------------------- 1 | I am file2 2 | -------------------------------------------------------------------------------- /04/promise_a/promise.js: -------------------------------------------------------------------------------- 1 | var EventEmitter = require('events').EventEmitter; 2 | 3 | var Deferred = function () { 4 | this.state = 'unfulfilled'; 5 | this.promise = new Promise(); 6 | }; 7 | 8 | Deferred.prototype.resolve = function (obj) { 9 | this.state = 'fulfilled'; 10 | this.promise.emit('success', obj); 11 | }; 12 | 13 | Deferred.prototype.reject = function (err) { 14 | this.state = 'failed'; 15 | this.promise.emit('error', err); 16 | }; 17 | 18 | Deferred.prototype.progress = function (data) { 19 | this.promise.emit('progress', data); 20 | }; 21 | 22 | Deferred.prototype.all = function (promises) { 23 | var count = promises.length; 24 | var that = this; 25 | promises.forEach(function (promise) { 26 | promise.then(function () { 27 | count--; 28 | if (count === 0) { 29 | that.resolve(); 30 | } 31 | }, function () { 32 | that.reject(); 33 | }); 34 | }); 35 | return this.promise; 36 | }; 37 | 38 | var Promise = function () { 39 | EventEmitter.call(this); 40 | }; 41 | util.inherits(Promise, EventEmitter); 42 | 43 | Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) { 44 | if (typeof fulfilledHandler === 'function') { 45 | // 利用once方法,保证成功回调只执行一次 46 | this.once('success', fulfilledHandler); 47 | } 48 | if (typeof errorHandler === 'function') { 49 | // 利用once方法,保证异常回调只执行一次 50 | this.once('error', errorHandler); 51 | } 52 | if (typeof progressHandler === 'function') { 53 | this.on('progress', progressHandler); 54 | } 55 | return this; 56 | }; 57 | 58 | exports.Deferred = Deferred; 59 | -------------------------------------------------------------------------------- /04/promise_a/sequence.js: -------------------------------------------------------------------------------- 1 | var Deferred = function () { 2 | this.promise = new Promise(); 3 | }; 4 | 5 | Deferred.prototype.resolve = function (obj) { 6 | var promise = this.promise; 7 | var handler; 8 | while ((handler = promise.queue.shift())) { 9 | if (handler && handler.fulfilled) { 10 | var ret = handler.fulfilled(obj); 11 | if (ret && ret.isPromise) { 12 | ret.queue = promise.queue; 13 | this.promise = ret; 14 | return; 15 | } 16 | } 17 | } 18 | }; 19 | 20 | Deferred.prototype.reject = function (err) { 21 | var promise = this.promise; 22 | var handler; 23 | while ((handler = promise.queue.shift())) { 24 | if (handler && handler.error) { 25 | var ret = handler.error(err); 26 | if (ret && ret.isPromise) { 27 | ret.queue = promise.queue; 28 | this.promise = ret; 29 | return; 30 | } 31 | } 32 | } 33 | }; 34 | 35 | Deferred.prototype.callback = function () { 36 | var that = this; 37 | return function (err, file) { 38 | if (err) { 39 | return that.reject(err); 40 | } 41 | that.resolve(file); 42 | }; 43 | }; 44 | 45 | 46 | var Promise = function () { 47 | this.queue = []; 48 | this.isPromise = true; 49 | }; 50 | 51 | Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) { 52 | var handler = {}; 53 | if (typeof fulfilledHandler === 'function') { 54 | handler.fulfilled = fulfilledHandler; 55 | } 56 | if (typeof errorHandler === 'function') { 57 | // 利用once方法,保证异常回调只执行一次 58 | handler.error = errorHandler; 59 | } 60 | this.queue.push(handler); 61 | return this; 62 | }; 63 | 64 | var fs = require('fs'); 65 | 66 | var readFile1 = function (file, encoding) { 67 | var deferred = new Deferred(); 68 | fs.readFile(file, encoding, deferred.callback()); 69 | return deferred.promise; 70 | }; 71 | var readFile2 = function (file, encoding) { 72 | var deferred = new Deferred(); 73 | fs.readFile(file, encoding, deferred.callback()); 74 | return deferred.promise; 75 | }; 76 | 77 | readFile1('file1.txt', 'utf8').then(function (file1) { 78 | return readFile2(file1.trim(), 'utf8'); 79 | }).then(function (file2) { 80 | // file2 => 2 81 | console.log(file2); 82 | }); 83 | 84 | exports.Deferred = Deferred; 85 | -------------------------------------------------------------------------------- /04/promise_a/smooth.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | var Deferred = require('./sequence.js').Deferred; 4 | 5 | var smooth = function (method) { 6 | return function () { 7 | var deferred = new Deferred(); 8 | var args = Array.prototype.slice.call(arguments, 1); 9 | args.push(deferred.callback()); 10 | method.apply(null, args); 11 | return deferred.promise; 12 | }; 13 | }; 14 | 15 | var readFile = smooth(fs.readFile); 16 | readFile('file1.txt', 'utf8').then(function (file1) { 17 | return readFile(file1.trim(), 'utf8'); 18 | }).then(function (file2) { 19 | // file2 => I am file2 20 | console.log(file2); 21 | }); 22 | -------------------------------------------------------------------------------- /04/step/file1.txt: -------------------------------------------------------------------------------- 1 | file1 2 | -------------------------------------------------------------------------------- /04/step/file2.txt: -------------------------------------------------------------------------------- 1 | file2 2 | -------------------------------------------------------------------------------- /04/step/group.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var Step = require('step'); 3 | 4 | Step( 5 | function readDir() { 6 | fs.readdir(__dirname, this); 7 | }, 8 | function readFiles(err, results) { 9 | if (err) throw err; 10 | // Create a new group 11 | var group = this.group(); 12 | results.forEach(function (filename) { 13 | if (/\.txt$/.test(filename)) { 14 | fs.readFile(__dirname + "/" + filename, 'utf8', group()); 15 | } 16 | }); 17 | }, 18 | function showAll(err, files) { 19 | if (err) throw err; 20 | console.dir(files); 21 | } 22 | ); 23 | -------------------------------------------------------------------------------- /04/step/parallel.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var Step = require('step'); 3 | 4 | Step( 5 | function readFile1() { 6 | fs.readFile('file1.txt', 'utf-8', this.parallel()); 7 | fs.readFile('file2.txt', 'utf-8', this.parallel()); 8 | }, 9 | function done(err, content1, content2) { 10 | // content1 => file1 11 | // content2 => file2 12 | console.log(arguments); 13 | } 14 | ); 15 | -------------------------------------------------------------------------------- /04/step/serial.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var Step = require('step'); 3 | 4 | Step( 5 | function readFile1() { 6 | fs.readFile('file1.txt', 'utf-8', this); 7 | }, 8 | function readFile2(err, content) { 9 | fs.readFile('file2.txt', 'utf-8', this); 10 | }, 11 | function done(err, content) { 12 | console.log(content); 13 | } 14 | ); 15 | -------------------------------------------------------------------------------- /04/wind/file1.txt: -------------------------------------------------------------------------------- 1 | file1 2 | -------------------------------------------------------------------------------- /04/wind/file2.txt: -------------------------------------------------------------------------------- 1 | file2 2 | -------------------------------------------------------------------------------- /04/wind/parallel.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | var Wind = require("wind"); 4 | var Task = Wind.Async.Task; 5 | 6 | var readFileAsync = function (file, encoding) { 7 | return Task.create(function (t) { 8 | fs.readFile(file, encoding, function (err, file) { 9 | if (err) { 10 | t.complete("failure", err); 11 | } else { 12 | t.complete("success", file); 13 | } 14 | }); 15 | }); 16 | }; 17 | // var readFileAsync = Wind.Async.Binding.fromStandard(fs.readFile); 18 | 19 | var parallel = eval(Wind.compile("async", function () { 20 | var result = $await(Task.whenAll({ 21 | file1: readFileAsync('file1.txt', 'utf-8'), 22 | file2: readFileAsync('file2.txt', 'utf-8') 23 | })); 24 | console.log(result.file1); 25 | console.log(result.file2); 26 | })); 27 | 28 | parallel().start(); 29 | -------------------------------------------------------------------------------- /04/wind/serial.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | var Wind = require("wind"); 4 | var Task = Wind.Async.Task; 5 | 6 | var readFileAsync = function (file, encoding) { 7 | return Task.create(function (t) { 8 | fs.readFile(file, encoding, function (err, file) { 9 | if (err) { 10 | t.complete("failure", err); 11 | } else { 12 | t.complete("success", file); 13 | } 14 | }); 15 | }); 16 | }; 17 | // var readFileAsync = Wind.Async.Binding.fromStandard(fs.readFile); 18 | 19 | var serial = eval(Wind.compile("async", function () { 20 | var file1 = $await(readFileAsync('file1.txt', 'utf-8')); 21 | console.log(file1); 22 | var file2 = $await(readFileAsync('file2.txt', 'utf-8')); 23 | console.log(file2); 24 | try { 25 | var file3 = $await(readFileAsync('file3.txt', 'utf-8')); 26 | } catch (err) { 27 | console.log(err); 28 | } 29 | })); 30 | 31 | serial().start(); 32 | -------------------------------------------------------------------------------- /05/closure01.js: -------------------------------------------------------------------------------- 1 | var foo = function () { 2 | var local = "局部变量"; 3 | (function () { 4 | console.log(local); 5 | }()); 6 | }; 7 | foo(); 8 | -------------------------------------------------------------------------------- /05/closure02.js: -------------------------------------------------------------------------------- 1 | var foo = function () { 2 | (function () { 3 | var local = "局部变量"; 4 | }()); 5 | console.log(local); 6 | }; 7 | foo(); 8 | -------------------------------------------------------------------------------- /05/closure03.js: -------------------------------------------------------------------------------- 1 | var foo = function () { 2 | var bar = function () { 3 | var local = "局部变量"; 4 | return function () { 5 | return local; 6 | }; 7 | }; 8 | var baz = bar(); 9 | console.log(baz()); 10 | }; 11 | foo(); 12 | -------------------------------------------------------------------------------- /05/delete.js: -------------------------------------------------------------------------------- 1 | global.foo = "I am global object"; 2 | console.log(global.foo); // => "I am global object" 3 | delete global.foo; 4 | // 或者重新赋值 5 | global.foo = undefined; // or null 6 | console.log(global.foo); // => undefined 7 | -------------------------------------------------------------------------------- /05/heap.js: -------------------------------------------------------------------------------- 1 | var size = 10 * 1024 * 1024; // 100M 2 | var arr = new Array(size); 3 | for (var i = 0; i < size; i++) { 4 | arr[i] = 0; 5 | } 6 | var mem = process.memoryUsage(); 7 | console.log(mem); 8 | -------------------------------------------------------------------------------- /05/in.txt: -------------------------------------------------------------------------------- 1 | var showMem = function () { 2 | var mem = process.memoryUsage(); 3 | var format = function (bytes) { 4 | return (bytes / 1024 / 1024).toFixed(2) + ' MB'; 5 | }; 6 | console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss)); 7 | console.log('----------------------------------------------------------------'); 8 | }; 9 | 10 | var useMem = function () { 11 | var size = 200 * 1024 * 1024; 12 | var buffer = new Buffer(size); 13 | for (var i = 0; i < size; i++) { 14 | buffer[i] = 0; 15 | } 16 | return buffer; 17 | }; 18 | 19 | var total = []; 20 | 21 | for (var j = 0; j < 15; j++) { 22 | showMem(); 23 | total.push(useMem()); 24 | } 25 | showMem(); 26 | -------------------------------------------------------------------------------- /05/leak/diff.js: -------------------------------------------------------------------------------- 1 | var memwatch = require('memwatch'); 2 | var leakArray = []; 3 | var leak = function () { 4 | leakArray.push("leak" + Math.random()); 5 | }; 6 | 7 | // Take first snapshot 8 | var hd = new memwatch.HeapDiff(); 9 | 10 | for (var i = 0; i < 10000; i++) { 11 | leak(); 12 | } 13 | 14 | // Take the second snapshot and compute the diff 15 | var diff = hd.end(); 16 | console.log(JSON.stringify(diff, null, 2)); 17 | -------------------------------------------------------------------------------- /05/leak/server.js: -------------------------------------------------------------------------------- 1 | var heapdump = require('heapdump'); 2 | 3 | var http = require('http'); 4 | 5 | var leakArray = []; 6 | var leak = function () { 7 | leakArray.push("leak" + Math.random()); 8 | }; 9 | 10 | http.createServer(function (req, res) { 11 | leak(); 12 | res.writeHead(200, {'Content-Type': 'text/plain'}); 13 | res.end('Hello World\n'); 14 | }).listen(1337); 15 | 16 | console.log('Server running at http://127.0.0.1:1337/'); 17 | -------------------------------------------------------------------------------- /05/leak/server2.js: -------------------------------------------------------------------------------- 1 | var memwatch = require('memwatch'); 2 | memwatch.on('leak', function (info) { 3 | console.log('leak:'); 4 | console.log(info); 5 | }); 6 | 7 | memwatch.on('stats', function (stats) { 8 | console.log('stats:') 9 | console.log(stats); 10 | }); 11 | 12 | var http = require('http'); 13 | 14 | var leakArray = []; 15 | var leak = function () { 16 | leakArray.push("leak" + Math.random()); 17 | }; 18 | 19 | http.createServer(function (req, res) { 20 | leak(); 21 | res.writeHead(200, {'Content-Type': 'text/plain'}); 22 | res.end('Hello World\n'); 23 | }).listen(1337); 24 | 25 | console.log('Server running at http://127.0.0.1:1337/'); 26 | -------------------------------------------------------------------------------- /05/out.txt: -------------------------------------------------------------------------------- 1 | var showMem = function () { 2 | var mem = process.memoryUsage(); 3 | var format = function (bytes) { 4 | return (bytes / 1024 / 1024).toFixed(2) + ' MB'; 5 | }; 6 | console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss)); 7 | console.log('----------------------------------------------------------------'); 8 | }; 9 | 10 | var useMem = function () { 11 | var size = 200 * 1024 * 1024; 12 | var buffer = new Buffer(size); 13 | for (var i = 0; i < size; i++) { 14 | buffer[i] = 0; 15 | } 16 | return buffer; 17 | }; 18 | 19 | var total = []; 20 | 21 | for (var j = 0; j < 15; j++) { 22 | showMem(); 23 | total.push(useMem()); 24 | } 25 | showMem(); 26 | -------------------------------------------------------------------------------- /05/out_of_heap.js: -------------------------------------------------------------------------------- 1 | var showMem = function () { 2 | var mem = process.memoryUsage(); 3 | var format = function (bytes) { 4 | return (bytes / 1024 / 1024).toFixed(2) + ' MB'; 5 | }; 6 | console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss)); 7 | console.log('----------------------------------------------------------------'); 8 | }; 9 | 10 | var useMem = function () { 11 | var size = 200 * 1024 * 1024; 12 | var buffer = new Buffer(size); 13 | for (var i = 0; i < size; i++) { 14 | buffer[i] = 0; 15 | } 16 | return buffer; 17 | }; 18 | 19 | var total = []; 20 | 21 | for (var j = 0; j < 15; j++) { 22 | showMem(); 23 | total.push(useMem()); 24 | } 25 | showMem(); 26 | -------------------------------------------------------------------------------- /05/outofmemory.js: -------------------------------------------------------------------------------- 1 | var showMem = function () { 2 | var mem = process.memoryUsage(); 3 | var format = function (bytes) { 4 | return (bytes / 1024 / 1024).toFixed(2) + ' MB'; 5 | }; 6 | console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss)); 7 | console.log('----------------------------------------------------------------'); 8 | }; 9 | 10 | var useMem = function () { 11 | var size = 20 * 1024 * 1024; 12 | var arr = new Array(size); 13 | for (var i = 0; i < size; i++) { 14 | arr[i] = 0; 15 | } 16 | return arr; 17 | }; 18 | 19 | var total = []; 20 | 21 | for (var j = 0; j < 15; j++) { 22 | showMem(); 23 | total.push(useMem()); 24 | } 25 | showMem(); 26 | -------------------------------------------------------------------------------- /05/parse.js: -------------------------------------------------------------------------------- 1 | Parser.prototype.parse = function (s) { 2 | var l = ''; 3 | for (var i = 0; i < s.length; i++) { 4 | if (s[i] == '\u0000') { 5 | l = Number(l); 6 | this.emit('data', s.substr(i + 1, l)); 7 | return this.parse(s.substr(i + 1 + l)); 8 | } else { 9 | l += s[i]; 10 | } 11 | } 12 | return s; 13 | }; 14 | 15 | Parser.prototype.parse = function (s) { 16 | var l = ''; 17 | for (var i = 0; i < s.length; i++) { 18 | if (s[i] == '\u0000') { 19 | l = Number(l); 20 | this.emit('data', s.substr(i + 1, l)); 21 | s = s.substr(i + 1 + l); 22 | i = 0; 23 | l = ''; 24 | } else { 25 | l += s[i]; 26 | } 27 | } 28 | return s; 29 | }; 30 | 31 | Parser.prototype.parse = function (s) { 32 | var l = ''; 33 | var j = 0; 34 | for (var i = 0; i < s.length; i++) { 35 | if (s[i] == '\u0000') { 36 | l = Number(l); 37 | this.emit('data', s.substr(i + 1, l)); 38 | i += l; 39 | j = i + 1; 40 | } else { 41 | l += s[i]; 42 | } 43 | } 44 | }; 45 | 46 | Parser.prototype.parse4 = function (s) { 47 | var l = 0, i = 0; 48 | while (i < s.length) { 49 | var ch = s.charCodeAt(i); 50 | if (ch === 0) { 51 | this.emit('data', s.substr(i + 1, l)); 52 | i += l + 1; 53 | l = 0; 54 | } else { 55 | l = l * 10 + ch; 56 | i++; 57 | } 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /05/stream.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | var reader = fs.createReadStream('in.txt'); 4 | var writer = fs.createWriteStream('out.txt'); 5 | reader.pipe(writer); 6 | -------------------------------------------------------------------------------- /05/test01.js: -------------------------------------------------------------------------------- 1 | for (var i = 0; i < 1000000; i++) { 2 | var a = {}; 3 | } 4 | -------------------------------------------------------------------------------- /05/test02.js: -------------------------------------------------------------------------------- 1 | var a = {}; 2 | 3 | for (var i = 0; i < 100000; i++) { 4 | a['i' + i] = {}; 5 | } 6 | 7 | for (var j = 0; j < 1000000; j++) { 8 | var b = {}; 9 | } 10 | -------------------------------------------------------------------------------- /05/try_catch.js: -------------------------------------------------------------------------------- 1 | try { 2 | var foo = 'hehe'; 3 | throw new Error('just throw.'); 4 | } catch (ex) { 5 | console.log(foo); 6 | } 7 | -------------------------------------------------------------------------------- /06/allocate.js: -------------------------------------------------------------------------------- 1 | var buf = new Buffer(100); 2 | -------------------------------------------------------------------------------- /06/buf.js: -------------------------------------------------------------------------------- 1 | var buf = new Buffer('床前明月光,疑是地上霜;举头望明月,低头思故乡。', 'utf-8'); 2 | console.log(buf); 3 | console.log(buf.length); 4 | -------------------------------------------------------------------------------- /06/decoder.js: -------------------------------------------------------------------------------- 1 | var StringDecoder = require('string_decoder').StringDecoder; 2 | var decoder = new StringDecoder('utf8'); 3 | 4 | var buf1 = new Buffer([0xE5, 0xBA, 0x8A, 0xE5, 0x89, 0x8D, 0xE6, 0x98, 0x8E, 0xE6, 0x9C]); 5 | console.log(decoder.write(buf1)); 6 | // => 床前明 7 | 8 | var buf2 = new Buffer([0x88, 0xE5, 0x85, 0x89, 0xEF, 0xBC, 0x8C, 0xE7, 0x96, 0x91, 0xE6]); 9 | console.log(decoder.write(buf2)); 10 | // => 月光,疑 11 | -------------------------------------------------------------------------------- /06/demo.js: -------------------------------------------------------------------------------- 1 | var str = "深入浅出node.js"; 2 | var buf = new Buffer(str, 'utf-8'); 3 | console.log(buf); 4 | // 5 | 6 | var buf = new Buffer(100); 7 | console.log(buf.length); // 100 8 | console.log(buf[10]); // 0-255 9 | console.log(buf[11]); // 0-255 10 | 11 | buf[10] = 100; 12 | console.log(buf[10]); 13 | 14 | buf[20] = -300; 15 | console.log(buf[20]); // 212 16 | buf[21] = 300; 17 | console.log(buf[21]); // 44 18 | buf[22] = 3.1415; 19 | console.log(buf[22]); // 3 20 | buf[23] = 256; 21 | console.log(buf[23]); // 0 22 | buf[24] = 300.1415; 23 | console.log(buf[24]); // 44 24 | -------------------------------------------------------------------------------- /06/string.php: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /06/test.md: -------------------------------------------------------------------------------- 1 | 床前明月光,疑是地上霜;举头望明月,低头思故乡。 2 | -------------------------------------------------------------------------------- /06/transfer.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var helloworld = ""; 3 | 4 | for (var i = 0; i < 1024 * 10; i++) { 5 | helloworld += "a"; 6 | } 7 | 8 | var str = helloworld; 9 | var buf = new Buffer(helloworld); 10 | 11 | http.createServer(function (req, res) { 12 | res.writeHead(200); 13 | if (req.url === '/str') { 14 | res.write(helloworld); 15 | } else { 16 | res.write(buf); 17 | } 18 | res.end(); 19 | }).listen(8000); 20 | -------------------------------------------------------------------------------- /06/unicode.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | 4 | var rs = fs.createReadStream(path.join(__dirname, 'test.md'), {highWaterMark: 11}); 5 | var data = ''; 6 | rs.setEncoding('utf8'); 7 | rs.on("data", function (trunk) { 8 | console.log('data'); 9 | data += trunk; 10 | }); 11 | rs.on("end", function () { 12 | console.log(data); 13 | }); 14 | -------------------------------------------------------------------------------- /07/http/client.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | 3 | var options = { 4 | hostname: '127.0.0.1', 5 | port: 1337, 6 | path: '/', 7 | method: 'GET' 8 | }; 9 | 10 | var req = http.request(options, function(res) { 11 | console.log('STATUS: ' + res.statusCode); 12 | console.log('HEADERS: ' + JSON.stringify(res.headers)); 13 | res.setEncoding('utf8'); 14 | res.on('data', function (chunk) { 15 | console.log(chunk); 16 | }); 17 | }); 18 | console.log(req); 19 | req.end(); 20 | -------------------------------------------------------------------------------- /07/http/server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | http.createServer(function (req, res) { 3 | res.writeHead(200, {'Content-Type': 'text/plain'}); 4 | res.writeHead(200); 5 | res.end('Hello World\n'); 6 | res.writeHead(200); 7 | }).listen(1337, '127.0.0.1'); 8 | console.log('Server running at http://127.0.0.1:1337/'); 9 | -------------------------------------------------------------------------------- /07/https/client.js: -------------------------------------------------------------------------------- 1 | var https = require('https'); 2 | var fs = require('fs'); 3 | 4 | var options = { 5 | hostname: 'localhost', 6 | port: 8000, 7 | path: '/', 8 | method: 'GET', 9 | key: fs.readFileSync('./keys/client.key'), 10 | cert: fs.readFileSync('./keys/client.crt'), 11 | rejectUnauthorized: false, 12 | // ca: [fs.readFileSync('./keys/ca.crt')] 13 | }; 14 | 15 | options.agent = new https.Agent(options); 16 | 17 | var req = https.request(options, function(res) { 18 | res.setEncoding('utf-8'); 19 | res.on('data', function(d) { 20 | console.log(d); 21 | }); 22 | }); 23 | req.end(); 24 | 25 | req.on('error', function(e) { 26 | console.log(e); 27 | }); 28 | -------------------------------------------------------------------------------- /07/https/keys/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICGzCCAYQCCQC+xKuVHZhrcTANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMQswCQYDVQQDEwJDQTAeFw0xMzA2MjcxMjAwMjdaFw0xMzA3Mjcx 5 | MjAwMjdaMFIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD 6 | VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxCzAJBgNVBAMTAkNBMIGfMA0G 7 | CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+Voeq5IfnsuWpnpniFO4z3ZNQ9o6wRsJI 8 | 4cm9Fw5odc3MI3NK9xprUEaL7Y+NUOx/iZAU51NBuMrsGfJstAyw0D6NetNaoj88 9 | VoNFmQJ2djs70ri9oLyUGZ3ECO4xq/yPAkUlBhQQHIz0/TnqcOb9C8IzIDoBT5xr 10 | qT9xCUMY+wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAKsbBDtP1b9mU8rcssENq369 11 | ncKs7WoJFV9CJ/lUpfP6zx6OBv3cNMwxswHUlaKaNbLO5HF6ve76KUk8IAI7tFo1 12 | VXDVjFke8NQ0HlOYrZXMtjFHT/qdt0UisHFdY/qAIBSI1dX7ZG+HvWZ0KfyVCpjC 13 | kZuEf8yg/Tes6bgoZIst 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /07/https/keys/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICIjCCAYsCCQDFUlH2xGv4KTANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMQswCQYDVQQDEwJDQTAeFw0xMzA2MjcxMjIzMDZaFw0xMzA3Mjcx 5 | MjIzMDZaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD 6 | VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMUCW15X2NsaWVu 7 | dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8TDywiLJxQICx4cztfE8cGO 8 | 9vstAJBQVamZSqroYLEFwrFZ3DfxPunCo5pI1oFonds2D7U0vnhHKWtNK7P6pzaC 9 | vujN0m1udsbcw0q3AsqRwuSKqVBqeUxCB7pVNTljJL2qx85vjs6oZcb9Q466qcKR 10 | XTj9iMBshuObyXq7O3ECAwEAATANBgkqhkiG9w0BAQUFAAOBgQAJSHhSYb6JCb2B 11 | dY9az9ZRJjKdNEAIF+fMdxb3bGr9v6OvYyZXN6HnbrDkLQLkEJvwtfS8haLLUsIC 12 | CePkIDk3F02nSQAOSENK8lBOfofXxbk3IaynnO0NThsooIxaT/YoXXA9ArRlGBQJ 13 | uT5fqq0E3MHaIPp/JLw4cr4mMyx9Mg== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /07/https/keys/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQDLxMPLCIsnFAgLHhzO18TxwY72+y0AkFBVqZlKquhgsQXCsVnc 3 | N/E+6cKjmkjWgWid2zYPtTS+eEcpa00rs/qnNoK+6M3SbW52xtzDSrcCypHC5Iqp 4 | UGp5TEIHulU1OWMkvarHzm+Ozqhlxv1DjrqpwpFdOP2IwGyG45vJers7cQIDAQAB 5 | AoGAfme2ienn4LsVbkgk2M+TNeG73Uzdkt7zZuCJ3n79HpZSG3/HXcw6VKvQeYsJ 6 | KkAm9N36wG3JpWqZwoD042qHzzzqgMBJilCb4vbptupxzRY362RyjS7sGzfP4Qwi 7 | OI6qdEcIqkLtK2m2VmFelyga3cb2M5CIua1MgpIgwSUSx00CQQD1svMeUqYojx5B 8 | DhzsCF7U2aySvCXa9keUYtwOr9ee26Kak2JoWhZcA2zPOZHXeY0lrvs3M35giqSR 9 | H0quOqRDAkEA1E/ITChNVUMQ5ZdaCBupVLn8KPPs92t6erQDObotxe8HkKhZPfaz 10 | puQq4paS3O2w+y/H56fCSaDDMVMpKyUgOwJAIsxfhpHqGqB6hng7PGrLE5ZozLd9 11 | HQ/4f1mpFSNuhH9S/lWVgHYR6KJLjOX4c+4xQX8Q8XaHlaDNQgiOiTKhBQJAQDzH 12 | eKt1AoghM6ZAmlVsPXNsZSOwngfJ7hhLJYs8UDgLTOxy2/mpz6QXialPVEMimk2R 13 | qXiro0Vd6a2ktiYsgwJBAIIO6O5mLK8Bnzv20/nehXZgHG8O/sWvNjCjkF79/BF8 14 | /NNk4zJNF8zFmp/CsoWYc4Eg9h44KeczB4WNACx5No8= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /07/https/keys/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICIjCCAYsCCQDFUlH2xGv4KDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMQswCQYDVQQDEwJDQTAeFw0xMzA2MjcxMjAyMDNaFw0xMzA3Mjcx 5 | MjAyMDNaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD 6 | VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9z 7 | dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuDJ15pR/7NpP/PfePzcG86xF 8 | igez235q/pS+wGeQFYybTalUXhq8/U7DBshgRhk3mM0ILJTMSrA2lP0y0HezGqlN 9 | KWB/MWrrYHP49M1QUdL/LGDZAhdb6seksf2sdSXmekybEWJh8GYOv3VGQkZ+a3MR 10 | r+Y/8EqegLZ0z8jpSLsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQArWnpsHcQJyA1O 11 | mTwOsvKILj8HQ2lCWu9Psh2QRj7I0oG6SB7UryylAHbbn0a+rE1uxyxR03RbBq2T 12 | DbJpb9pMrqLWpDNhXQio2sdoGaW2SVVsRTE9QeRg3OGda0FCGha9DT9YIADPV5rk 13 | bbgk2/iPHdNoQI7fXE4k6EDL8ht0+A== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /07/https/keys/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQC4MnXmlH/s2k/8994/NwbzrEWKB7Pbfmr+lL7AZ5AVjJtNqVRe 3 | Grz9TsMGyGBGGTeYzQgslMxKsDaU/TLQd7MaqU0pYH8xautgc/j0zVBR0v8sYNkC 4 | F1vqx6Sx/ax1JeZ6TJsRYmHwZg6/dUZCRn5rcxGv5j/wSp6AtnTPyOlIuwIDAQAB 5 | AoGAEp4HDKc1xtrJ+ueSrxEAwuBGpwzgQO8mIVUncosFJShxCghzXo+VSoULcUQP 6 | dwZVeDxA90CS5XmqCqUM3cU7dOp2kBMK6DIEOOZbYlnLDffg03LBt5KeDUULDC7h 7 | aFFZWipKWdrJNLU6GdS71HaYCgf7kGOWJoovO6wORKWMcAECQQDjQ1hCX1StkDCF 8 | KtFotMw6nnKTiUpEpDD9pd6Xhr94D/Q1HSeT/5pbXFMJQL/lroFL9pu6vF+Y7620 9 | tq+X9iD7AkEAz30K3z721F+2U26THZi/m4QnHOFAUAbhPoslQcHgPTt9S0JkCt1o 10 | py/8i1bG7BPo6kpeZ9w3ozzR88EwvUZrQQJBAL9fT2wcwL6jA+ivhMWqMaxPDuak 11 | HpEsvkBps8ZfZs5giOFNGq3q+H1kglvxVWbBCwn/sWWPCOVNNzZM/BJ35Y8CQDoZ 12 | SmUOrXD0SAp+qOUds3FphMY6cJa4BnRL5CfQkOi0crYTJg5AxyAheLbPmq3aOVr5 13 | bgvpBw9HZYa6rtohEMECQQCxjwnOdrS0r1/kdE6X877YrPdG/MeZQN/dAMtXIuUY 14 | oO4gjTKLu8xWP1CIa+rhi+cx8trkNioOAP6xGsb8+rDP 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /07/https/server.js: -------------------------------------------------------------------------------- 1 | var https = require('https'); 2 | var fs = require('fs'); 3 | 4 | var options = { 5 | key: fs.readFileSync('./keys/server.key'), 6 | cert: fs.readFileSync('./keys/server.crt') 7 | }; 8 | 9 | https.createServer(options, function (req, res) { 10 | res.writeHead(200); 11 | res.end("hello world\n"); 12 | }).listen(8000); 13 | -------------------------------------------------------------------------------- /07/tcp/client.js: -------------------------------------------------------------------------------- 1 | var net = require('net'); 2 | var client = net.connect({port: 8124}, function () { //'connect' listener 3 | console.log('client connected'); 4 | client.write('world!\r\n'); 5 | }); 6 | 7 | client.on('data', function (data) { 8 | console.log(data.toString()); 9 | client.end(); 10 | }); 11 | 12 | client.on('end', function () { 13 | console.log('client disconnected'); 14 | }); 15 | -------------------------------------------------------------------------------- /07/tcp/echo.js: -------------------------------------------------------------------------------- 1 | var net = require('net'); 2 | 3 | var server = net.createServer(function (socket) { 4 | socket.write('Echo server\r\n'); 5 | socket.pipe(socket); 6 | }); 7 | 8 | server.listen(1337, '127.0.0.1'); 9 | -------------------------------------------------------------------------------- /07/tcp/server.js: -------------------------------------------------------------------------------- 1 | var net = require('net'); 2 | 3 | var server = net.createServer(function (socket) { 4 | // 新的连接 5 | socket.on('data', function (data) { 6 | socket.write("你好"); 7 | }); 8 | 9 | socket.on('end', function () { 10 | console.log('客户端断开'); 11 | }); 12 | socket.write("欢迎光临《深入浅出Node.js》示例:\n"); 13 | }); 14 | 15 | server.listen(8124, function () { 16 | console.log('server bound'); 17 | }); 18 | 19 | // server.listen('/tmp/echo.sock', function () { 20 | // console.log(arguments); 21 | // }); 22 | -------------------------------------------------------------------------------- /07/tls/client.js: -------------------------------------------------------------------------------- 1 | var tls = require('tls'); 2 | var fs = require('fs'); 3 | 4 | var options = { 5 | key: fs.readFileSync('./keys/client.key'), 6 | cert: fs.readFileSync('./keys/client.crt'), 7 | ca: [ fs.readFileSync('./keys/ca.crt') ] 8 | }; 9 | 10 | var stream = tls.connect(8000, options, function () { 11 | console.log('client connected', stream.authorized ? 'authorized' : 'unauthorized'); 12 | process.stdin.pipe(stream); 13 | }); 14 | 15 | stream.setEncoding('utf8'); 16 | stream.on('data', function(data) { 17 | console.log(data); 18 | }); 19 | stream.on('end', function() { 20 | server.close(); 21 | }); 22 | -------------------------------------------------------------------------------- /07/tls/keys/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICGzCCAYQCCQC+xKuVHZhrcTANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMQswCQYDVQQDEwJDQTAeFw0xMzA2MjcxMjAwMjdaFw0xMzA3Mjcx 5 | MjAwMjdaMFIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD 6 | VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxCzAJBgNVBAMTAkNBMIGfMA0G 7 | CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+Voeq5IfnsuWpnpniFO4z3ZNQ9o6wRsJI 8 | 4cm9Fw5odc3MI3NK9xprUEaL7Y+NUOx/iZAU51NBuMrsGfJstAyw0D6NetNaoj88 9 | VoNFmQJ2djs70ri9oLyUGZ3ECO4xq/yPAkUlBhQQHIz0/TnqcOb9C8IzIDoBT5xr 10 | qT9xCUMY+wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAKsbBDtP1b9mU8rcssENq369 11 | ncKs7WoJFV9CJ/lUpfP6zx6OBv3cNMwxswHUlaKaNbLO5HF6ve76KUk8IAI7tFo1 12 | VXDVjFke8NQ0HlOYrZXMtjFHT/qdt0UisHFdY/qAIBSI1dX7ZG+HvWZ0KfyVCpjC 13 | kZuEf8yg/Tes6bgoZIst 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /07/tls/keys/ca.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBkTCB+wIBADBSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEh 3 | MB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCB 4 | nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvlaHquSH57LlqZ6Z4hTuM92TUPaO 5 | sEbCSOHJvRcOaHXNzCNzSvcaa1BGi+2PjVDsf4mQFOdTQbjK7BnybLQMsNA+jXrT 6 | WqI/PFaDRZkCdnY7O9K4vaC8lBmdxAjuMav8jwJFJQYUEByM9P056nDm/QvCMyA6 7 | AU+ca6k/cQlDGPsCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBABHEav3o+ykw/yNm 8 | IK0QEeptM7G00VQyIHNF13DPyeDyiNa3K2GW6It1MM9bQ/E3lB9N0P2ZKXMUs2F3 9 | nV301QVRMuZoXG1OR1yVQYVCf/sDOsmDRP7tpGmJotk4G789BJMbqyGN+75i3xCb 10 | VqJcMUiukx/IXLKuV4Lxd9U/aFHK 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /07/tls/keys/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXgIBAAKBgQC+Voeq5IfnsuWpnpniFO4z3ZNQ9o6wRsJI4cm9Fw5odc3MI3NK 3 | 9xprUEaL7Y+NUOx/iZAU51NBuMrsGfJstAyw0D6NetNaoj88VoNFmQJ2djs70ri9 4 | oLyUGZ3ECO4xq/yPAkUlBhQQHIz0/TnqcOb9C8IzIDoBT5xrqT9xCUMY+wIDAQAB 5 | AoGBALQyPXyXoObFYlJkObFlOWJW6mojElFmm/bd890Vn+lbZftWsIcPS66/MBq3 6 | TElwjIXt2T9BBXxaE5rUscMh7kQw2vgOmkWhpE8IGZmiUcqNZD32Q+pMhu/LEAmi 7 | gzGbGbgYfFyDw4g8GWdVY21RzeJLfqntoTn5uRpReIbWp8XhAkEA3YTNBL+x4rlC 8 | +xuBrIZPKHHy/fzVj3vYGHnQJIsDXWi6R9mWHJX48RjOix7i1snZrABVC4KZsIiF 9 | oSZvXVmIqwJBANv3OMyEE4OLGqPeSn2d2Od9giO6PcvfYRQ3P09JF2oa5FHU2s9d 10 | xGLuBfZYmHMhU2EB9aoFRNOko8kluc/MUPECQQCD2WeuS+s1Z8/WZqjoZ4j2KdzY 11 | EIWMwcn9x4N8PMHj91HpMjmHCj0CRCGr7NZXwg0ts4TrNPEFgj0Hjjj69y/BAkB4 12 | hEw/aYHTiaxv6gQALTLBKnfaIVloURw8WkS6qP5GKTO9ThUQlnxaA7WKkmH8el7X 13 | gJ5bqAVcvBDszVmv627RAkEAllFfxLvBR8cJXfTqTbDy+ICV3U4mzHq6SIvpAp6R 14 | 4NrfyO+/Q7cSVWGnuT1w4U+r4I8i8EzfQbsA5XpI6LpTmQ== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /07/tls/keys/ca.srl: -------------------------------------------------------------------------------- 1 | C55251F6C46BF829 2 | -------------------------------------------------------------------------------- /07/tls/keys/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICIjCCAYsCCQDFUlH2xGv4KTANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMQswCQYDVQQDEwJDQTAeFw0xMzA2MjcxMjIzMDZaFw0xMzA3Mjcx 5 | MjIzMDZaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD 6 | VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMUCW15X2NsaWVu 7 | dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8TDywiLJxQICx4cztfE8cGO 8 | 9vstAJBQVamZSqroYLEFwrFZ3DfxPunCo5pI1oFonds2D7U0vnhHKWtNK7P6pzaC 9 | vujN0m1udsbcw0q3AsqRwuSKqVBqeUxCB7pVNTljJL2qx85vjs6oZcb9Q466qcKR 10 | XTj9iMBshuObyXq7O3ECAwEAATANBgkqhkiG9w0BAQUFAAOBgQAJSHhSYb6JCb2B 11 | dY9az9ZRJjKdNEAIF+fMdxb3bGr9v6OvYyZXN6HnbrDkLQLkEJvwtfS8haLLUsIC 12 | CePkIDk3F02nSQAOSENK8lBOfofXxbk3IaynnO0NThsooIxaT/YoXXA9ArRlGBQJ 13 | uT5fqq0E3MHaIPp/JLw4cr4mMyx9Mg== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /07/tls/keys/client.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBmTCCAQICAQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAxQJbXlf 4 | Y2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLxMPLCIsnFAgLHhzO 5 | 18TxwY72+y0AkFBVqZlKquhgsQXCsVncN/E+6cKjmkjWgWid2zYPtTS+eEcpa00r 6 | s/qnNoK+6M3SbW52xtzDSrcCypHC5IqpUGp5TEIHulU1OWMkvarHzm+Ozqhlxv1D 7 | jrqpwpFdOP2IwGyG45vJers7cQIDAQABoAAwDQYJKoZIhvcNAQEFBQADgYEAXHOB 8 | 6Lt/ktZZ2RUe7Dzb9jNECZl+A2gjDk8MaVHEvUtKBpt02AMW3dCcjS1Z/FIKR6dt 9 | xcRv2WyNLLSTXaZL3RS9tI314GJ32twOlu6E+n4siy0dMEmBudL9eyXDHXoMHH7D 10 | tO41gGLTfXYv6PVDuA7RQVEWt/BZc2EbnY/awAA= 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /07/tls/keys/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQDLxMPLCIsnFAgLHhzO18TxwY72+y0AkFBVqZlKquhgsQXCsVnc 3 | N/E+6cKjmkjWgWid2zYPtTS+eEcpa00rs/qnNoK+6M3SbW52xtzDSrcCypHC5Iqp 4 | UGp5TEIHulU1OWMkvarHzm+Ozqhlxv1DjrqpwpFdOP2IwGyG45vJers7cQIDAQAB 5 | AoGAfme2ienn4LsVbkgk2M+TNeG73Uzdkt7zZuCJ3n79HpZSG3/HXcw6VKvQeYsJ 6 | KkAm9N36wG3JpWqZwoD042qHzzzqgMBJilCb4vbptupxzRY362RyjS7sGzfP4Qwi 7 | OI6qdEcIqkLtK2m2VmFelyga3cb2M5CIua1MgpIgwSUSx00CQQD1svMeUqYojx5B 8 | DhzsCF7U2aySvCXa9keUYtwOr9ee26Kak2JoWhZcA2zPOZHXeY0lrvs3M35giqSR 9 | H0quOqRDAkEA1E/ITChNVUMQ5ZdaCBupVLn8KPPs92t6erQDObotxe8HkKhZPfaz 10 | puQq4paS3O2w+y/H56fCSaDDMVMpKyUgOwJAIsxfhpHqGqB6hng7PGrLE5ZozLd9 11 | HQ/4f1mpFSNuhH9S/lWVgHYR6KJLjOX4c+4xQX8Q8XaHlaDNQgiOiTKhBQJAQDzH 12 | eKt1AoghM6ZAmlVsPXNsZSOwngfJ7hhLJYs8UDgLTOxy2/mpz6QXialPVEMimk2R 13 | qXiro0Vd6a2ktiYsgwJBAIIO6O5mLK8Bnzv20/nehXZgHG8O/sWvNjCjkF79/BF8 14 | /NNk4zJNF8zFmp/CsoWYc4Eg9h44KeczB4WNACx5No8= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /07/tls/keys/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICIjCCAYsCCQDFUlH2xGv4KDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMQswCQYDVQQDEwJDQTAeFw0xMzA2MjcxMjAyMDNaFw0xMzA3Mjcx 5 | MjAyMDNaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD 6 | VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9z 7 | dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuDJ15pR/7NpP/PfePzcG86xF 8 | igez235q/pS+wGeQFYybTalUXhq8/U7DBshgRhk3mM0ILJTMSrA2lP0y0HezGqlN 9 | KWB/MWrrYHP49M1QUdL/LGDZAhdb6seksf2sdSXmekybEWJh8GYOv3VGQkZ+a3MR 10 | r+Y/8EqegLZ0z8jpSLsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQArWnpsHcQJyA1O 11 | mTwOsvKILj8HQ2lCWu9Psh2QRj7I0oG6SB7UryylAHbbn0a+rE1uxyxR03RbBq2T 12 | DbJpb9pMrqLWpDNhXQio2sdoGaW2SVVsRTE9QeRg3OGda0FCGha9DT9YIADPV5rk 13 | bbgk2/iPHdNoQI7fXE4k6EDL8ht0+A== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /07/tls/keys/server.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBmTCCAQICAQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAxMJbG9j 4 | YWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4MnXmlH/s2k/8994/ 5 | NwbzrEWKB7Pbfmr+lL7AZ5AVjJtNqVReGrz9TsMGyGBGGTeYzQgslMxKsDaU/TLQ 6 | d7MaqU0pYH8xautgc/j0zVBR0v8sYNkCF1vqx6Sx/ax1JeZ6TJsRYmHwZg6/dUZC 7 | Rn5rcxGv5j/wSp6AtnTPyOlIuwIDAQABoAAwDQYJKoZIhvcNAQEFBQADgYEAo33u 8 | y4phu0pbaaLAV9KvKIyciFrK5iJ867966nkVMFtY06ILSbTV+rRNupE9c9gsGBB8 9 | Ro/hq3adhynAf0kj960iVEuQxBV5LpSHVNdpuUsF1FGCnSK+CN/rpYwEwRZxU/ha 10 | dOdSd/mrH6aHyGpRhQBjDYuB+/xoSbDD0bxZUEU= 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /07/tls/keys/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQC4MnXmlH/s2k/8994/NwbzrEWKB7Pbfmr+lL7AZ5AVjJtNqVRe 3 | Grz9TsMGyGBGGTeYzQgslMxKsDaU/TLQd7MaqU0pYH8xautgc/j0zVBR0v8sYNkC 4 | F1vqx6Sx/ax1JeZ6TJsRYmHwZg6/dUZCRn5rcxGv5j/wSp6AtnTPyOlIuwIDAQAB 5 | AoGAEp4HDKc1xtrJ+ueSrxEAwuBGpwzgQO8mIVUncosFJShxCghzXo+VSoULcUQP 6 | dwZVeDxA90CS5XmqCqUM3cU7dOp2kBMK6DIEOOZbYlnLDffg03LBt5KeDUULDC7h 7 | aFFZWipKWdrJNLU6GdS71HaYCgf7kGOWJoovO6wORKWMcAECQQDjQ1hCX1StkDCF 8 | KtFotMw6nnKTiUpEpDD9pd6Xhr94D/Q1HSeT/5pbXFMJQL/lroFL9pu6vF+Y7620 9 | tq+X9iD7AkEAz30K3z721F+2U26THZi/m4QnHOFAUAbhPoslQcHgPTt9S0JkCt1o 10 | py/8i1bG7BPo6kpeZ9w3ozzR88EwvUZrQQJBAL9fT2wcwL6jA+ivhMWqMaxPDuak 11 | HpEsvkBps8ZfZs5giOFNGq3q+H1kglvxVWbBCwn/sWWPCOVNNzZM/BJ35Y8CQDoZ 12 | SmUOrXD0SAp+qOUds3FphMY6cJa4BnRL5CfQkOi0crYTJg5AxyAheLbPmq3aOVr5 13 | bgvpBw9HZYa6rtohEMECQQCxjwnOdrS0r1/kdE6X877YrPdG/MeZQN/dAMtXIuUY 14 | oO4gjTKLu8xWP1CIa+rhi+cx8trkNioOAP6xGsb8+rDP 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /07/tls/server.js: -------------------------------------------------------------------------------- 1 | var tls = require('tls'); 2 | var fs = require('fs'); 3 | 4 | var options = { 5 | key: fs.readFileSync('./keys/server.key'), 6 | cert: fs.readFileSync('./keys/server.crt'), 7 | requestCert: true, 8 | ca: [ fs.readFileSync('./keys/ca.crt') ] 9 | }; 10 | 11 | var server = tls.createServer(options, function (stream) { 12 | console.log('server connected', stream.authorized ? 'authorized' : 'unauthorized'); 13 | stream.write("welcome!\n"); 14 | stream.setEncoding('utf8'); 15 | stream.pipe(stream); 16 | }); 17 | server.listen(8000, function() { 18 | console.log('server bound'); 19 | }); 20 | -------------------------------------------------------------------------------- /07/udp/client.js: -------------------------------------------------------------------------------- 1 | var dgram = require('dgram'); 2 | 3 | var message = new Buffer("深入浅出Node.js"); 4 | var client = dgram.createSocket("udp4"); 5 | client.send(message, 0, message.length, 41234, "localhost", function(err, bytes) { 6 | client.close(); 7 | }); 8 | -------------------------------------------------------------------------------- /07/udp/server.js: -------------------------------------------------------------------------------- 1 | var dgram = require("dgram"); 2 | 3 | var server = dgram.createSocket("udp4"); 4 | 5 | server.on("message", function (msg, rinfo) { 6 | console.log("server got: " + msg + " from " + 7 | rinfo.address + ":" + rinfo.port); 8 | }); 9 | 10 | server.on("listening", function () { 11 | var address = server.address(); 12 | console.log("server listening " + 13 | address.address + ":" + address.port); 14 | }); 15 | 16 | server.bind(41234); 17 | -------------------------------------------------------------------------------- /07/websocket/server.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacksonTian/diveintonode_examples/68564ca0eff8ebb07269ce8c26df41d51b22f5e5/07/websocket/server.js -------------------------------------------------------------------------------- /08/bagpipe/assets/render.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /08/bagpipe/server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | var url = require('url'); 4 | var path = require('path'); 5 | var querystring = require('querystring'); 6 | 7 | var mime = require('mime'); 8 | 9 | var framework = function (req, res) { 10 | var index = -1; 11 | var next = function () { 12 | index++; 13 | var middleware = framework.stack[index]; 14 | middleware.handle(req, res, next); 15 | }; 16 | next(); 17 | }; 18 | 19 | framework.stack = []; 20 | 21 | framework.use = function (route, handle) { 22 | if (typeof route === 'function') { 23 | handle = route; 24 | route = '/'; 25 | } 26 | framework.stack.push({route: route, handle: handle}); 27 | }; 28 | 29 | var server = function () { 30 | return framework; 31 | }; 32 | 33 | server.staticFile = function (root) { 34 | return function (req, res, next) { 35 | var pathname = url.parse(req.url).pathname; 36 | fs.readFile(path.join(root, pathname), function (err, file) { 37 | if (err) { 38 | if (err.code === 'ENOENT') { 39 | return next(); 40 | } else { 41 | return next(err); 42 | } 43 | } 44 | res.writeHead(200, {'Content-Type': mime.lookup(pathname)}); 45 | res.end(file); 46 | }); 47 | }; 48 | }; 49 | 50 | server.render = function (viewpath) { 51 | var cache = {}; 52 | 53 | var complie = function (str) { 54 | var tpl = str.replace(/\n/g, '\\n') 55 | .replace(/<%=([\s\S]+?)%>/g, function (match, code) { 56 | // 转义 57 | return "' + escape(" + code + ") + '"; 58 | }).replace(/<%=([\s\S]+?)%>/g, function (match, code) { 59 | // 正常输出 60 | return "' + " + code + "+ '"; 61 | }).replace(/<%([\s\S]+?)%>/g, function (match, code) { 62 | // 可执行代码 63 | return "';\n" + code + "\ntpl += '"; 64 | }).replace(/\'\n/g, '\'') 65 | .replace(/\n\'/gm, '\''); 66 | 67 | tpl = "tpl = '" + tpl + "';"; 68 | // 转换空行 69 | tpl = tpl.replace(/''/g, '\'\\n\''); 70 | tpl = 'var tpl = "";\nwith (obj || {}) {\n' + tpl + '\n}\nreturn tpl;'; 71 | console.log(tpl); 72 | return new Function('obj', 'escape', tpl); 73 | }; 74 | 75 | http.ServerResponse.prototype.render = function (viewname, data) { 76 | var res = this; 77 | if (!cache[viewname]) { 78 | var text; 79 | try { 80 | text = fs.readFileSync(path.join(viewpath, viewname), 'utf8'); 81 | } catch (ex) { 82 | res.writeHead(500, {'Content-Type': 'text/html'}); 83 | res.end('模版文件错误'); 84 | return; 85 | } 86 | cache[viewname] = complie(text); 87 | } 88 | var complied = cache[viewname]; 89 | res.writeHead(200, {'Content-Type': 'text/html'}); 90 | var html = complied(data); 91 | res.end(html); 92 | }; 93 | return function (req, res, next) { 94 | next(); 95 | }; 96 | }; 97 | 98 | var app = server(); 99 | app.use(server.staticFile(path.join(__dirname, 'assets'))); 100 | app.use(server.render(path.join(__dirname, 'views'))); 101 | app.use(function (req, res, next) { 102 | res.render('index.html'); 103 | }); 104 | 105 | http.createServer(app).listen(3001, function () { 106 | console.log('start at 3001'); 107 | }); 108 | -------------------------------------------------------------------------------- /08/bagpipe/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bagpipe示例 5 | 6 | 7 | 8 | 9 | 11 |
12 | 14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /08/mime.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | http.createServer(function (req, res) { 3 | // res.writeHead(200, {'Content-Type': 'text/plain'}); 4 | // res.end('Hello World\n'); 5 | // 或者 6 | res.writeHead(200, {'Content-Type': 'text/html'}); 7 | res.end('Hello World\n'); 8 | }).listen(1337); 9 | console.log('Server running at http://127.0.0.1:1337/'); 10 | -------------------------------------------------------------------------------- /08/server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var url = require('url'); 3 | 4 | var parseCookie = function (cookie) { 5 | var cookies = {}; 6 | if (!cookie) { 7 | return cookies; 8 | } 9 | 10 | var list = cookie.split(';'); 11 | for (var i = 0; i < list.length; i++) { 12 | var pair = list[i].split('='); 13 | cookies[pair[0].trim()] = pair[1]; 14 | } 15 | return cookies; 16 | }; 17 | var checkUser = function () { 18 | return false; 19 | }; 20 | http.createServer(function (req, res) { 21 | // console.log(req.method); 22 | // console.log(req.url); 23 | // console.log(url.parse(req.url, true).query); 24 | console.log(req.headers); 25 | // console.log(parseCookie(req.headers.cookie)); 26 | // res.setHeader('Location', '/pathname?session_id=hehe'); 27 | // res.writeHead(302); 28 | // res.end(); 29 | res.writeHead(200, {'Content-Type': 'text/plain'}); 30 | res.end('Hello World\n'); 31 | // var auth = req.headers['authorization'] || ''; 32 | // var parts = auth.split(' '); 33 | // var method = parts[0] || ''; // Basic 34 | // var encoded = parts[1] || ''; // dXNlcjpwYXNz 35 | // var decoded = new Buffer(encoded, 'base64').toString('utf-8').split(":"); 36 | // var user = decoded[0]; // user 37 | // var pass = decoded[1]; // pass 38 | // if (!checkUser(user, pass)) { 39 | // res.setHeader('WWW-Authenticate', 'Basic realm="Secure Area"'); 40 | // res.writeHead(401); 41 | // res.end(); 42 | // } else { 43 | // res.writeHead(200, {'Content-Type': 'text/plain', 'Server': 'hehe'}); 44 | // res.end('Hello World\n'); 45 | // } 46 | }).listen(1337, '127.0.0.1'); 47 | console.log('Server running at http://127.0.0.1:1337/'); 48 | 49 | // function (req, res) { 50 | // switch (req.method) { 51 | // case 'POST': 52 | // update(req, res); 53 | // break; 54 | // case 'DELETE': 55 | // remove(req, res); 56 | // break; 57 | // case 'PUT': 58 | // create(req, res); 59 | // break; 60 | // case 'GET': 61 | // default: 62 | // get(req, res); 63 | // } 64 | // } 65 | 66 | -------------------------------------------------------------------------------- /08/template.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | 4 | var escape = function (html) { 5 | return String(html) 6 | .replace(/&(?!\w+;)/g, '&') 7 | .replace(//g, '>') 9 | .replace(/"/g, '"'); 10 | }; 11 | 12 | var complie = function (str) { 13 | var tpl = str.replace(/<%=([\s\S]+?)%>/g, function (match, code) { 14 | // 转义 15 | return "' + escape(" + code + ") + '"; 16 | }).replace(/<%-([\s\S]+?)%>/g, function (match, code) { 17 | // 正常输出 18 | return "' + " + code + "+ '"; 19 | }).replace(/<%([\s\S]+?)%>/g, function (match, code) { 20 | return "';\n" + code + "\ntpl += '"; 21 | }).replace(/\'\n/g, '\'') 22 | .replace(/\n\'/gm, '\''); 23 | 24 | tpl = "tpl = '" + tpl + "';"; 25 | tpl = tpl.replace(/''/g, '\'\\n\''); 26 | tpl = 'var tpl = "";\nwith (obj || {}) {\n' + tpl + '\n}\nreturn tpl;'; 27 | return new Function('obj', 'escape', tpl); 28 | }; 29 | 30 | var render = function (tpl, data) { 31 | return tpl.call(this, data, escape); 32 | }; 33 | 34 | var tpl = 'Hello <%=username%>.'; 35 | 36 | console.log(render(complie(tpl), {username: ''})); 37 | 38 | var tpl2 = [ 39 | '<% if (obj.user) { %>', 40 | '

<%=user.name%>

', 41 | '<% } else { %>', 42 | '

匿名用户

', 43 | '<% } %>'].join('\n'); 44 | 45 | console.log(render(complie(tpl2), {user: {name: 'Jackson Tian'}})); 46 | 47 | console.log(render(complie(tpl2), {})); 48 | 49 | var tpl3 = [ 50 | '<% for (var i = 0; i < items.length; i++) { %>', 51 | '<%var item = items[i];%>', 52 | '

<%= i+1 %>、<%=item.name%>

', 53 | '<% } %>' 54 | ].join('\n'); 55 | // console.log(render(complie(tpl3), {items: []})); 56 | console.log(render(complie(tpl3), {items: [{name: 'Jackson'}, {name: '朴灵'}]})); 57 | 58 | var preComplie = function (str) { 59 | return str.replace(/<%\s+(include.*)\s+%>/g, function (match, code) { 60 | var partial = code.split(/\s/)[1]; 61 | return fs.readFileSync(path.join('/path/to/views', partial), 'utf8'); 62 | }); 63 | }; 64 | 65 | var view = ['
    ', 66 | '<% users.forEach(function(user){ %>', 67 | '<% include user %>', 68 | '<% }) %>', 69 | '
'].join('\n'); 70 | 71 | var partial = '
  • <%=user.name%>
  • '; 72 | 73 | console.log(preComplie(view)); 74 | -------------------------------------------------------------------------------- /09/cluster.js: -------------------------------------------------------------------------------- 1 | var cluster = require('cluster'); 2 | 3 | cluster.setupMaster({ 4 | exec : "worker.js" 5 | }); 6 | 7 | var cpus = require('os').cpus(); 8 | for (var i = 0; i < cpus.length; i++) { 9 | cluster.fork(); 10 | } 11 | 12 | cluster.on('exit', function(worker, code, signal) { 13 | var exitCode = worker.process.exitCode; 14 | console.log('worker ' + worker.process.pid + ' died (' + exitCode + '). restarting...'); 15 | cluster.fork(); 16 | }); 17 | -------------------------------------------------------------------------------- /09/handle/1/child.js: -------------------------------------------------------------------------------- 1 | process.on('message', function (m, server) { 2 | if (m === 'server') { 3 | server.on('connection', function (socket) { 4 | socket.end('handled by child\n'); 5 | }); 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /09/handle/1/parent.js: -------------------------------------------------------------------------------- 1 | var child = require('child_process').fork('child.js'); 2 | 3 | // Open up the server object and send the handle. 4 | var server = require('net').createServer(); 5 | server.on('connection', function (socket) { 6 | socket.end('handled by parent\n'); 7 | }); 8 | server.listen(1337, function () { 9 | child.send('server', server); 10 | }); 11 | -------------------------------------------------------------------------------- /09/handle/2/child.js: -------------------------------------------------------------------------------- 1 | // child.js 2 | process.on('message', function (m, server) { 3 | if (m === 'server') { 4 | server.on('connection', function (socket) { 5 | socket.end('handled by child, pid is ' + process.pid + '\n'); 6 | }); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /09/handle/2/parent.js: -------------------------------------------------------------------------------- 1 | // parent.js 2 | var cp = require('child_process'); 3 | var child1 = cp.fork('child.js'); 4 | var child2 = cp.fork('child.js'); 5 | 6 | // Open up the server object and send the handle. 7 | var server = require('net').createServer(); 8 | server.on('connection', function (socket) { 9 | socket.end('handled by parent\n'); 10 | }); 11 | server.listen(1337, function () { 12 | child1.send('server', server); 13 | child2.send('server', server); 14 | }); 15 | -------------------------------------------------------------------------------- /09/handle/3/child.js: -------------------------------------------------------------------------------- 1 | // child.js 2 | var http = require('http'); 3 | var server = http.createServer(function (req, res) { 4 | res.writeHead(200, {'Content-Type': 'text/plain'}); 5 | res.end('handled by child, pid is ' + process.pid + '\n'); 6 | }); 7 | 8 | process.on('message', function (m, tcp) { 9 | if (m === 'server') { 10 | tcp.on('connection', function (socket) { 11 | server.emit('connection', socket); 12 | }); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /09/handle/3/parent.js: -------------------------------------------------------------------------------- 1 | var cp = require('child_process'); 2 | var child1 = cp.fork('child.js'); 3 | var child2 = cp.fork('child.js'); 4 | 5 | // Open up the server object and send the handle. 6 | var server = require('net').createServer(); 7 | server.listen(1337, function () { 8 | child1.send('server', server); 9 | child2.send('server', server); 10 | server.close(); 11 | }); 12 | -------------------------------------------------------------------------------- /09/master.js: -------------------------------------------------------------------------------- 1 | var fork = require('child_process').fork; 2 | var cpus = require('os').cpus(); 3 | for (var i = 0; i < cpus.length; i++) { 4 | fork(__dirname + '/worker.js'); 5 | } 6 | -------------------------------------------------------------------------------- /09/pm/master.js: -------------------------------------------------------------------------------- 1 | var fork = require('child_process').fork; 2 | var cpus = require('os').cpus(); 3 | 4 | var server = require('net').createServer(); 5 | server.listen(1337); 6 | 7 | var workers = {}; 8 | var createWorker = function () { 9 | var worker = fork(__dirname + '/worker.js'); 10 | worker.on('exit', function () { 11 | console.log('Worker ' + worker.pid + ' exited.'); 12 | delete workers[worker.pid]; 13 | createWorker(); 14 | }); 15 | worker.send('server', server); 16 | workers[worker.pid] = worker; 17 | console.log('Create worker. pid: ' + worker.pid); 18 | }; 19 | 20 | for (var i = 0; i < cpus.length; i++) { 21 | createWorker(); 22 | } 23 | 24 | process.on('exit', function () { 25 | for (var pid in workers) { 26 | workers[pid].kill(); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /09/pm/worker.js: -------------------------------------------------------------------------------- 1 | // child.js 2 | var http = require('http'); 3 | var server = http.createServer(function (req, res) { 4 | res.writeHead(200, {'Content-Type': 'text/plain'}); 5 | res.end('handled by child, pid is ' + process.pid + '\n'); 6 | }); 7 | 8 | var worker; 9 | process.on('message', function (m, tcp) { 10 | if (m === 'server') { 11 | worker = tcp; 12 | worker.on('connection', function (socket) { 13 | server.emit('connection', socket); 14 | }); 15 | } 16 | }); 17 | 18 | process.on('uncaughtException', function () { 19 | worker.close(function () { 20 | process.exit(1); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /09/signal.js: -------------------------------------------------------------------------------- 1 | process.on('SIGTERM', function() { 2 | console.log('Got a SIGTERM, exiting...'); 3 | process.exit(1); 4 | }); 5 | 6 | console.log('server running with PID:', process.pid); 7 | process.kill(process.pid, 'SIGTERM'); 8 | -------------------------------------------------------------------------------- /09/suicide/master.js: -------------------------------------------------------------------------------- 1 | var fork = require('child_process').fork; 2 | var cpus = require('os').cpus(); 3 | 4 | var server = require('net').createServer(); 5 | server.listen(1337); 6 | 7 | var workers = {}; 8 | var createWorker = function () { 9 | var worker = fork(__dirname + '/worker.js'); 10 | // 退出时重新启动新的进程 11 | worker.on('message', function (message) { 12 | if (message.act === 'suicide') { 13 | createWorker(); 14 | } 15 | }); 16 | worker.on('exit', function () { 17 | console.log('Worker ' + worker.pid + ' exited.'); 18 | delete workers[worker.pid]; 19 | }); 20 | worker.send('server', server); 21 | workers[worker.pid] = worker; 22 | console.log('Create worker. pid: ' + worker.pid); 23 | }; 24 | 25 | for (var i = 0; i < cpus.length; i++) { 26 | createWorker(); 27 | } 28 | 29 | process.on('exit', function () { 30 | for (var pid in workers) { 31 | workers[pid].kill(); 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /09/suicide/worker.js: -------------------------------------------------------------------------------- 1 | // child.js 2 | var http = require('http'); 3 | var server = http.createServer(function (req, res) { 4 | res.writeHead(200, {'Content-Type': 'text/plain'}); 5 | res.end('handled by child, pid is ' + process.pid + '\n'); 6 | throw new Error('throw exception'); 7 | }); 8 | 9 | var worker; 10 | process.on('message', function (m, tcp) { 11 | if (m === 'server') { 12 | worker = tcp; 13 | worker.on('connection', function (socket) { 14 | server.emit('connection', socket); 15 | }); 16 | } 17 | }); 18 | 19 | process.on('uncaughtException', function (err) { 20 | process.send({act: 'suicide'}); 21 | // 停止接收新的连接 22 | worker.close(function () { 23 | // 所有已有连接断开后,退出进程 24 | process.exit(1); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /09/worker.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | http.createServer(function (req, res) { 3 | res.writeHead(200, {'Content-Type': 'text/plain'}); 4 | res.end('Hello World\n'); 5 | // }).listen(Math.round((1 + Math.random()) * 1000), '127.0.0.1'); 6 | }).listen(8080, '127.0.0.1'); 7 | -------------------------------------------------------------------------------- /10/cluster.js: -------------------------------------------------------------------------------- 1 | var cluster = require('cluster'); 2 | 3 | cluster.setupMaster({ 4 | exec: "server.js" 5 | }); 6 | 7 | var cpus = require('os').cpus(); 8 | for (var i = 0; i < cpus.length; i++) { 9 | cluster.fork(); 10 | } 11 | console.log('start ' + cpus.length + ' workers.'); 12 | -------------------------------------------------------------------------------- /10/for.js: -------------------------------------------------------------------------------- 1 | var nativeMap = function (arr, callback) { 2 | return arr.map(callback); 3 | }; 4 | var customMap = function (arr, callback) { 5 | var ret = []; 6 | for (var i = 0; i < arr.length; i++) { 7 | ret.push(callback(arr[i])); 8 | } 9 | return ret; 10 | }; 11 | 12 | var run = function (name, times, fn, arr, callback) { 13 | var start = (new Date()).getTime(); 14 | for (var i = 0; i < times; i++) { 15 | fn(arr, callback); 16 | } 17 | var end = (new Date()).getTime(); 18 | console.log('Running %s %d times cost %d ms', name, times, end - start); 19 | }; 20 | 21 | var callback = function (item) { 22 | return item; 23 | }; 24 | 25 | run('nativeMap', 1000000, nativeMap, [0, 1, 2, 3, 5, 6], callback); 26 | run('customMap', 1000000, customMap, [0, 1, 2, 3, 5, 6], callback); 27 | 28 | var Benchmark = require('benchmark'); 29 | 30 | var suite = new Benchmark.Suite(); 31 | 32 | var arr = [0, 1, 2, 3, 5, 6]; 33 | suite.add('nativeMap', function () { 34 | return arr.map(callback); 35 | }).add('customMap', function () { 36 | var ret = []; 37 | for (var i = 0; i < arr.length; i++) { 38 | ret.push(callback(arr[i])); 39 | } 40 | return ret; 41 | }) 42 | // add listeners 43 | .on('cycle', function(event) { 44 | // console.log(event); 45 | console.log(event.target.toString()); 46 | }) 47 | .on('complete', function() { 48 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 49 | }) 50 | // run async 51 | .run(); 52 | -------------------------------------------------------------------------------- /10/length.js: -------------------------------------------------------------------------------- 1 | var Benchmark = require('benchmark'); 2 | 3 | var suite = new Benchmark.Suite(); 4 | // add tests 5 | var list = []; 6 | for (var i = 0; i < 10000; i++) { 7 | list[i] = i; 8 | } 9 | 10 | suite.add('origin', function () { 11 | var sum = 0; 12 | for (var i = 0; i < list.length; i++) { 13 | sum += list[i]; 14 | } 15 | }) 16 | .add('refined', function () { 17 | var sum = 0; 18 | for (var i = 0, l = list.length; i < l; i++) { 19 | sum += list[i]; 20 | } 21 | }) 22 | // add listeners 23 | .on('cycle', function(event) { 24 | console.log(String(event.target)); 25 | }) 26 | .on('complete', function() { 27 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 28 | }) 29 | // run async 30 | .run(); 31 | -------------------------------------------------------------------------------- /10/map_for.js: -------------------------------------------------------------------------------- 1 | var Benchmark = require('benchmark'); 2 | 3 | var suite = new Benchmark.Suite(); 4 | 5 | var mymap1 = function (arr, callback) { 6 | var ret = []; 7 | for (var i = 0, l = arr.length; i < l; i++) { 8 | ret.push(callback(arr[i])); 9 | } 10 | return ret; 11 | }; 12 | var mymap2 = function (arr, callback) { 13 | var ret = []; 14 | for (var i = 0, l = arr.length; i < l; i++) { 15 | ret.push(callback(arr[i], i)); 16 | } 17 | return ret; 18 | }; 19 | var mymap3 = function (arr, callback) { 20 | var ret = []; 21 | for (var i = 0, l = arr.length; i < l; i++) { 22 | ret.push(callback(arr[i], i, arr)); 23 | } 24 | return ret; 25 | }; 26 | var mymap4 = function (arr, callback) { 27 | var ret = []; 28 | for (var i = 0, l = arr.length; i < l; i++) { 29 | ret.push(callback.call(arr, arr[i], i, arr)); 30 | } 31 | return ret; 32 | }; 33 | var mymap5 = function (arr, callback) { 34 | var ret = []; 35 | for (var i = 0, l = arr.length; i < l; i++) { 36 | ret.push(callback.apply(arr, [arr[i], i, arr])); 37 | } 38 | return ret; 39 | }; 40 | var mymap6 = function (arr, callback) { 41 | var ret = []; 42 | for (var i = 0, l = arr.length; i < l; i++) { 43 | ret.push(callback.apply(arr, [arr[i], i])); 44 | } 45 | return ret; 46 | }; 47 | var mymap7 = function (arr, callback) { 48 | var ret = []; 49 | for (var i = 0, l = arr.length; i < l; i++) { 50 | ret.push(callback.apply(arr, [arr[i]])); 51 | } 52 | return ret; 53 | }; 54 | 55 | // add tests 56 | var list = []; 57 | for (var i = 0; i < 10000; i++) { 58 | list[i] = i; 59 | } 60 | 61 | suite.add('map', function () { 62 | list.map(function (item) { 63 | return item * 2; 64 | }); 65 | }) 66 | .add('mymap1', function () { 67 | mymap1(list, function (item) { 68 | return item * 2; 69 | }); 70 | }) 71 | .add('mymap2', function () { 72 | mymap2(list, function (item) { 73 | return item * 2; 74 | }); 75 | }) 76 | .add('mymap3', function () { 77 | mymap3(list, function (item) { 78 | return item * 2; 79 | }); 80 | }) 81 | .add('mymap4', function () { 82 | mymap4(list, function (item) { 83 | return item * 2; 84 | }); 85 | }) 86 | .add('mymap5', function () { 87 | mymap5(list, function (item) { 88 | return item * 2; 89 | }); 90 | }) 91 | .add('mymap6', function () { 92 | mymap6(list, function (item) { 93 | return item * 2; 94 | }); 95 | }) 96 | .add('mymap7', function () { 97 | mymap6(list, function (item) { 98 | return item * 2; 99 | }); 100 | }) 101 | .add('for push', function () { 102 | var ret = []; 103 | for (var i = 0, l = list.length; i < l; i++) { 104 | ret.push(list[i] * 2); 105 | } 106 | }) 107 | .add('for index', function () { 108 | var ret = []; 109 | for (var i = 0, l = list.length; i < l; i++) { 110 | ret[i] = list[i] * 2; 111 | } 112 | }) 113 | // add listeners 114 | .on('cycle', function(event) { 115 | console.log(String(event.target)); 116 | }) 117 | .on('complete', function() { 118 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 119 | }) 120 | // run async 121 | .run(); 122 | -------------------------------------------------------------------------------- /10/server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var helloworld = ""; 3 | 4 | for (var i = 0; i < 1024 * 10; i++) { 5 | helloworld += "a"; 6 | } 7 | 8 | helloworld = new Buffer(helloworld); 9 | 10 | http.createServer(function (req, res) { 11 | res.writeHead(200); 12 | res.end(helloworld); 13 | }).listen(8001); 14 | -------------------------------------------------------------------------------- /10/test.js: -------------------------------------------------------------------------------- 1 | var falafel = require('falafel'); 2 | 3 | var src = '(' + function () { 4 | var xs = [ 1, 2, [ 3, 4 ] ]; 5 | var ys = [ 5, 6 ]; 6 | console.dir([ xs, ys ]); 7 | } + ')()'; 8 | 9 | var output = falafel(src, function (node) { 10 | if (node.type === 'ArrayExpression') { 11 | node.update('fn(' + node.source() + ')'); 12 | } 13 | }); 14 | console.log(output); 15 | -------------------------------------------------------------------------------- /11/app.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | 3 | http.createServer(function (req, res) { 4 | res.writeHead(200, {'Content-Type': 'text/plain'}); 5 | res.end('Hello world!'); 6 | }).listen(8000); 7 | 8 | 9 | var fs = require('fs'); 10 | var path = require('path'); 11 | 12 | var pidfile = path.join(__dirname, 'run/app.pid'); 13 | fs.writeFileSync(pidfile, process.pid); 14 | 15 | process.on('SIGTERM', function () { 16 | if (fs.existsSync(pidfile)) { 17 | fs.unlinkSync(pidfile); 18 | } 19 | process.exit(0); 20 | }); 21 | -------------------------------------------------------------------------------- /11/appctl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | DIR=`pwd` 3 | NODE=`which node` 4 | # get action 5 | ACTION=$1 6 | 7 | # help 8 | usage() { 9 | echo "Usage: ./appctl.sh {start|stop|restart}" 10 | exit 1; 11 | } 12 | 13 | get_pid() { 14 | if [ -f ./run/app.pid ]; then 15 | echo `cat ./run/app.pid` 16 | fi 17 | } 18 | 19 | # start app 20 | start() { 21 | pid=`get_pid` 22 | 23 | if [ ! -z $pid ]; then 24 | echo 'server is already running' 25 | else 26 | $NODE $DIR/app.js 2>&1 & 27 | echo 'server is running' 28 | fi 29 | } 30 | 31 | # stop app 32 | stop() { 33 | pid=`get_pid` 34 | if [ -z $pid ]; then 35 | echo 'server not running' 36 | else 37 | echo "server is stopping ..." 38 | kill -15 $pid 39 | echo "server stopped !" 40 | fi 41 | } 42 | 43 | restart() { 44 | stop 45 | sleep 0.5 46 | echo ===== 47 | start 48 | } 49 | 50 | case "$ACTION" in 51 | start) 52 | start 53 | ;; 54 | stop) 55 | stop 56 | ;; 57 | restart) 58 | restart 59 | ;; 60 | *) 61 | usage 62 | ;; 63 | esac 64 | -------------------------------------------------------------------------------- /11/logger.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | var moment = require('moment'); 4 | var util = require('util'); 5 | var os = require('os'); 6 | 7 | var logdir = path.join(__dirname + '/logs'); 8 | if (!fs.existsSync(logdir)) { 9 | fs.mkdirSync(logdir); 10 | } 11 | 12 | var info = fs.createWriteStream(logdir + '/info.log', {flags: 'a', mode: '0666'}); 13 | var error = fs.createWriteStream(logdir + '/error.log', {flags: 'a', mode: '0666'}); 14 | 15 | var logger = new console.Console(info, error); 16 | 17 | var format = function (msg) { 18 | var ret = ''; 19 | if (!msg) { 20 | return ret; 21 | } 22 | 23 | var date = moment(); 24 | var time = date.format('YYYY-MM-DD HH:mm:ss.SSS'); 25 | if (msg instanceof Error) { 26 | var err = { 27 | name: msg.name, 28 | data: msg.data 29 | }; 30 | 31 | err.stack = msg.stack; 32 | ret = util.format('%s %s: %s\nHost: %s\nData: %j\n%s\n\n', 33 | time, 34 | err.name, 35 | err.stack, 36 | os.hostname(), 37 | err.data, 38 | time 39 | ); 40 | console.log(ret); 41 | } else { 42 | ret = time + ' ' + util.format.apply(util, arguments) + '\n'; 43 | } 44 | return ret; 45 | }; 46 | 47 | logger.log('Hello world!'); 48 | logger.error('segment fault'); 49 | logger.error(format(new Error())); 50 | 51 | var input = '{error: format}'; 52 | try { 53 | JSON.parse(input); 54 | } catch (ex) { 55 | ex.data = input; 56 | logger.error(format(ex)); 57 | } 58 | -------------------------------------------------------------------------------- /B/myscript.js: -------------------------------------------------------------------------------- 1 | // myscript.js 2 | x = 5; 3 | setTimeout(function () { 4 | debugger; 5 | console.log("world"); 6 | }, 1000); 7 | console.log("hello"); 8 | --------------------------------------------------------------------------------