81
瞭瞭 NodeJS 瞭瞭瞭瞭 by Fillano

All about NodeJS

Embed Size (px)

Citation preview

Page 1: All about NodeJS

瞭解NodeJS開發技術

by Fillano

Page 2: All about NodeJS

課程主要內容

• NodeJS 的背景知識• 如何撰寫 NodeJS 程式• 幾個 code example 展示與說明• 在 Windows 環境中執行 NodeJS• 如何找到更多資源

Page 3: All about NodeJS

作者、 Javascript、 V8及其它NodeJS的背景知識

Page 4: All about NodeJS

什麼是NodeJS

• 它主要是一個伺服器端的 Javascript 環境• 它提供了符合 CommonJS1.0 規格的模組機制,擴充功能

非方便• 只要能使用模組來擴充功能,實際使用上並不限於伺服器

程式

Page 5: All about NodeJS

什麼是NodeJS

• 舊瓶裝新酒• 1996 – Netscape Livewire in Netscape Enterprise Server• ASP with Jscript, Jscript.NET• Mozilla Rhino

• Flowscript for Apache Cocoon 2.1• Javascript Webflow for Spring• Helma (http://helma.org)

• RingoJS (http://ringojs.org/)

Page 6: All about NodeJS

什麼是NodeJS

• 舊瓶裝新酒• Mozilla SpiderMonkey

• Aptana Jaxer (http://jaxer.org/)• couchDB (RESTful API)

• Google V8• v8cgi (http://code.google.com/p/v8cgi/)• v8juice (http://code.google.com/p/v8-juice/)

• wikipedia: Comparison of server-side JavaScript solutions

Page 7: All about NodeJS

什麼是NodeJS

• 全新的生命力 不需要倚賴其他伺服器 類似 v8juice 與 jslib (http://jslib.mozdev.org/) 接下來會談到的成功因素

Page 8: All about NodeJS

為什麼這麼熱門

• 因為執行速度非常快• 有多快?一些比較:

http://shootout.alioth.debian.org/ vs php (

benchmarking nodejs basic performance tests against apache-php)

vs ruby (express vs sinatra benchmarks) vs ringojs (RingoJS vs. Node.js: Runtime Values)

Page 9: All about NodeJS

為什麼它這麼快?

• 它使用了 Google V8 Javascript 引擎 特別的 JIT 技術:兩階段 JIT

AST :將 Javascript 剖析成抽象語法樹 Generic CodeGen :直接產生尚未最佳化的機器碼執行

目前使用的最佳化技術 Cranshaft 執行時期追蹤與 Profiling

將型別資訊紀錄在相關 AST 節點中 Optimized CodeGen

四階段最佳化,產生可利用暫存器存放變數的機器碼

Hsu Ping Feng
codegen unit: functionmatch cpu architecturelimit to optimization: javascript as a dynamic language
Page 10: All about NodeJS

為什麼它這麼快?

• Evented I/O I/O 的速度,遠比 CPU 執行的速度慢,所以最有效率的方法

是在 I/O 完成時,由系統通知程式執行完畢,可以處理 I/O 動作執行的結果

Page 11: All about NodeJS

為什麼它這麼快?

• Evented I/O 舊方法: select, poll ,需要用兩個很慢的方法來監視資源

輪詢:每隔一段時間詢問系統是否有結果 遍歷:走訪每一個要監聽的檔案與網路 port

Page 12: All about NodeJS

為什麼它這麼快?

• Evented I/O 新方法: evented I/O ,告訴系統要監控的資源,當有變動時,

系統以事件通知 Linux: epoll BSD: kqueue Windows, Solaris: IOCP (I/O Completion Port)

Page 13: All about NodeJS

誰創造了 NodeJS Ryan Dahl

• 在德國工作的美籍 Freelancer ,專長: Interruptable Parser Event loops(event-machine, gearman…) Response time historgram

Page 14: All about NodeJS

誰創造了 NodeJS Ryan Dahl

• 一些開放原始碼專案的發起者: Ebb web server EY Load Balancer module for Nginx

Page 15: All about NodeJS

誰創造了 NodeJS Ryan Dahl

• 為了解決網站伺服器效能的問題,嘗試了: Ruby: Event Machine Python: Twisted

• 但是都不能滿意,在 Google V8 Engine 發表後,決定自己寫一個: 2009 JSConf 發表,獲得全場起立鼓掌 Crockford 曾說:這是 Javascript 發展過程的一個重要案例,

會影響未來 ECMA-262 規格的制定

Page 16: All about NodeJS

誰創造了 NodeJS Issac Schlueter 及其它開發者

• Issac Schlueter: NodeJS 上最多人使用的套件管理系統 -NPM 的作者,目前是 Ryan Dahl 在 Joyent 的同事

• 更多貢獻者:• Bert Belder(Release manager), Tim Caswell(How to node

website), Felix Geisendorfer, TJ Hollowaychuck(Express Framework), Paul Querna, Matt Ranney, Mikeal Rogers, Micheil Smith etc…

Page 17: All about NodeJS

哪裡可以找到 NodeJS

• http://nodejs.org 最新版本的原始碼檔案下載 最新版本的 Windows 可執行檔下載 最新版本的 API文件

• http://github.com/joynet/node 原始碼 Repository wiki :重點 - 如何在不同作業系統中編譯 NodeJS Issue Tracker

Page 18: All about NodeJS

誰在使用 NodeJS

• Plurk(www.plurk.com) http://www.slideshare.net/amix3k/comet-with-nodejs-and-v8

• Linkedin(www.linkedin.com) How LinkedIn used Node.js and HTML5 to build a better, faster ap

p

• 其它,參考: Projects, Applications, and Companies Using Node (列表中有一些是提供 NodeJS Hosting 服務的公司,他們

自己也利用 NodeJS 開發相關管理方案,例如 nodejitsu)

Page 19: All about NodeJS

使用 NodeJS 的時機 快速反應!

• 可以但並不適用於所有案例• 重點:當快速反應是最重要考量時• 並不適合需要大量運算的案例

Page 20: All about NodeJS

使用 NodeJS 的時機 快速反應!

• 單一執行緒與 event loop Javascript 程式本身只能在一個執行緒中執行 所有事件都是在一個 event loop依序執行 所以反應速度還是會隨著連線數上昇而逐漸下降

• 解決方法 在單一或多個機器上同時執行多個 node instance ,使用

proxy做 load balance 新版的 V8 引擎可以支援一個行程多個 instance

Page 21: All about NodeJS

當前開發狀態

• v0.5x( 開發版 )支援Microsoft Windows

支援 child_process支援 IOCP 可動態載入的原生模組 其它

支援 Visual C++之前只能在 Cygwin 及 MSYS 環境中編譯 v0.5.6 將可以在 Visual C++ Express正確編譯

Page 22: All about NodeJS

當前開發狀態

• 關鍵: libuv支援不同 OS 的 evented I/O 抽象層支援Microsoft Windows 的 I/O Completion Port 機制讓 NodeJS 抽換掉對於 libeio, libevent, libev等的直接依賴 在 Windows 環境中可使用 Visual C++編譯

Page 23: All about NodeJS

Javascript知識、效能、 NodeJS開發環境如何撰寫 NodeJS程式

Page 24: All about NodeJS

最簡單的程式範例 hello world 伺服器• 一頁就放的下的程式

var http = require('http');

http.createServer(function (req, res) {

res.writeHead(200, {'Content-Type': 'text/plain'});

res.end('Hello World.');

}).listen(1337, "127.0.0.1");

console.log('Server running at http://127.0.0.1:1337/');

Page 25: All about NodeJS

最簡單的程式範例 hello world加上 Express Framework

• 一頁就放的下的程式

var express = reuqire('express'), app = express.createServer();app.get('/', function(req, res){ res.send('Hello World.');});app.listen(3000);

Page 26: All about NodeJS

Javascript 背景知識 伺服器端的 Javascript

• 與瀏覽器中有什麼不同?沒有 DOM物件 Global 提供的環境不一樣

• 其它地方大同小異 因為都是 Javascript (ECMAScript) 以 NodeJS 來說,大量使用非同步的執行方式,但是與在瀏覽器中事件與非同步的寫法也差不多

Page 27: All about NodeJS

Javascript 背景知識 event loop

Page 28: All about NodeJS

Javascript 背景知識 event loop

• Javascript 程式的 Life Cycle第一步先執行 Global Context 中的程式碼 接下來,用 event loop 的方式執行所有事件函數,直到結束 如果在瀏覽器中,可以利用動態新增 script tag 的方式,再次

執行載入的 script 中 Global Context 中的程式碼,不過在NodeJS 不會有這個狀況發生

所以,大部份時間可能都是在執行函數

Page 29: All about NodeJS

Javascript 背景知識 event loop

• 優點沒有執行緒的額外負擔,反應速度快共用的變數不需鎖定,程式結構簡單

• 缺點某一函數執行時間長,就會推遲其它函數執行無法把負載分散到不同的 CPU

• 解決方法(以 NodeJS 為例) 同時執行多個 instance ,利用 proxy做負載均衡 Intel 的計畫,讓 Javascript 可以在多核心環境中進行平行處

理 https://github.com/RiverTrail/RiverTrail 目前只支援 Firefox

Page 30: All about NodeJS

Javascript 背景知識 事件與 callback函數• 通常在使用事件時,會傳遞給它一個函數,利用這個函數來執

行事件觸發時要職行的動作,這個函數就叫做 callback函數

var elem = document.getElementById(‘target’);elem.addEventListener(‘click’, function(e) {

//this is a callback function}, false);

Page 31: All about NodeJS

Javascript 背景知識 事件與 callback函數• 在瀏覽器中,通常很少超過兩層

var elem = document.getElementById(‘target’);elem.addEventListener(‘click’, function(e) {

req.onreadystatechange = function() {if(this.readyState===4&&this.status===200) {

var that = this;window.setTimeout(function(){

alert(that.responseTest)}, 500)

}}

}, false);

Page 32: All about NodeJS

Javascript 背景知識 事件與 callback函數• 在 NodeJS 環境中,有非常多的操作是用 callback 來完成,例如

這一段 mongo db 的範例

var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory});p_client.open(function(err, p_client) { p_client.dropDatabase(function(err, done) { p_client.createCollection('test_custom_key', function(err, collection) { collection.insert({'a':1}, function(err, docs) { collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) { cursor.toArray(function(err, items) { test.assertEquals(1, items.length); p_client.close(); });});});});});});

Page 33: All about NodeJS

Javascript 背景知識 事件與 callback函數

• 為什麼會出現這麼多層的 callbacks ? 重要的操作幾乎都透過 callback已非同步的方式完成 所以常常在 callbacks 中使用其他功能,就需要另外加一層

callbacks 在許多功能需要循序執行時,就需要在 callbacks 中使用下一

個步驟的功能,這些還是需要 callbacks 來完成

Page 34: All about NodeJS

Javascript 背景知識 事件與 callback函數

• 複雜 callbacks 的問題 程式邏輯會分散到各個 callbacks ,比較難除錯 不容易做單元測試

• 解決方式借助一些模組的幫助,將這些非同步的 callbacks改成同步的形式(底層還是使用非同步)

不要用匿名函數做 callbacks ,這樣對它做單元測試就比較容易

Page 35: All about NodeJS

Javascript 背景知識 撰寫 Javascript 程式的一些原則

• 不要污染 Global Scope 利用 Object把函數及變數 Group 起來 (namespacing) 利用立即執行的匿名函數,把在 Global Scope 執行的程式包

裝起來 不過只要好好使用模組,在 NodeJS 這不是大問題

• 簡單的性能策略注意變數 Scope 解析的問題 需要花時間處理的程式,可以切割成數個函數,利用

process.nextTick() 非同步執行

Page 36: All about NodeJS

V8 Javascript VM 的性能 一些簡單的原則

• V8 會依照函數執行的次數作為參考,進行最佳化( hot functions)某個函數預期它會在 NodeJS instance 生命週期中執行越多次,調整它對於效能就會更有效果

某些操作在 Javascript 中並沒有非同步執行的版本,例如JSON.parse/stringify ,而這些操作比較花時間。這時可以找一找是否有人實作非同步的版本(模組)

例如: https://github.com/dominictarr/JSONStream

Page 37: All about NodeJS

V8 Javascript VM 的性能 一些簡單的原則

• 但是有一些地方會妨礙 V8做最佳化無法決定 scope 中變數的型別時某些 Javascript函數,無法最佳化,所以使用到的話… 例如:用 Array.prototype.slice.call(arguments,1) 來把

arguments轉換成陣列就比 for(var i=0; i<arguments.length; i++) 慢,因為後者可以最佳化

Page 38: All about NodeJS

開發 NodeJS 程式 環境建置

• 取得 NodeJS 可執行檔 Unix-Like 環境

需要預先安裝 Python 及 GCC4.0 以上 在 nodejs.org 網站取得原始碼 解開後依序執行 ./configure、make 需要安裝到系統中時,執行 make install

Page 39: All about NodeJS

開發 NodeJS 程式 環境建制

• 取得 NodeJS 可執行檔 Windows 環境

安裝 Cygwin或是 mingw+msys 環境,還是需要 Python 及GCC4.0 以上

解開後依序執行 ./configure、make 需要安裝到系統中時,執行 make install 如果需要在純 windows 環境中執行 node.exe ,還需要把

Cygwin或是 msys 提供的一些 dll 檔複製到同一個目錄 如果不知道要複製哪些,執行 node.exe 會出現找不到這些 dll 檔

的錯誤訊息,可以當作參考

Page 40: All about NodeJS

開發 NodeJS 程式 環境建制

• 取得 NodeJS 可執行檔 Windows 環境

V0.5.6之後,可以直接使用 Microsoft Visual C++ 2010 來編譯,不過這個開發版本尚未釋出

不想自己編譯的話, V0.5.x 都有提供已編譯好的執行檔

Page 41: All about NodeJS

開發 NodeJS 程式 環境建制

• 安裝 NPM(node package manager) Unix-like 環境

需要預先安裝 curl參考 npmjs.org首頁上提供的方式,執行 one line install

Windows 環境 目前在 Windows 環境中還無法執行 npm 但是可利用 NODE_PATH 環境變數指定模組的預設路徑 到 search.npmjs.org 網站上尋找要安裝的模組參考依賴性,把相關的模組一起安裝到 NODE_PATH

Page 42: All about NodeJS

開發 NodeJS 程式 Global Scope 環境• Javascript 的運行環境是由 host透過存在於 Global Scope 的物

件或函數來提供的例如在 node.exe 的 console 中執行以下程式,就可以列舉出 Global Scope 中的物件與函數

> (function(o){for(var i in o) console.log(i)})(this);

Page 43: All about NodeJS

開發 NodeJS 程式 Global Scope 環境• 結果可以看到:> (function(o){for(var i in o) console.log(i)})(this);ArrayBufferInt8ArrayUint8ArrayInt16ArrayUint16ArrayInt32ArrayUint32ArrayFloat32ArrayFloat64ArrayDataViewglobal……

TypedArray 相關物件

Global物件的別名,就像瀏覽器環境中的 window物件

Page 44: All about NodeJS

開發 NodeJS 程式 Global Scope 環境• 結果可以看到:

…processGLOBALrootBuffersetTimeoutsetIntervalclearTimeoutclearIntervalconsole

處理行程的物件,有行程相關資訊、取得工作目錄等功能

用來處理 binary 資料的物件

用來做 stdio 的物件,可以輸出錯誤、 debug、 log等資訊

跟瀏覽器中的一樣啦

Global物件的別名,就像瀏覽器環境中的 window物件

Page 45: All about NodeJS

開發 NodeJS 程式 Global Scope 環境• 還漏掉一些(不會列舉出來):

…__dirname__pathnameexportsmodule

程式所在目錄的絕對路徑所執行 js 檔案的絕對路徑撰寫模組時,用來將介面輸出到呼叫端的物件其實就是 module.exports

提供目前模組的功能介面與資訊

如果撰寫「模組」,這幾個顯示的都是模組「 local」的資訊

Page 46: All about NodeJS

開發 NodeJS 程式 核心模組• 核心模組是編譯在 NodeJS 執行檔中的模組• 與外部模組一樣,透過下面方式載入使用

var http = require(‘http’);// 將 http 模組載入,指派給 http 變數

var server = http.createServer(function(request, response) {//分析 request 資訊,寫入 response

});server.listen(80, ‘127.0.0.1’);

Page 47: All about NodeJS

開發 NodeJS 程式 核心模組 -console (STDIO)

• NodeJS 提供的核心模組 提供標準輸入輸出功能,會自動載入 重要的功能:

console.log()/console.info(): 輸出訊息到標準輸出 console.warn()/console.error(): 輸出訊息到標準錯誤 console.dir(物件 ): 把物件資訊輸出到標準錯誤 console.trace(): 傾印程式當前位置的 stack trace 資訊 console.assert(): 就是 assert.ok() ,用來做測試

Page 48: All about NodeJS

開發 NodeJS 程式 核心模組 -timers

• NodeJS 提供的核心模組 會自動載入 重要的功能(跟瀏覽器中的一樣)

setTimeout(callback, time) clearTimeout(tid) setInterval(callback, time) clearInterval(tid)

Page 49: All about NodeJS

開發 NodeJS 程式 核心模組 -process

• NodeJS 提供的核心模組 提供行程資訊與操作,會自動載入 重要的功能

process.stdout / stderr: 寫入標準輸出 /標準錯誤的 writeable stream物件

process.stdin: 讀取標準輸入的 readable stream物件 process.argv: 程式啟動時傳入的參數 process.env: 取得系統環境變數 process.nextTick(callback): 讓 callback 非同步執行 process.cwd() / chdir(): 取得 /修改目前工作目錄 process.exit(code=0): 結束行程,返回訊息代碼

Page 50: All about NodeJS

開發 NodeJS 程式 核心模組 -util

• NodeJS 提供的核心模組 提供一些常用的工具函數,使用 require(‘util’)載入 重要的功能

util.format(): 返回格式化字串 util.debug(string): 輸出訊息到標準錯誤,執行時會停止所有程

式 util.log(string): 輸出訊息到標準輸出,並加上時間資訊 util.inspect(object): 回傳物件的代表資訊 util.pump(readableStream, writeableStream): 將讀入直接轉

到寫出 util.inherits(target, parent): 讓目標物件繼承父物件

Page 51: All about NodeJS

開發 NodeJS 程式 核心模組 -events.EventEmitter

• NodeJS 提供的核心模組 提供事件機制,使用到事件都要繼承它,使用

require(‘events’).EventEmitter載入 重要的功能

emitter.on(‘event’, listener): 指定事件處理函數給特定事件 emitter.once(): 同上,但是函數只會執行一次 emitter.removeListener(‘evnet’, listener): 移除事件處理函數 emitter.removeAllListeners(‘evnet’): 移除指定事件的所有處理函數

emitter.listeners(‘event’): 返回指定事件的處理函數陣列 emitter.emit(‘event’, [參數 1], [參數 2], …): 執行指定事件的處

理函數

Page 52: All about NodeJS

開發 NodeJS 程式 核心模組 -Buffer

• NodeJS 提供的核心模組 用來處理 binary 資料,自動載入 重要的功能

new Buffer(): 建構子 buffer.write(): 將字串寫入 Buffer buffer.copy(): 把 buffer 的資料拷貝給指定的 buffer物件 buffer.length: 取得 buffer 的長度 buffer[index]: 取得 buffer索引位置的資料

Page 53: All about NodeJS

開發 NodeJS 程式 核心模組 -streams

• NodeJS 提供的核心模組 用來處理各種資料的 I/O 的抽象結構,通常包裝成不同物件的成員自動載入,有 Readable 及 Writeable 兩種

重要的功能 Readable Stream

‘data’ 事件 : 會在資料到達時觸發 pipe(dest, [opt]): 可以把輸入 (Readable)轉向輸出 (Writeable)

Writeable Stream write(buffer)/write(string, encoding): 將資料寫入 end()/end(string, encoding,)/end(buffer): 結束資料,不再寫入

Page 54: All about NodeJS

開發 NodeJS 程式 核心模組 -crypto

• NodeJS 提供的核心模組 提供處理加解密的各個方法,透過 require(‘crypto’)載入 重要的功能

createCredentials()/createHmac()/creatCipher()/createDecipher()/ createSign()/createVerify()/createDiffeHellman()等 : 產生各種用來做加解密、 hash、簽章、驗證等物件

update(data): 用來把資料傳給上述物件,可搭配 stream 的方式在收到資料時傳給它,最後再用各物件的個別的操作來產生結果

Page 55: All about NodeJS

開發 NodeJS 程式 核心模組 -fs

• NodeJS 提供的核心模組 提供處理檔案系統的各種方法,透過 require(‘fs’)載入 重要的功能

fs.open(path, flag, mode, callback): 開啟檔案, fd 會在開啟檔案後傳遞給 callback

fs.read(fd, buffer, offset, length, position, [callback]): 讀取檔案 fs.write(fd, buffer, offset, length, position, [callback]): 寫入檔案 fs.readFile(filename, [encoding], [callback]): 一次讀取整個檔案 fs.close(fd): 關閉檔案還有一些目錄及檔案操作的函數

Page 56: All about NodeJS

開發 NodeJS 程式 核心模組 -net

• NodeJS 提供的核心模組 網路操作的各種方法,透過 require(‘net’)載入 重要的功能

net.createServer([opt], connectionListener): 產生 net.Server物件,並且把 connectionListener設定為’ connection’ 事件處理函數,將 net.Socket物件傳給它

net.createConnection(port or fd…, [callback]): 產生net.Socket物件,並且把 callback設定為’ connection’ 事件處理函數,將 netSocket物件傳給它

Page 57: All about NodeJS

開發 NodeJS 程式 核心模組 -net

• NodeJS 提供的核心模組 網路操作的各種方法,透過 require(‘net’)載入 重要的功能

net.Server server.listen(): 監聽 port或是 fd server.close(): 關閉網路連接 server.pause(): 暫停 connection 事件:會在網路連接建立時觸發,把 net.Socket物件傳遞給事件處理函數做進一步處理

Page 58: All about NodeJS

開發 NodeJS 程式 核心模組 -net

• NodeJS 提供的核心模組 網路操作的各種方法,透過 require(‘net’)載入 重要的功能

net.Socket connect 事件:在 socket連結建立時觸發 data 事件 : 在 socket收到資料時觸發 connect(port or fd): 建立網路 port或 fd 與 socket 的繫結 setEncoding(encoding): 指定資料編碼格式 ex. utf8, ascii,

base64 write(data): 將資料寫入 socket送出 address(): 取得本地監聽的 ip 及 port 資料 remoteAddress/remotePort: 取得遠端的網址 /port

Page 59: All about NodeJS

開發 NodeJS 程式 核心模組 -net

• NodeJS 提供的核心模組 網路操作的各種方法,透過 require(‘net’)載入 使用說明

客戶端每次建立一個連線,就會觸發 connection 事件透過傳遞給 connection 事件處理函數的 net.Socket物件,就可

以接收資料 /傳遞資料 net 模組可以用來建立各種 tcp 伺服器

Page 60: All about NodeJS

開發 NodeJS 程式 核心模組 -http

• NodeJS 提供的核心模組建立 http 伺服器,透過 require(‘http’)載入 使用說明

http.createServer(requestListener): 通常只要使用這個方法 request 事件 : 會在使用者對伺服器請求時觸發,會傳入

ServerRequest, ServerReponse物件給處理函數

Page 61: All about NodeJS

開發 NodeJS 程式 核心模組 -http

• NodeJS 提供的核心模組建立 http 伺服器,透過 require(‘http’)載入 使用說明

ServerRequest request.url: 使用者 request 的網址 request.method: http method ,例如 GET, POST等 request.headers: request header陣列 data 事件 : 在 request body 資料收到後觸發

Page 62: All about NodeJS

開發 NodeJS 程式 核心模組 -http

• NodeJS 提供的核心模組建立 http 伺服器,透過 require(‘http’)載入 使用說明

ServerResponse writeHead(status, [reasonPhrase], [headers]): 將 http狀態及

header回覆給 client write(chuck, encoding): 將部份資料回覆給 client end(data, encoding): 類似 write ,不過在回覆資料後就結束連結

Page 63: All about NodeJS

開發 NodeJS 程式 核心模組 -url

• NodeJS 提供的核心模組協助剖析網址,透過 require(‘url’)載入 使用說明

url.parse(urlString, parseQueryString=false, slashDenoteHost=false): 剖析網址,回傳包含 URL各個組成部分的物件。 parseQueryString指定是否要剖析網址之後的query string。最後一個參數指定是否要把 //host/path 剖析成{host: ‘host’, path: ‘path’}

Page 64: All about NodeJS

開發 NodeJS 程式 核心模組 -vm

• NodeJS 提供的核心模組編譯執行 Javascript ,透過 require(‘vm’)載入 使用說明

vm.runInThisContext(code, [filename]): 在目前的 context 中編譯執行 code字串,如果指定了 filename ,會調整 process 中的資訊( script 檔名等)

vm.runInNewContext(code, [sandbox], [filename]): 在新的context 中執行 code ,如果指定 sandbox物件,則把它當作context

Page 65: All about NodeJS

開發 NodeJS 程式 核心模組 -child process

• NodeJS 提供的核心模組 提供建立子行程的功能,透過 require(‘child_process’)載入。這部份功能在 windows 上的支援仍然不完整

使用說明(用不同方式執行可執行的程式,並取得其 stdio) child_process.spawn() child_process.exec() child_process.fork()

Page 66: All about NodeJS

發想並撰寫一個可以與檔案系統對應的http伺服器

程式碼範例

Page 67: All about NodeJS

簡單的範例 驗證概念• 嘗試讓 http server對應到檔案系統• 構想

• 從最簡單的 http server範例開始• 利用 fs 模組讀取檔案內容• 輸出到 server response

• 範例: myweb-v0.0.1.js

Page 68: All about NodeJS

簡單的範例 為模組化做準備• 調整程式,把需要的操作用物件包裝,然後用建構函數來產生物

件• 只要把這個建構函數 expose ,就可以使用• 如果需要單元測試,模組化會比較方便• 範例: myweb-v0.0.2.js

Page 69: All about NodeJS

簡單的範例 加上 mime 功能• server response 需要提供 mime type ,瀏覽器才有辦法知道怎樣使用

• 利用已經有人建構好的 mime 模組• 範例: myweb-v0.0.3.js

Page 70: All about NodeJS

簡單的範例 提供預設檔案功能• 構想:如果 request 的資源是目錄,則在目錄中尋找

index.html 檔案,輸出到 server response• 範例: myweb-v0.0.4.js

Page 71: All about NodeJS

簡單的範例 模組化• 構想:

• 利用 module.exports輸出MyHttpServer建構函數• 使用時透過 new 來建立實體

• 範例: myweb-v0.0.5.js, test-v0.0.5.js

Page 72: All about NodeJS

簡單的範例 嘗試使用 process.nextTick改進效能• 構想:

• 一些流程利用匿名函數包裝,丟給 process.nextTick 非同步執行• 不過實測對於效能並沒有明顯改進

• 範例: myweb-v0.0.6.js, test-v0.0.6.js

Page 73: All about NodeJS

簡單的範例 加上靜態檔案 cache改進效能• 構想:

把靜態檔案存入 cache ,如果有 cache就直接使用,減少 I/O測試過,對於效能有明顯提昇

• 範例: myweb-v0.0.7.js, test-v0.0.7.js

Page 74: All about NodeJS

簡單的範例 加上 router 機制,讓網址對應到處理函數• 構想:

• 模仿 express framework ,利用 get(‘path’, func) 來新增利用GET 方法,請求 path 路徑的處理函數 func

• post, put, delete, head等也可以使用同樣方法• 範例: myweb-v0.0.8.js, test-v0.0.8.js

Page 75: All about NodeJS

簡單的範例 開始做架構調整,先加上 cookie 機制• 構想:

利用 NodeJS 的事件機制,在伺服器每個 request 的 life cycle 中,插入 hook函數

利用 nodeunit做單元測試,以確保架構調整沒有問題加上’ init’ hook ,並且在這個階段處理 cookie hook函數,會接收到 request 與 response物件做處理

• 範例: myweb-v0.0.9.js, test-v0.0.9.js

Page 76: All about NodeJS

目前的支援狀況還有與 iis整合的方式Windows環境?

Page 77: All about NodeJS

NodeJS 在 Windows 中的支援

• v0.6.0 前預設要完成的目標(綠色為已完成)支援 IOCP(透過 libuv)支援使用 Visual C++編譯支援 Named Pipe ( 類似 Unix Domain Socket)支援 child process支援動態的原生模組 (dll 格式 )編譯成 64位元執行檔 其他… (還很多 )

Page 78: All about NodeJS

NodeJS 在 Windows 中的支援

• 目前最新開發版: v0.5.6 有 219 個測試通過, 38 個測試失敗,早幾版的數字大致相反

不需調整,就可以用 VC++編譯,之前版本不行持續改進 child process支援(完整支援據說還要一兩個月)持續改進修正 crypt 與 https 的問題

Page 79: All about NodeJS

與 IIS整合 介紹 iisnode

• 下載及安裝,參考網站中的指引:https://github.com/tjanczuk/iisnode

• 設定 web.config ,為要執行的 NodeJS 程式指定 Handler• 只支援 http協定• 原理:

• 把 IIS 當作 proxy ,利用 named pipe把 request/response導到執行的 NodeJS instance

• 伺服器程式要改寫,監聽 process.env.PORT , IIS 會透過這個環境變數,把 named pipe 路徑傳給 NodeJS

• 可以透過設定,自動做負載均衡• 效能不到直接執行 NodeJS 的一半,但是可以很方便做

proxy 與負載均衡

Page 80: All about NodeJS

Q & A

Page 81: All about NodeJS

一些資源• http://nodejs.org • http://npmjs.org • http://howtonode.org• http://groups.google.com/group/nodejs• http://www.facebook.com/NodeJS.tw• http://wiki.nodejs.tw• https://github.com/tjanczuk/iisnode