BÔ GIAO DUC VA ĐAO TAO

̣ ́ ̣ ̀ ̀ ̣

TR

NG Đ I H C KHOA H C

ƯỜ

Ạ Ọ

KHOA CÔNG NGH THÔNG TIN



BÀI TI U LU N Ể

MÔN : L P TRÌNH M NG

Tìm hi u v node.js

Đ Tài : ề

Giáo viên h

ng d n

ướ

ẫ : Nguy n Quang H ng

ư

Sinh viên th c hi n : Nguy n Quang Hà

ơ ả ng toàn c c). ụ

ế ừ ừ ạ ỏ ồ

IV. Các ng d ng đ ứ ượ ề Ứ ụ

t file

V. WebSocket v i Node.js và Socket.IO ớ ề ể ụ ế ng trình notepad ho c công c so n th o l p trình nào đó đ t o 2 file ả ậ ể ạ ứ ặ ươ

3 i thi u. .............................................................................................................................. I. Gi ệ 1. L p trình không đ ng b 3 .................................................................................................. ậ ộ ồ 2. B n ph i làm t 3 .......................................................................................................... t c ả ấ ả ạ 3. Module 5 ............................................................................................................................... 6 4. Global Scope ...................................................................................................................... 6 5. C ng đ ng ......................................................................................................................... ồ ộ 6 II. Installation ............................................................................................................................. 6 ............................................................................................................. 1. Installing Node.js . 7 ..................................................................................................... 2. Installing New Modules 7 III. Các objects c b n. ............................................................................................................. 7 ............................................................................... 1. Global Objects (đ i t ố ượ 15 2. S ki n (Event). .............................................................................................................. ự ệ a. EventEmitter 15 .................................................................................................................... b. K th a t 16 .......................................... EventEmitter ( Inheriting From EventEmitter ). 17 ........................................ c. Lo i b các s ki n l ng nghe (Removing Event Listeners). ự ệ ắ 3. Lu ng ( Streams ). 17 ........................................................................................................... a. Readable Streams 17 ............................................................................................................. b. Writable Stream. 20 .............................................................................................................. 20 ....................................................................................................................... 4. File System 5. HTTP. 23 ............................................................................................................................... .................................................................................................. 6. Đ c thêm Nodejs Docs. 29 ọ c xây d ng trên n n Node.js. 29 ............................................................. ự ụ 29 1. ng d ng đ u tiên. ......................................................................................................... ầ 2. HTTP Server. 29 ................................................................................................................... 3. X lý các tham s URL 31 ................................................................................................... ố ử 32 ................................................................................................................ 4. Đ c và vi ế ọ 33 ............................................................................................................. 5. Nodejs v i mysql ớ 34 ................................................................................ 35 .................................................................................................... 1. Tìm hi u v Socket.IO 35 ................................................................ c. 2. ng d ng tính k t qu bi u th c cho tr ướ ả ể Ứ S d ng ch ử ụ ụ ạ sau. 35 ....................................................................................................................................... Server.js: 35 .............................................................................................................................. 36 .......................................................................................................................... Client.html: 38 ......................................................................................................... 3. ng d ng webchat. Ứ ụ

TÌM HI U V NODE.JS Ể Ề

I. Gi ớ i thi u. ệ

t là t k đ vi ế ế ể ế ng trình đ ươ ệ

ụ t b ng i ti u ể ố ể t ng chi ậ ồ

Node.js bao g m có ứ ế ằ JavaScript, sử c vi ộ đ t ổ V8 JavaScript engine c aủ ỹ ậ ố ạ kh năng m r ng. i đ i

t các ng d ng internet có c thi ề đ Node.js là m tộ h th ng ph n m m ượ ầ ệ ố Ch máy ch web. kh năng m r ng, đ c bi ặ ở ộ ượ ủ ả d ng k th t đi u kh n theo s ki n, ự ệ nh p/xu t không đ ng b ấ ể ề ụ phí và t ồ ả Google, libUV, và vài th vi n khác. ở ộ ư ệ

Node.js đ c t o b i Ryan Dahl t năm 2009, và phát tri n d i s b o tr c a ượ ạ ở ừ ể ướ ự ả ợ ủ Joyent.

M c tiêu ban đ u c a Dahl là làm cho trang web có nh trong m t s ư ả

ụ ụ ộ ố ầ ủ ư Gmail. Sau khi th v i vài ngôn ng Dahl ch n Javascript vì m t API ộ ọ

kh năng push ữ ể ị ướ c ộ

ứ ử ớ Nh p/Xu t không đ y đ . Đi u này cho phép anh có th đ nh nghĩa m t quy Nh p/Xu t đi u khi n theo s ki n, non-blocking. ng d ng web nh ấ ấ ầ ủ ể ề ự ệ ậ ậ ể

Vài môi tr ng t ng t c vi t trong các ngôn ng khác bao g m ườ ươ đ ự ượ ế ồ Twisted ữ

ớ ầ ươ ế ệ ạ ộ

t k thu t c a ậ ủ CommonJS. Nó cung c pấ ế ỹ

ng REPL ng tác. cho Python, Perl Object Environment cho Perl, libevent cho C và EventMachine cho Ruby. ng trình Javascript, Nodejs không ch y trên m t trình duy t mà Khác v i h u h t các ch ch y trên Server. Node.js s d ng nhi u chi ti ề ử ụ cho ki m th t m t môi tr ử ươ ể ạ ộ ườ

Node.js đ cượ InfoWorld bình ch n là “Công ngh c a năm” năm 2012. ệ ủ ọ

ữ ạ ả ớ ườ ng

truy n th ng ch y trên server (server side) ph bi n nh PHP, Python, Ruby, etc Đ b t đ u dùng Node.js, b n ph i hi u s khác nhau gi a Node.js v i các môi tr ể ắ ầ ể ự ố ề ổ ế ư ạ

1. L p trình không đ ng b ậ ồ ộ

Là l i th n u b n đã quen thu c v i các ph ợ ạ ế ế ươ ậ ồ

ng pháp l p trình không đ ng b . T t c t c ch y nh các block thread thông ộ ớ ộ ồ

ườ ề ề ạ

ộ ấ ả ng thay vì ch y n n. Đây là đi u quan tr ng nh t đ nh v Node.js. Ví d , n u b n ạ i đó là ấ ả ạ ấ ể ỉ ư ớ ề ộ ụ ế ọ ạ ệ ố ộ ậ ứ ả ị

các hàm trong Node.js là không đ ng b . Do đó, t th đang đ c m t t p tin trên h th ng t p tin, b n ph i ch đ nh m t ch c năng g i l th c hi n khi đã hoàn thành các ho t đ ng đ c. ậ ạ ộ ọ ạ ọ ọ ệ ự

2. B n ph i làm t ạ ả t c ấ ả

ấ ả ả ự ạ

t c . Đó không ph i ả Node.js ch là môi tr ỉ ầ ề ặ ấ ứ ể ơ

i ườ m i, nh ng thành công th c s c a nó là đ a l ệ ớ ớ ộ

ể ạ

ng – đi u đó có nghĩa là b n ph i t ườ là m t server http ng m đ nh ho c là b t c server nào khác. Đi u này có th là h i khó ị ộ hi u v i ng ư ng c . M t scrits có th đi u ph i m i k t n i v i các client. Đi u này ể ề ộ nguyên đ a đ n m t hi u qu r t cao. Ví d sau v m t ng d ng Node.js ệ ư ế làm t ề i m t hi u năng đáng kinh ư ạ làm s d ng ít tài ử ụ ề ụ ự ự ủ ọ ế ố ớ ụ ố ả ấ ề ộ ứ ộ

var i, a, b, c, max;

max = 1000000000;

var d = Date.now();

for (i = 0; i < max; i++) {

a = 1234 + 5678 + i;

b = 1234 * 5678 + i;

c = 1234 / 2 + i;

}

console.log(Date.now() - d);

Và đây là t ng đ ng v i mã PHP: ươ ươ ớ

$a = null;

$b = null;

$c = null;

$i = null;

$max = 1000000000;

$start = microtime(true);

for ($i = 0; $i < $max; $i++) {

$a = 1234 + 5678 + $i;

$b = 1234 * 5678 + $i;

$c = 1234 / 2 + $i;

}

var_dump(microtime(true) - $start);

Và gi ta xem ch m đi m benchmark cho hai đo n code trên khi ch y trên hai môi ờ ể ấ ạ ạ

tr ng khác nhau: ườ

Number of iterations Node.js PHP

100 2.00 0.14

10’000 3.00 10.53

1’000’000 15.00 1119.24

10’000’000 143.00 10621.46

1’000’000’000 11118.00 1036272.19

ạ ệ ự

ễ ự ạ ạ ừ

Tôi th c hi n ch y hai đo n code trên t ử ng nh vòng l p. Nh ng v n đ thay đ i khi s ớ ố ượ ầ ặ ầ ổ ơ

ả ấ ề ơ ấ ạ ố ầ ấ ư ậ ử ạ

command line (console command) nên không ừ có tr thao tác th c thi. Tôi ch y t ng th nghi m 10 l n và l y k t qu trung bình. PHP ế ệ ố nhanh h n trong các l n ch y v i s l ỏ ng vòng l p tăng lên, s l n x lý tăng lên thì PHP ch y ch m h n r t nhi u trong khi l ượ t c thao tác, PHP ch m h n 93% so v i Node.js. Node.js có t c đ đáng kinh ng c. Sau t ặ ố ộ ấ ả ề ớ ạ ậ ơ

3. Module

ứ ụ ả

ộ ư ư ệ ệ ạ ị ặ ỗ

ứ ộ ậ ủ ụ ế

ụ ể ấ

Node.js s d ng m t ki n ử ụ ố ợ ứ ạ ệ ố ể ề ể ậ ậ

ứ ế trúc mô-đun đ đ n gi n hóa vi c t o ra các ng d ng ph c ể ơ t p. Mô-đun gi ng nh các th vi n trong C, ho c các đ n v trong Pascal. M i module có ơ ạ ch a m t t p h p các ch c năng liên quan đ n "đ i t ng" c a các mô-đun. Ví d , các ố ượ ứ ơ mô-đun http ch a các ch c năng c th cho HTTP. Node.js cung c p m t vài mô-đun c ộ ứ b n đ giúp b n truy c p các t p tin trên h th ng t p tin, t o ra trình đi u khi n server ậ ạ ả HTTP và TCP / UDP và th c hi n các ch c năng h u ích khác. ệ ứ ữ ự

Đ g i m t modul th t d dàng, ch c n g i hàm require() nh sau ậ ễ ể ọ ỉ ầ ư ộ ọ

Var http = require(‘http’);

Hàm require() tr v tham chi u đ n các module quy đ nh. Trong tr ế ế ủ ợ ị

c l u tr ộ ượ ư ữ ế

ệ ị

ng ng đ th c hi n. ể ự ế

ề ư ụ ứ ng ng trong th m c thì nó s tìm trên global module cache. B n cũng có th ứ ng đ i hay tuy t đ i nh sau: ng d n t ng h p c a mã ả ề ườ trong bi n http. Trong đo n code này, m t tham chi u đ n các module http đ ế ạ ế trên, ta đã truy n tên c a module vào trong hàm require(). Vi c này ch đ nh cho Node.js ỉ ủ ệ N u Node không th y tìm trong th m c node_modules module t ấ ươ module t ể ạ ẽ ch đ nh m t module qua m t file v t lý qua đ ệ ố ị ư ụ ộ ươ ộ ẫ ươ ườ ư ậ ố ỉ

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

Module đ ầ ừ ượ ủ ế ằ

ứ ể

ạ ộ c đ nh nghĩa trong h ch có th truy c p t ọ ỉ ứ ạ

ủ ượ ử ụ ớ ư ậ ừ

ủ ng export v i các thu c tính và ph ể ế ể ứ ủ c s d ng t ớ ả ử ụ ầ ớ ừ ươ ạ ộ

bên ngoài. Hãy xem xét các modul ví d sau đây: c đóng gói t ng ph n mã. Đo n mã n m trong m t mô-đun ch y u là ậ ừ private - có nghĩa là các ch c năng và bi n đ ế ượ ị bên trong c a các mô-đun. Tuy nhiên, b n có th ti p xúc v i ch c năng và / ho c các ặ ố bi n đ bên ngoài c a mô-đun. Đ làm nh v y, ph i s d ng các đ i ế t ố ng th c c a nó v i t ng ph n mã mà b n mu n ượ g i t ọ ừ ụ

var PI = Math.PI;

exports.area = function (r) {

return PI * r * r;

};

exports.circumference = function (r) {

return 2 * PI * r;

};

Trong ví d này PI là bi n private và ch đ ụ ế

c s d ng bên trong đo n mã, trong đó có ỉ ượ ử ụ ậ khóa exports ch đ nh thì s có th truy c p ạ ẽ ể ỉ ị c t ượ ừ

bên ngoài. hai hàm area() và circumference() đ c t đ ượ ừ

4. Global Scope

ng ch y javascrip v i google V8 engine do đó h tr ch y đ ộ ạ ườ

Node là m t môi tr ạ ủ ệ ậ ạ

ụ ứ ế ạ ả

ể ạ ễ ế ặ ớ

c ỗ ợ ạ ượ ở ớ server side. Do đó b n cũng nên tuân th các kinh nghi m mà b n có trong l p trình v i ớ các ng d ng client-side. Ví d khi t o các bi n global trong Node không ph i lúc nào cũng có th t o. Nh ng b n có th t o d dàng các bi n ho c hàm global v i cách b t ỏ ừ khóa var tr c các bi n nh sau: ụ ể ạ ướ ư ế ạ ư

globalVariable = 1;

globalFunction = function () { ... };

ế Nh ng các bi n global nên tránh s d ng, và xin nh c n th n r ng khi khai báo bi n ậ ằ ử ụ ớ ẩ ư ế

thì dùng t khóa var đ th c hi n. ừ ể ự ệ

5. C ng đ ng ộ ồ

C ng đ ng phát tri n Node.js ch y u t p trung ủ ế ậ ể ộ ồ ở

nodejs và nodejs- ộ ộ ả hai nhóm google : ề

dev, m t kênh ộ là NodeConf đ ch c th ng niên. c t IRC là #node.js trên m ngạ freenode. Có m t h i th o v Node.js ượ ổ ứ ườ

Hi n nay Node.js đ c s d ng b i nhi u công ty trong đó có Linkedin, Microsoft, ệ ượ ử ụ ề ở

Yahoo! và Walmart.

II. Installation

1. Installing Node.js .

ạ ể ặ ố ạ

Hi n nhiên là b n ph i h c cách cài đ t node tr ướ ả ọ ơ c khi mu n vi ạ ề ặ ấ ả

ữ ộ ấ ứ ứ t và ch y b t c ng i s d ng window ườ ử ụ ỉ ầ ng ng, b n ch c n ạ ứ

ế d ng nào trên n n node. Cài đ t node thì r t là đ n gi n, b n là ng ụ hay linux thì trên website nodejs.org đ u đã có nh ng b cài t ươ download v và cài đ t nh thông th ề ng. ườ ư ề ặ

V i linux thì b n s d ng package manager, b t c a s terminal và type: ậ ử ổ ạ ử ụ ớ

sudo apt-get update

sudo apt-get install node

Ho c:ặ

sudo aptitude update

sudo aptitude install node

B n có th c n thêm Node.js vào danh sách mã ngu n b ng l nh sau: ể ầ ệ ạ ằ ồ

sudo echo deb http://ftp.us.debian.org/debian/ sid main > /etc/apt/

sources.list.d/sid.list

ọ ầ ệ ố ệ ố ữ ể ơ

ủ C n tr ng khi cài sid packages trên nh ng h th ng cũ h n có th làm h th ng c a ng, hay c n th n và remove /etc/apt/sources.list.d/sid.list sau khi b n cài ưở ạ ẩ ậ

b n b nh h ị ả ạ xong Node.

2. Installing New Modules

ả ặ ể ặ ạ ạ

ở ử ổ ủ ạ

ộ ứ đ ng đ ự ộ ể ng ng và nh p l nh: ng d n t Ứ Node.js có m t ng d ng qu n lý packages, đó là Node Packgate Manager (NPM). ng ụ c cài đ t khi b n cài Node.js và b n dùng NPM đ cài đ t các d ng này t ượ ụ module khác. Đ cài đ t m t module, b n m c a s command line c a nodejs ra, vào ặ đ ườ ộ ậ ệ ẫ ươ ứ

npm install module_name

ệ ề ệ ẽ ạ ạ ộ

ụ mu n ch đ nh. Không ph thu c vào h đi u hành b n dùng, l nh trên s cài module mà b n mong ố ỉ ị

III. Các objects c b n. ơ ả

1. Global Objects (đ i t ng toàn c c). ố ượ ụ

đã bi tế , h th ng mô-đun ệ ố

Nh chúng ta ế c aủ node không khuy n khích ộ globals quan tr ngọ đ s d ng ế ể ử ụ . Vi c đ u tiên

ế ệ ử ụ vi c s d ng ệ ầ ề ề thao tác như quá trình truy n tín

ụ , tuy nhiên node cung c p m t ấ ấ là ti n trình global proccess id (pid), và nhi u h n n a , cho th y nhi u ấ ơ ữ . Globals khác, ch ng h n

ề i s d ng t . c cung c p cho nh ng ng ư bi n toàn c c và quan tr ng nh t ọ hi u,ệ xu t c nh, ấ ả obiects đ ượ ẳ ể ế JavaScript cho trình duy t web ạ như console ệ ườ ử ụ đ vi ấ ữ

a. Console

ử ụ m t s cượ sử d ngụ đ ể xu tấ thông tin để stdout

ệ ộ ố l nhệ đ ư:

Các console obiects s d ng ho cặ stderr. Chúng là các l nh nh console.log ([data], [...])

ng pháp ượ ử ụ ườ ấ là console.log(), mà

ươ ch đ n gi n là console obiects đ vi c s d ng th stdout và g n m t ngu n c p d li u t cho Ph ỉ ơ ng xuyên nh t ồ ấ ữ ệ dòng (\ n ế ắ ả ộ

console.log (wahoo '); // => Wahoo

console.log ({foo: 'bar'}); // => [Object Object]

Còn m t l nh có ch c năng nh ộ ệ ứ ư console.log()đó là console.info().

console.error ([data], [...])

Gi ng h t nhau đ ệ ố tế cho stderr. ể console.log(), tuy nhiên vi

ơ ở ữ

ế

console.error ('k t n i c s d li u

ệ không thành công ');

Còn m t l nh có ch c năng nh ộ ệ ứ ư console.error()đó là console.warn().

console.dir (obj)

S d ng ng ử ụ ph ố ượ đ nế stdout. ngươ pháp inspect() c aủ mô-đun sys khá-in các đ i t

console.dir ({foo: 'bar'}); / / => {Foo: 'bar'} console.assert (expression, [message])

false thì AssertionError s đ a ra ị ẽ ư N uế expression b ị đánh giá là có giá tr là message

đ c cho . ượ

ơ ở ữ

ế

console.assert (connected, 'C s d li u k t n i không thành công ');

console.time(label)

Đánh d uấ th i gian ờ ắ ầ . b t đ u

console.timeEnd (label)

Th i gian k t thúc , đ c ghi vào ế ờ ượ đ u raầ .Ví d :ụ

console.time('100-elements');

for (var i = 0; i < 100; i++) {

;

}

console.timeEnd('100-elements');

console.trace(label)

In m t ộ t p ậ stack các d u v t ế stderr c aủ v trí ấ ị hi nệ t iạ .

b. Process

t ắ ề v iớ goodies. Tr cướ tiên, chúng ta sẽ có m t cái nhìn ộ ạ ộ i m t

v node process đó : Các process object g n li n số thu cộ tính cung c p thông tin ấ ề

process.version

Chu i phiên b n ả nút, ví dụ: ỗ

console.log (' Version:' + process.version); // Version v0.8.16

process.execPath

Đ ng d n đ n ng trình "/ usr / local / bin / node". ế th m c ư ụ th c thi chính ự ườ ẫ c a ch ủ ươ

process.platform

Các n n t ng ề ả b n đang ạ ử ụ . Ví d , ụ "darwin". s d ng

process.pid

Các process ID.

process.stdout ()

c . M t ộ lu ngồ có th ghi đ ể ượ đ n stdout ế

Ví d : ụ Đ nh nghĩa ị về console.log().

console.log = function (d) { process.stdout.write (d + '\ n'); };

process.stderr ()

T ng t nh đây là ghi đ n ươ ư ở ế stderr. ự ư process.stdout() nh ng

trong Node, ố

. Chúng bị blocking trong tr

ng h p ho cặ mô t ả ậ ư lu ng khác ồ ợ mà chúng liên quan ng h p ợ chúng liên quan ườ

process.stderr() và process.stdout() là không gi ng nh ườ t p tin TTY. Trong tr ư ữ lu ngồ khác.

ngườ b blocking khi vi tế chúng th ị đ nế các t pậ tin th ng xuyên ườ đ n ế các pipes, chúng không b ị blocking nh nh ng

process.stdin ()

c , do M t ộ lu ngồ có th đ c đ ể ọ ượ cho stdin. Các dòng stdin b t m d ng ừ theo m c đ nh ặ ị ị ạ

đó, ng i ta ph i ườ ả g iọ process.stdin.resume () đ đ c ể ọ t nóừ .

Ví dụ mở đ u vào chu n ầ ẩ và l ng nghe ắ ự ệ : c hai s ki n ả

process.stdin.resume (); process.stdin.setEncoding ('utf8'); process.stdin.on ('data', function (chunk) { process.stdout.write ('data: ' + chunk); }); process.stdin.on (end', function () { process.stdout.write (' end'); });

process.cwd ( )

Tr ả về th m c làm vi c ư ụ ệ hi nệ t iạ . Ví d :ụ

cd ~ && node

node> process.cwd() "/Users/tj"

process.chdir ( )

Thay đ i ổ th m c làm vi c ư ụ ệ hi nệ t iạ .

process.chdir('/ foo');

process.getuid ( )

Tr v ả ề số user ID c a ủ process đang ch yạ .

process.setuid ( )

Thi t l p ng pháp này ế ậ user ID có hi uệ l cự cho quá trình đang ch yạ . Ph ươ ch pấ nh nậ cả

ỗ . Ví dụ cả hai process.setuid(501), và . ợ ệ m tộ số ID, cũng nh ư m t chu i process.setuid('tj') đ u ề h p l

process.getgid ( )

Tr v ả ề số group ID c a ủ process đang ch yạ .

process.setgid ( )

T c s d ng trong group ươ ượ ử ụ , cũng ch pấ

ự ư process.setuid() tuy nhiên đ ị ho cặ chu i đ i di n ỗ ạ ệ . Ví d ,ụ process.setgid(20) ho cặ

nh ng t nh nậ m t s giá tr ộ ố process.setgid('www').

process.chdir (directory)

i ệ ạ c a ủ process ho cặ đ aư m t ngo i l ấ ạ . ạ ệ n u ế th t b i ệ Thay đ i ổ thư m cụ làm vi c hi n t

ộ console.log ('Starting directory: '+ process.cwd ()); try { process.chdir ('/ tmp'); console.log ('New directory:' + process.cwd ()); } catch (err) { console.log ('chdir: '+ err); }

process.env

M t đ i t ng có ch a các bi n i s d ng ộ ố ượ ế môi tr ứ ngườ c a ng ủ ườ ử ụ . Ví d :ụ

{ PATH:

'/Users/tj/.gem/ruby/1.8/bin:/Users/tj/.nvm/current/bin:/usr/bin:/bin:/u

s

/sbin:/sbin:/usr/local/bin:/usr/X1

, PWD: '/Users/tj/ebooks/masteringnode'

, EDITOR: 'mate'

, LANG: 'en_CA.UTF-8'

, SHLVL: '1'

, HOME: '/Users/tj'

, LOGNAME: 'tj'

, DISPLAY: '/tmp/launch-YCkT03/org.x:0'

, _: '/usr/local/bin/node'

, OLDPWD: '/Users/tj'

}

process.argv

ệ m t t p tin v i Khi th c hi n ự

ự th hai là là nút th c thi, ậ và giá tr còn l i ớ các nút th c thi ứ process.argv cung c pấ truy c p vào các ạ là các tên t p tin, ậ ự ị

ộ ậ ị ầ c thông qua. vector đ iố số, giá tr đ u tiên đ i số ố đ ượ

c th c hi n Ví d , ụ t p tin ậ ngu n ồ c a chúng ta ủ ./src/process/misc.js có thể đ ượ ệ b ng cách ự ằ

ch y:ạ

$ node src/process/misc.js foo bar baz

: ấ nh sauư mà chúng ta g i ọ console.dir(process.argv), xu t ra

[ 'node'

, '/Users/tj/EBooks/masteringnode/src/process/misc.js'

, 'foo'

, 'bar'

, 'baz'

]

process.exit ([code])

ồ L nhệ process.exit() là đ ng nghĩa v i

ớ hàm C exit(), trong đó code > 0 đ c phát ra đ cượ bi ượ

ượ ọ vi c exit c khi ế là t c bi ượ , cho phép cượ c g i, ướ ả ệ process.reallyExit() đ

th tấ b iạ , ho cặ 0 đ m t th i gian ng n ờ ộ ọ ớ mã tr ng thái g i v i tế là thành công. Khi đ ắ đ ch bi n ể ế ế tùy ý để x y ra tr . nh tấ đ nhị ạ

process.on ( )

đã là m tộ EventEmitter, cho phép b n làm nh ng đi u ề như l ngắ nghe cho ạ

các tr ng h p ngo i l Process t ườ nó ự ợ ữ ự ệ uncaughtException: ạ ệ ch a bi băt ư ́ thông qua s ki n ̣

process.on('uncaughtException', function(err){

console.log('got an error: %s', err.message);

process.exit(1);

});

setTimeout(function(){

throw new Error('fail');

}, 100);

process.kill (pid, [signal])

ử ệ thông qua pid nh tấ đ nhị ặ ị

process.kill() g i tín hi u

cùng m t nút iướ đây, chúng ta g i ử tín hi uệ SIGTERM đ n quá trình ế

SIGINT. , m c đ nh cho ộ ờ đ minh ờ

L nh ệ Trong ví dụ d ể h aọ b yẫ tín hi u,ệ sau đó chúng ta ra " terminating " và thoát ra. L uư ý r ngằ th i gian ch th hai c a ủ 1000 mili giây là không bao giờ đ tạ đ cượ . ứ

process.on ('SIGTERM', function () {

console.log('terminating');

process.exit(1);

});

setTimeout(function(){

console.log('sending SIGTERM to process %d', process.pid);

process.kill(process.pid, 'SIGTERM');

}, 500);

setTimeout(function(){

console.log('never called');

}, 1000);

});

Errno

i máy ch Process object này l uư trữ c a các con s ủ ố báo hi u ệ l iỗ t ạ

i ủ, tham kh o ả nh ngữ gì ộ ỗ d aự trên s choự

gi a C++ ngườ đây là nh ngữ đ ữ

b n s tìm th y ạ ẽ phép, trong khi process.ENOENT đ iạ di nệ cho m t t p tin th và JavaScript, nh ng chúng h u ích cho vi c ấ trong C-land. Ví d ,ụ process.EPERM đ iạ di nệ cho m t l ho c th m c ư ụ b ị thi uế . Thông ộ ậ cượ sử d ngụ trong các ràng bu cộ để thu h p kho ng cách ả ẹ ạ ệ như: ng h p ngo i l ợ ệ x lý các tr ườ ư ử ữ

if (err.errno === process.ENOENT) {

// Display a 404 "Not Found" page

} else {

// Display a 500 "Internal Server Error" page

}

c. Buffers

C b n . Khi ệ ị

ầ ị

ặ ệ ố t pậ tin, li u nh phân ng pháp cho vi c khai thác ơ ả JavaScript là Unicode thân thi n, nh ng ệ ệ giao ti pế v iớ lu ngồ TCP ho c h th ng octet. Node cung c p m t s ph ấ ư không ph iả v iớ d li u nh phân c n thi , t oạ và s d ng ữ ệ t đ ế ể xử lý các lu ngồ ử ụ lu ngồ octet. ộ ố ươ

a v i các đ i t ng ng v i ng t ươ Đ x lý các d li u nh phân, ữ ệ ự ư m t m ng nh ộ node cung c p cho chúng t ấ ả các s nguyên ố ố ượ toàn c cụ . ộ

, nh ngư t c ớ ươ ứ ể ượ thay đ i kích c ổ

ể ử Buffer là t nhớ thô bên ngoài V8 heap. Buffer không th đ xây d ng m t tr ợ ng ớ vi cệ c p phát b ấ ể ỡ. Có m t s cách đ ộ ố ng h p b đ m, và nhi u cách b n có th thao tác d li u c a nó. ữ ệ ủ ạ ộ ườ ộ ệ ự ề ể

ng ng pháp Chuy n ể đ iổ gi aữ Buffers và các đ i t ố ượ chu iỗ JavaScript đòi h iỏ m t ph ộ ươ

mã hóa rõ ràng. D i đây là khác nhau. ướ chu iỗ các b ng mã ả

ữ ệ ASCII duy nh tấ . Ph

ươ t l p ẽ ạ ỏ các bit cao n u thi ế này chuy nể

).

null • 'ascii' - 7 bit d li u chóng, và s lo i b null đ iổ m t ký t ự ộ ố chuy nể đ iổ m t ký t N u b n mu n ạ ng pháp mã hóa này là r tấ nhanh ế ậ . L uư ý r ng vi c mã hóa ệ ằ ('\ 0' ho c 'ặ \ u0000') vào 0x20 (mã ký t ủ vào 0x00, b n nên ạ ự ự c a m t không gian ộ s d ng ' ử ụ ế ộ

utf8'.

mã hóa ký tự Unicode. Nhi uề trang web và các đ nh d ng ạ tài ị

• 'utf8' - Nhi u byte ề li uệ khác sử d ngụ UTF-8.

ề ố . Các c p đ i di n ệ (U ạ ặ

• 'utf16le - 2 ho c 4ặ byte, ký tự Unicode mã hóa ít v cu i 10.000 FFFF 10 U) đ c h tr . ượ ỗ ợ

ng t ươ • 'UCS2' - T ự 'utf16le'.

. ỗ • 'base64' - Mã hóa chu i Base64

ươ

ả c ố ượ b đ mộ ệ n u có th mã hóa d li u nh phân ữ ệ ng pháp mã hóa ự. Ph ế ị ể. Mã hóa này s đ ử ụ 8 bit thành chu iỗ b ng cách s d ng ằ ử ụ ố và nên tránh s d ng này b ph n đ i ẽ ượ lo iạ bỏ trong các phiên b nả

• 'binary' - M t cách ộ ủ m i ký t đ u tiên c a ỗ ầ các đ i t t ươ ng ủ Node. ng lai c a

là hai ký t th p l c phân . ỗ ự ậ ụ • 'hex' - Mã hóa m i byte

Buffer cũng có th đ c DataViews. ể ượ sử d ngụ xem m ngả ki u và ể

var buff = new Buffer(4);

var ui16 = new Uint16Array(buff);

var view = new DataView(buff);

ui16[0] = 1;

ui16[1] = 2;

console.log(buff);

view.setInt16(0, 1); // set big-endian int16 at byte offset 0

view.setInt16(2, 2, true); // set little-endian int16 at byte offset 2

console.log(buff);

//

//

m t chu i ch đ n gi n là ỉ ơ ả ỗ ự ả

Cách đ n gi n nh t đ xây d ng m t b đ m t ỗ ấ ể ố ầ ơ ư ậ ừ ộ ấ

c đ i di n trong h th p l c phân. ộ ệ ộ ố ượ ư ạ ng b đ m có ch a 5 byte d li u đ ứ ộ ộ ệ ể ữ ệ ượ ạ ử ụ s d ng chúng ờ ệ ậ ụ

chu i nh là tham s đ u tiên. Nh b n có th nhìn th y trong đăng nh p, bây gi ta có m t đ i t ệ var hello = new Buffer ('Hello'); console.log (hello); // => console.log (hello.toString ()); // => "Hello"

c i đây s đ ỗ ư ụ ấ ẽ ượ ử ấ

ể ượ thay đ iổ b ng cách đi qua Theo m c đ nh, mã hóa là "utf8", nh ng đi u này có th đ ặ ị ằ m t chu i nh là đ i s th hai. Ví d , d u ch m l ng d stdout nh ư kí c in ố ố ứ ư ộ ướ t ascii ". ự "&" khi trong b ng mã " ả var buf = new Buffer('â—¦');

console.log(buf.toString());

// => â—¦

var buf = new Buffer('â—¦', 'ascii');

console.log(buf.toString());

// => &

(nh ng trong tr hàm t ng đ ng) đ v t qua ườ ng h p này ợ ươ ươ ể ượ

m t m ng các s nguyên đ i di n cho dòng octet. M t s thay th ộ ộ ự ả ế câu l nh ệ ạ ố ư ệ

var hello = new Buffer ([0x48, 0x65, 0x6c, 0x6c, 0x6f);

c t o ra v i m t s nguyên đ i di n cho s l ng các byte ớ ể ượ ạ ố ượ ộ ố ệ ạ

B đ m cũng có th đ ổ

ộ ệ c phân b , sau đó chúng ta có th g i ủ ộ offset và mã hóa. ể ọ l nhệ write(), cung c p m t ủ ấ

ể completing "Hello") ộ offset c a 2 byte cu c g i th hai c a chúng ta đ ộ ọ ủ ấ ứ t ế 2 byte v i offset c a 3 ( ớ đ ượ D i đây, chúng ta cung c p m t ướ write() (buffering "Hel") và sau đó vi var buf = new Buffer(5);

buf.write('He');

buf.write('l', 2);

buf.write('lo', 3);

console.log(buf.toString());

// => "Hello"

ủ ồ

c v i chu i ề . Ví d , The .length c a m t tr ượ ớ ự

ng h p b đ m ch a byte chi u dài c a ứ i s ký t ả ạ ố ề ớ ộ ườ ộ ệ ỗ c c bụ ộ, ch đ n gi n là tr l ỉ ơ ẽ ợ ả ả ứ ộ ệ ề

, trái ủ lu ng (stream) ụ kí tự ellipsis 'â-¦' bao g mồ ng ba byte, do đó, các b đ m s ph n ng v i chi u dài byte (3), và không ph i là chi u dài ả ký t (1). ự

var ellipsis = new Buffer('â—¦', 'utf8');

console.log('â—¦ string length: %d', 'â—¦'.length);

// => â—¦ string length: 1

console.log('â—¦ byte length: %d', ellipsis.length);

// => â—¦ byte length: 3

console.log(ellipsis);

// =>

byte c a m t chu i ộ ế ệ ỗ c c bụ ộ, truy n đ n l nh ủ ề ộ

Đ ể xác đ nh đ dài ị Buffer.byteLength().

API đ nh v y mà nó c vi gi ng nh ượ ế ằ m t cách ộ

t b ng ư ậ thể làm vi cệ v iớ các " slices" c a b đ m ố ủ ộ ệ b ng cách ằ ư là String. Ví d ,ụ chúng ta có truy nề offset cho câu l nhệ Slice():

var chunk = buf.slice(4, 9);

console.log(chunk.toString());

// => "some"

Ngoài ra, khi đ iợ m t chu i ỗ , chúng ta có th ể truy n offset ề ộ đ nế Buffer#toString():

var buf = new Buffer('just some data');

console.log(buf.toString('ascii', 4, 9));

// => "some"

2. S ki n (Event). ự ệ

c s d ng Khái ni m v ệ ự ệ là r t quan tr ng ấ ọ trong node, và đ ượ ử ụ r tấ nhi uề

ng trình ủ và module c a ủ bên th 3ứ . Module s ki n ự ệ chính

ề m tộ "s ki n" trong su tố module chính c a ch ươ c aủ Node cung c pấ cho chúng ta v iớ m t ộ hàm t oạ , EventEmitter.

a. EventEmitter

Thông th i đây ườ m t đ i t ộ ố ượ kế th aừ từ EventEmitter, tuy nhiên ví dụ nh d ỏ ướ

ng ng minh h aọ API. Đ u tiên chúng ta ầ kỳ s l t oạ ra m tộ emitter, sau đó chúng ta có thể xác đ nhị ng pháp, mà ng b tấ ch pấ nh nậ tên c aủ các sự ươ ố ượ callbacks sử d ngụ emitter.on() ph

các đ iố t ngượ tùy ý thông qua nh làư dữ li uệ . Khi emitter.emit() đ

s l ng tham s ự ệ , theo sau b i b t kỳ ố ượ ượ ọ , c g i ố

ki n và ệ chúng ta chỉ required đ ể truy nề các tên s ki n (trong tr ở ấ ). ng h p này ợ ườ các chu iỗ tên đ u tiên và cu i cùng ầ ố

var EventEmitter = require('events').EventEmitter;

var emitter = new EventEmitter;

emitter.on('name', function(first, last){

console.log(first ', ' last);

});

emitter.emit('name', 'tj', 'holowaychuk');

emitter.emit('name', 'simon', 'holowaychuk');

b. K th a t EventEmitter ( Inheriting From EventEmitter ). ế ừ ừ

Đ c s d ng t th c ổ ế và thi ượ ử ụ ph bi n

ự c aủ EventEmitter là tính k th a t EventEmitter nguyên m u ẫ mà không b nh h ế ừ ừ . Đi uề này nó ưở ng ị ả

ng ti n a. ế có nghĩa là chúng ta có th ể gi nguyên ữ đ i v i ph ử ụ API c a nóủ trong khi s d ng ố ớ ươ ệ riêng c a chúng t ủ

ằ ở ạ Dog, trong đó

Đ ể làm nh v y, t nhiên còn đ ắ ầ b ng cách xác đ nh ư ậ chúng ta b t đ u ị c bi đ nế th i gian ( ờ s ẽ bark từ th i gian ượ ờ ư m t s ki n ộ ự ệ ). các hàm kh i t o t đ n nh t ế ế ấ var EventEmitter = require('events').EventEmitter;

function Dog(name) {

this.name = name;

}

đây chúng t ế ừ ừ EventEmitter vì v y chúng ta có thể sử d ngụ các ph ậ

Ở ứ ẳ ngươ ạ như EventEmitter#on() và EventEmitter#emit ().

a k th a t cung c pấ , ch ng h n proto b lo i tr ị ạ ừ, đ ng lo l ng, ừ iở ạ này sau. chúng sẽ đ cượ tr l ắ th c mà nó N uế thu c tính ộ Dog.prototype. proto = EventEmitter.prototype;

Bây gi chúng ta Simon! Khi Simon ờ cượ thành l pậ , chúng ta có thể t o ra ... ạ có Dog đ

ằ ọ console.log() v iớ callback. Callback

ng tế b ng cách g i trong ngữ c nhả c aủ các đ i t ượ ọ ố ượ bark, chúng ta có thể cho stdout bi c g i là chính nó đ var simon = new Dog('simon');

simon.on('bark', function(){

console.log(this.name ' barked');

});

Bark hai l n m i giây: ầ ỗ

setInterval(function(){

simon.emit('bark');

}, 500);

c. Lo i b các s ki n l ng nghe (Removing Event Listeners). ự ệ ắ ạ ỏ

đã bi nghe s ki n ư tế , l ng ắ cượ g iọ khi chúng ta

hàm đó đ i nghe ằ

. ự ệ ch đ n gi n là ỉ ơ ườ ữ không đ ề b ng cách c ượ dùng th ặ dùng l nhệ ng xuyên ườ Nh chúng ta ả emit() m t s ki n ộ ự ệ . Chúng ta có thể lo iạ bỏ nh ng ng removeListener(type, callback), m c dù đi u này

, chúng ta phát ra thông báo "foo bar" m i 300 mili giây, trong đó ỗ

i đây ụ ướ i ộ

ng t mà ộ ọ ạ c aủ console.log(). Sau 1000 mili giây, chúng ta g iọ ự ươ

t c các ng i nghe tôi đã thông qua on() ban đ uầ . Chúng ta ạ ỏ ấ ả ườ

. Trong ví d d có m t cu c g i l removeListener() v iớ các đ i số ố t cũng có thể sử d ngụ removeAllListeners(type), trong đó lo i b t cượ đăng ký type nh t đ nh đ ấ ị

var EventEmitter = require('events').EventEmitter; var emitter = new

EventEmitter; emitter.on('message', console.log);

setInterval(function(){

emitter.emit('message', 'foo bar');

}, 300);

setTimeout(function(){

emitter.removeListener('message', console.log);

}, 1000);

3. Lu ng ( Streams ). ồ

Streams là m t khái ni m ộ ộ

ữ ệ có thể đ ấ để tr cự

ệ quan tr ngọ trong nút. Các lu ngồ API là m t cách duy nh t ự ế m t t p tin, ộ ậ ượ m t ngu n ộ

, ho cặ tr cự ti pế t các API, đ l , ứ m t HTTP request ờ chúng ta sẽ t p trung vào c xem tr c ti p ừ ộ ể ạ các chi ti i ồ ch ỉ cho ế ụ ể t c th ậ

ể . ng sau x lýử lu ngồ gi ngố như dữ li uệ . Ví dụ, d li u ti pế vào m t ộ socket đ đáp ng ể đ cọ như stdin. Đ bây gi lu ngồ ch ươ

a. Readable Streams

c xem Readable Streams đ như m t HTTP ộ

ượ ế qua các s ki n ệ

ự ệ . Vi c đ u tiên c a ệ ầ dữ li uệ đ ượ c truy n đi ề request k th a t ủ nh ng s ki n này là s ki n ự ệ ữ ự ệ như là m t tr để x lý s ki n ử ế ừ ừ EventEmitter để lộ dữ ữ ệ là m tộ ự ệ d li u, ợ đ mệ ( ng h p ộ ườ ủ

li u đ n đo nạ tùy ý c a các Buffer instance ).

req.on('data', function(buf){

// Làm gì đó v iớ Buffer

});

ự ệ s k t thúc c a ự ế ạ

là m t HTTP , đ i di n cho ệ ế echo server, ch đ n gi n là M t ộ s ki n quan tr ng ộ ả

ọ khác là k t thúc ỉ ơ POST "hello world", response c a chúng t ế ữ ệ ự ệ . ủ d li u s ki n "simply" các request body data thông a sẽ là " ủ

Ví d , đây ụ qua các response. Vì v yậ , n u chúng ta hello world ".

var http = require('http');

http.createServer(function(req, res){

res.writeHead(200);

req.on('data', function(data){

res.write(data);

});

req.on('end', function(){

res.end();

});

}).listen(3000);

Module sys th c s có m t cượ thi ệ ặ

ấ t cho ậ m t ộ lu ngồ đ cọ nh là đ i s tế kế đ c bi ư hành đ ng ộ ố ố đ uầ tiên, và vi "simply" tế

. ộ ch cứ năng đ ự ự này, aptly tên sys.pump(). Nó ch p nh n dòng th haiứ

var http = require('http'),

sys = require('sys');

http.createServer(function(req, res){

res.writeHead(200);

sys.pump(req, res);

}).listen(3000);

stream.readable

Giá tr boolean ị sau khi x yả ra m tộ l iỗ ,

lu ngồ đ nế m tộ 'k t thúc' đ ế true, nh ngư s thành false ẽ c g i. ượ ọ c ượ m c đ nh là ặ ị , ho c ặ destroy() đ

stream.setEncoding ([encoding])

Làm cho 'data' s ki n ộ ỗ thay vì m tộ b đ mộ ệ . encoding có th làể

ặ ị ộ ộ ệ đ tr v m t ệ ủ ể ả ề ộ chu i đ i di n c a 'utf8'. Nh chúng ta ư ỗ ạ

. ự ệ phát ra m t chu i 'utf8', 'utf16le'('UCS2'),'ascii', ho cặ 'hex'. M c đ nh là bi t, ế chúng ta có thể g iọ toString() trên m t b đ m d li u nh phân ữ ệ ị

nh v y, ự ư ậ chúng ta có thể g iọ setEncoding() trên m t ộ lu ngồ , sau đó dữ li uệ

T ng t ươ ự ệ s phát ra s ki n ẽ chu iỗ .

req.setEncoding('utf8'); req.on('data', function(str){

// Làm gì đó v i String

});

stream.pause ()

v n cho các V n đấ ộ ệ t ư ấ

ề là m t tín hi u c g i l pớ giao ti pế cơ b nả , yêu c u ầ không có thêm dữ c g i. li uệ đ ượ ọ ượ ử cho đ nế khi resume() đ

c t m d ng s không v n ư ấ , lu ngồ nh tấ đ nhị ừ ngay l pậ ượ ạ L u ý ư r ng,ằ

, đ ả th iờ gian không xác đ nhị cượ phát ra cho m t kho ng ẽ ộ

ượ ọ do tính ch tấ t ự ệ 'data' có thể đ c g i. pause() đ

t c,ứ và do đó, s ki n ngay c sau khi ả stream.resume ()

ế ụ ạ s ki n i ự ệ 'data' sau khi pause().

Ti p t c l stream.destroy ()

mô t Đóng t p tin ậ cả ơ b nả . Stream là không còn có th ghi ể ể ọ và cũng không th đ c

đ cượ .

t ặ ự ệ 'k t thúc' . B t kỳấ ế

phát ra b t kỳ chi ti ấ c g i đi. đ ượ ử ế 'data', ho c s ki n ượ ả s ki n i c t d li u ữ ệ ồ ự ủ ự ệ 'close' khi ngu n l c c a Các lu ngồ đ

Các dòng s không ẽ s không ẽ ượ ử . c x lý

ghi x p hàng ế mình đã đ stream.pipe (destination, [options])

Đây là m t ph ng pháp Stream.prototype có s n trên t t c các ộ ươ ẵ ấ ả lu ngồ .

K t n i ế . Dữ li uệ đ n trên lu ngồ này đ ượ

Các lu ngồ đích và ngu nồ đ ượ ế ộ b ng cách t m d ng c ghi ừ và khôi ph cụ ằ ạ

t ế ố này đ cọ dòng để WriteStream đi m đ n ể đ ng b c gi ữ ồ trả về các lu ngồ đích. ế . Ch c năng này đ n đích. ế khi c n thi ầ ứ

ế khi đi qua lu ng ngu n ố ồ

end() đ

ể c. ặ ị ế c g i là ượ ọ không th ghi đ ể đi m đ n ượ {end: false} là tùy ch n đọ ồ phát ra cu i cùng , ể giữ cho lu ngồ đích

Theo m c đ nh do đó, đi m đ n mà ể mở.

Goodbye" có th đ c ằ ể ượ vi tế ở ố . cu i Đi u ề này giữ process.stdout mở r ng "

process.stdin.resume();

process.stdin.pipe (process.stdout, {end: false});

process.stdin.on ("end", function () {

process.stdout.write ("Goodbye \ n");});

b. Writable Stream.

M t l p c s

không đ ng b các Writable Stream. T b ng cách ghi đè ằ ngươ tự như Readable Stream, ệ ộ khi s d ng câu l nh ử ụ ồ ệ ạ ớ

ộ ớ ơ ở cho vi c t o ra b nạ có có thể t oạ ra các l p con _write(chunk, cb).

stream.writable

false sau khi l đ true, nh ng ư s thành ẽ ặ iỗ x y ra ho c ả ị

c ượ m c đ nh đó là ặ ị ượ ọ . c g i

Giá tr boolean end() /destroy() đ stream.Write (string, [encoding])

Vi n u chu i t ế chu iỗ v i encod ớ ả ề ing cho lu ngồ . Tr v true ỗ đã đ

đ cho bi t r ng c ể ế ế ằ b đ mộ ệ kernel đã đ yầ , và d li u s đ

ả ề ng lai t khi nào . S ki n ươ cượ bỏ vào b đ mộ ệ ữ ệ ẽ ượ g i điử b đ mộ ệ kernel là r ngỗ m tộ l nầ n aữ . ế ự ệ 'drain' sẽ cho bi

'utf8'.

kernel. Tr v false trong t Vi c mã hóa m cặ đ nhị ệ stream.Write (buffer)

T ng t nh ự ư trên, ngo i trạ ừ v i m t b đ m ộ ộ ệ thô. ớ

ươ stream.end ()

K t thúc s cho phép dòng v iớ EOF ho cặ FIN. Cu c g i này ộ ọ ẽ hàng đ iợ ghi d li u ữ ệ đ cượ

ế g iử tr cướ khi đóng lu ngồ . stream.end (string, encoding)

G i ử chu i v i ỗ ớ mã hóa nh tấ đ nhị và ch m d t ấ ứ dòng v iớ EOF ho cặ FIN. Đi uề này r tấ

ng . ố ượ các gói tin g i điử ể ả

h u ích đ gi m s l ữ stream.end (buffer)

T ươ tự nh trên, nh ng ộ ộ ệ . ư v i m t b đ m ớ

ng ư stream.destroy ()

Đóng mô t cơ b nả . Stream là không còn có th ghi ể ả ậ

t hàng ế 'data', ho cặ s ki n 'k t thúc' ế

c g i đi. c t các lu ngồ đ ể ọ và cũng không th đ c . B t kỳấ ự ệ ượ ả s ki n i ự ệ 'close' khi tài nguyên

t p tin phát ra b t kỳ chi ti cượ . các lu ngồ s không đ ẽ ấ ữ ệ ghi s không đ iợ d li u đ ượ ử ẽ ượ ử . c x lý đã đ c a mình ủ stream.destroySoon ()

i phóng Sau khi ghi hàng đ iợ đ cượ gi ả

h yủ ngay l p t c, ậ ứ mi n là không có d li u ễ , đóng t p tin mô t ậ iạ trong hàng đ iợ đ vi ữ ệ còn l ả. destroySoon() v nẫ có thể ể ế . t

4. File System

Đ làm vi c v i h th ng t p tin, ệ ớ ệ ố ể ho t đ ng POSIX, và h u h t các ph ạ ộ Chúng ta s xem xét làm th nào đ s d ng c hai, sau đó thi ộ t l p l a ch n t node cung c p ấ module "fs". Các l nh ệ ươ ệ ồ ể ử ụ th c ự thi các ộ ng pháp làm vi c đ ng b ho c không đ ng b . ồ t h n. ọ ố ơ ặ ế ậ ự ế ế ẽ ả

a. Làm vi c v i t p tin h th ng. ệ ớ ậ ệ ố

ắ ầ ệ ớ ậ ụ ơ ả

ệ ố t n i dung c a t p tin ạ Cho phép b t đ u v i m t ví d c b n làm vi c v i t p tin h th ng. Ví d này t o ộ ụ đ nế ư ụ ạ ế ộ ủ ậ

ớ ộ m t th m c, t o ra m t t p tin bên trong nó, sau đó vi ộ ậ console:

var fs = require('fs');

fs.mkdir('./helloDir',0777, function (err) {

if (err) throw err;

fs.writeFile('./helloDir/message.txt', 'Hello Node', function (err)

{ if (err) throw err;

console.log('file created with contents:');

fs.readFile('./helloDir/message.txt','UTF-8' ,function (err, data)

{ if (err) throw err;

console.log(data);

});

});

});

Rõ ràng trong ví d trên, ứ ớ ề ượ c

callback tr đ u đ t trong ặ c theo sau khi s d ng ph ử ụ ướ ươ

c hoàn thành theo th t ả ộ c đây đ ng pháp không h đang ứ ự ọ

c. ng v i m i callback ỗ ụ g i là callbacks chainable. Mô hình này c n đ ầ ượ ọ đ ng b , không có đ m b o r ng các ho t đ ng s đ ả ằ ạ ộ ồ t o ra. Đi u này có th d n đ n hành vi không th đoán tr ế ạ ẽ ượ ể ể ẫ ề ướ

Ví d có th đ c vi t l ể ượ ụ ế ạ ể ử ụ i đ s d ng m t cách ti p c n đ ng b : ộ ế ậ ộ ồ

fs.mkdirSync('./helloDirSync',0777);

fs.writeFileSync('./helloDirSync/message.txt', 'Hello Node');

var data = fs.readFileSync('./helloDirSync/message.txt','UTF-8');

console.log('file created with contents:');

console.log(data);

ươ ồ ộ

ể ế ố ế ủ ớ ặ ặ ươ ể ề ẽ ặ ấ

t h n đ s d ng ph Nó là t ộ ả ng pháp không đ ng b trên các máy ch v i m t t i ể ử ụ ố ơ cao, nh các ph ng pháp đ ng b s làm cho toàn b quá trình đ ngăn ch n và ch cho ờ ư ộ ộ ẽ các ho t đ ng đ hoàn thành. Đi u này s ngăn ch n b t kỳ k t n i đ n ho c các s ki n ự ệ ạ ộ khác.

b. File thông tin

Các đ i t ứ ề ộ ậ ề

c s d ng đ xác đ nh lo i đ i t ố ượ ể ượ ử ụ ể

ng fs.Stats có ch a thông tin v m t t p tin ho c th m c c th . Đi u này ặ ụ ạ ố ượ mà chúng ta đang làm vi c. Trong ví d ị ng t p tin trong m t th m c và hi n th ư ụ ụ ể ệ ư ụ ng ố ượ ể ộ

ng th m c. ị c t ậ ượ ấ ả ặ t c các đ i t ộ ố ượ ậ ư ụ có th đ này, chúng ta đang nh n đ cho dù chúng là m t t p tin ho c m t đ i t ộ ậ var fs = require('fs');

fs.readdir('/etc/', function (err, files)

{ if (err) throw err;

files.forEach( function (file) {

fs.stat('/etc/' + file, function (err, stats)

{ if (err) throw err;

if (stats.isFile()) {

console.log("%s is file", file);

}

else if (stats.isDirectory ()) {

console.log("%s is a directory", file);

}

console.log('stats: %s',JSON.stringify(stats));

});

});

});

c. Xem các t p tin. ậ

fs.watchfile theo dõi m t t p tin và ộ ậ thay đ iổ m t s ki n ộ ự ệ b tấ cứ khi nào

Ph ươ t p tin đ ậ ng pháp ượ thay đ iổ . c

var fs = require('fs');

fs.watchFile('./testFile.txt', function (curr, prev) {

console.log('the current mtime is: ' + curr.mtime);

console.log('the previous mtime was: ' + prev.mtime);

});

fs.writeFile('./testFile.txt', "changed", function (err) {

if (err) throw err;

console.log("file write complete");

});

M t t p tin cũng có th đ c ộ ậ ể ượ unwatched b ngằ cách sử d ngụ ph ươ

không còn c n đ c giám ộ ầ khi t p tin ậ ng pháp g i ọ ầ ượ ử ụ

fs.unwatchFile. Cách này chỉ nên s d ng m t l n sát.

5. HTTP.

Đ s d ng HTTP server và client ph i dùng l nh ể ử ụ ệ ả

require('http').

c thi Các giao di n ệ HTTP trong Node đ ượ ề c a ủ các giao ế ế ể hỗ trợ nhi u tính năng t k đ ử ụ . Trong đó, có thể là đo nạ mã hóa, tin nh n.ắ th cứ truy n th ng ề ố khó s d ng

HTTP headers đ c bi u di n : ượ ễ b i m t đ i t ộ ố ượ nh th này ng ư ế ể ở

{ 'content-length': '123',

'content-type': 'text/plain',

'connection': 'keep-alive',

'accept': '*/*' }

Key đ c c ượ lowercased và giá tr không đ ị ượ s a đ i. ử ổ

http.STATUS_CODES

t c các mã tr ng thái tiêu ấ ả ạ chu nẩ c a ủ HTTP response, và mô tả M t b s u t p ng nắ g n cho t ng cái ộ ộ ư ậ c aủ t ừ ọ . Ví d ,ụ http.STATUS_CODES [404] === 'Not Found'.

http.createServer ([requestListener])

đ ả ề ộ đ iố t ngượ web server m iớ . RequestListener là m t ch c năng ứ ộ cượ t ự ộ đ ng Tr v m t thêm vào s ki n ự ệ 'request'.

http.createClient ([port], [host])

ả ố s d ng ử ụ , hãy s d ng ử ụ http.request() để thay thế. Xây d ngự m t HTTP Hàm này b ph n đ i ị ộ client m iớ . Port và host tham chi u ế đ n máy ch ế ủ đ đ ể ượ ế ố . c k t n i

a. Class: http.Server.

server.listen(port, [hostname], [backlog], [callback])

ấ B t ắ đ uầ ch p nh n các k t n i ế ố trên port ch đ nh ỉ ị và hostname. N uế hostname đ cượ bỏ ế ố tr cự ti pế đ nế b t kỳ đ a ch ỉ IPv4 m t socket thay vì port và ộ unix, cung c p ấ m t tên t p tin ấ ộ ị ậ ậ qua, các server sẽ ch p nh n các k t n i ậ ấ (INADDR_ANY). Đ nghe ể hostname.

Backlog là chi u dài t ự ế s đ ẽ ượ c ủ ề b iở h đi u hành ệ ề ề ế ậ sysctl như tcp_max_syn_backlog và ế ố đang chờ. Chi u dài th c t ợ k t n i t l p c a tham s này iố đa c a hàng đ i thông qua các thi ủ là 511 (không ph iả 512). ị ặ ị ố xác đ nhị somaxconn trên Linux. Giá tr m c đ nh

Hàm này là không đ ng b c i ồ ộ. G i l ọ ạ tham số cu i cùng s đ ẽ ượ thêm vào nh làư m tộ ố listener cho s ki n ự ệ 'listen'. Xem thêm net.Server.listen(port).

server.listen (path, [callback])

ng d n B t ắ đ uầ m t máy ch socket ủ ộ UNIX l ngắ nghe cho các k t n i ế ố trên đ ườ ẫ nh tấ . c i ọ ạ tham số cu i cùng s đ ố đ nhị Hàm này là không đ ng b ng ồ t l ng nghe i bi ộ. G i l cho s ki n ế ắ ườ ẽ ượ thêm vào nh làư m tộ ự ệ 'listen'. Xem thêm net.Server.listen (path).

server.listen (handle, [callback])

Các đ i t c thi t l p đ ố ượ có thể đ ượ ế ậ ể x lýử m t máy ch ộ ủ ho cặ socket, ho cặ đ iố ng ngượ {fd: }. t

L ng nghe trên t p tin không đ c h tr ắ m tộ mô t ả ậ ượ ỗ ợ trên Windows.

là không đ ng b c i ồ ộ. G i l ọ ạ tham số cu i cùng s đ ẽ ượ thêm vào nh làư ố t l ng nghe cho s ki n Ch c năng này ứ m t ng i bi ế ắ ộ ườ ự ệ 'listen'. Xem thêm net.Server.listen().

server.close ([callback])

D ng ừ server và ch pấ nh nậ các k t n i m i ế ố ớ . Xem net.Server.close().

server.maxHeadersCount

i đa t l p là 0 - không có ặ ị . N uế thi ế ậ c áp d ng. gi Gi ớ ạ đ i h n i h n t ớ ạ ố ượ headers count đ nế , là 1000 theo m c đ nh ụ

b. Class: http.ServerRequest.

ng này đ c

ố ượ i s d ng ộ ộ ủ m t máy ch HTTP ượ t oạ ra trong n i b c a ủ để m t listener ố ố ầ ộ - không ph iả b iở 'request'. Request

Đ i t ộ ườ ử ụ - và thông qua nh làư đ i s đ u tiên ng giao di nệ Readable Streams. th c hi n các ệ ự

request.method

Yêu c uầ m t chu i. ỗ Ch đ c. ộ ỉ ọ Ví d :ụ 'GET', 'DELETE'.

request.url

Câu l nh này ch Yêu c uầ chu i URL. ỗ ệ ỉ ch a các ứ URL theo th cự tế trong HTTP request.

N u ế request là:

GET /status?name=ryan HTTP/1.1\r\n

Accept: text/plain\r\n

\r\n

Thì request.url s là:

'/status?name=ryan'

N u b n mu n ạ ố đ phân tích các ể ế URL thành các ph nầ c aủ nó, b n có th ể sử d ngụ ạ

require('url').parse(request.url). Ví d :ụ

node> require('url').parse('/status?name=ryan')

{ href: '/status?name=ryan',

search: '?name=ryan',

query: 'name=ryan',

pathname: '/status' }

N u b n chu i truy v n ạ mu n trích xu t ấ các params t ế ố ừ ấ , b n có th ể sử d ngụ ạ ỗ

require('querystring').parse, ho cặ thông qua các đ i số ố thứ hai để require('url').parse. Phân tích cú pháp. Ví d :ụ

node> require('url').parse('/status?name=ryan', true)

{ href: '/status?name=ryan',

search: '?name=ryan',

query: { name: 'ryan' },

pathname: '/status' }

request.headers

Đ c ọ b nả đồ duy nh t c a ấ ủ tên header và giá trị. Tên header là lower-cased. Ví d :ụ

ư

// In m t cái gì đó nh :

// {User-agent ':' curl/7.22.0 '

// Host: '127 .0.0.1:8000 ',

// accept: '*/*' }

console.log(request.headers);

request.trailers

Ch đ c ỉ ọ HTTP trailer (n u có). ế

request.httpVersion

Phiên b nả giao th c HTTP ứ ỉ ọ Ví dụ: '1.1 ', '1.0'. Ngoài ra

nh m t chu i. ỗ Ch đ c. ầ ư ộ ố và request.httpVersionMinor là thứ

request.httpVersionMajor là s nguyên đ u tiên hai. request.setEncoding ([encoding])

Thi t l p t thêm thông ể ế ế ậ mã hóa cho c chơ ế request. Xem stream.setEncoding() đ bi

tin. request.pause ()

các s ki n đ tăng t c i lên . ạ ừ request t ừ ự ệ phát ra. R t h u ích ấ ữ ố t ể ả

T m d ng request.resume ()

Ti p t c l i ừ . ế ụ ạ request t m d ng ạ

request.connection

Các đ i t ng ố ượ net.Socket k tế h pợ v i k t n i. ớ ế ố V i ớ h tr HTTPS, ỗ ợ ử ụ s d ng

c .

request.connection.verifyPeer() và request.connection.getPeerCertificate() đ có đ ể

ượ thông tin xác th cự c a client ủ

c. Class: http.ServerResponse.

ộ ộ ủ m t HTTP ở ườ i

c c thông qua ượ t oạ ra trong n i b c a ố ứ ộ như là tham s th hai c a ủ s ki n server - không ph iả b i ng ự ệ 'request'. Response

Đ i t ố ượ ử ụ . Nó đ s d ng th c hi n các ệ ự ng này đ ượ giao di nệ Writable Stream.

response.writeHead (statusCode [reasonPhrase], [headers])

có 3 ứ ể

G i m t ử ữ ố ộ response headers đ đáp ng yêu c u. statusCode là m t tr ng thái HTTP ộ ạ ầ m t reasonPhrase nh là đ i s th ể đ a raư ố ố ứ ư ộ ố ọ

ch s mã, gi ng nh 404. Tùy ch n có th ư hai.

Ví d :ụ

var body = 'hello world';

response.writeHead(200, {

'Content-Length': body.length,

'Content-Type': 'text/plain' });

c g i tr c khi Câu l nhệ này ch đ c g i là m t l n trên m t tin nh n và nó ph i đ ộ ộ ầ ả ượ ọ ướ ắ

ỉ ượ ọ c g i. ượ ọ

response.end() đ

c khi g i, ướ ọ header ng mầ ọ response.write() ho c ặ response.end() tr

N u b n g i ạ cượ tính toán và g i hàm này ế sẽ đ ọ đ nhị cho b nạ .

c đ a ra trong các byte không ph i ký t ư ượ ư ả ự

world' ch a các byte ký t

Content-Length đ L u ý: r ng ứ ỗ

ế nó ch a các ký t duy nh t. N u ứ ấ c s d ng đ xác đ nh s byte ể ượ ử ụ ị

ể . Ví d trên ụ ự ượ c đ ố ủ Content-Length và đ dài c a ộ

ề ằ

ằ làm vi cệ vì chu i 'hello mã hóa cao h n ơ thì sau đó Buffer.byteLength() nên đ trong m t ộ đo n ạ mã hóa nh t đ nh. Và Node không ki m tra ấ ị c truy n đi b ng nhau hay không. thân đã đ ượ response.statusCode

hàm ẩ

đi u khi n các mã tr ng thái đó s đ Khi s d ng các header n (không g i ạ ề ọ response.writeHead() m t cách rõ ràng), c.ượ c g i ộ khi các header nh n ậ đ ẽ ượ ử đ n cho client ế ử ụ ể

Ví d :ụ

response.statusCode = 404;

Sau khi response header đã đ các mã tr ng thái đ cượ g i cho ử client, hàm này ch raỉ ạ cượ

g iử . response.setHeader (name, value)

header nẩ . N u ế header này đã t n t c thay th . Thi ầ t ế l pậ m t giá tr ộ cượ g iử , giá tr c a nó ồ ạ trong i ỗ ở ị ủ ả ộ

. ấ sẽ đ ả ử nhi uề header v i cùng m t tên ị header duy nh t cho ượ ớ đ ph n header đây n uế b n c n ph i g i ạ ầ ế Sử d ngụ m t m ng các chu i ộ

Ví d :ụ

response.setHeader ("Content-Type", "text / html");

hoăc̣

response.setHeader ("Set-Cookie", "lo i = ninja", "ngôn ng = javascript

"]);

response.sendDate

đ ng t o ra và g i ử response n u nó không ế ạ

, date header s đ c t ẽ ượ ự ộ header. M c đ nh là true. ặ ị

Khi giá tr là true ị ph i là đã có trong các ả response.getHeader (name)

ử client. Đi uề này chỉ

có th đ Đ c ọ ra m t header ộ ể ượ g iọ là tr c đó đã đ c khi ướ cượ x p hàng đ i ợ nh ngư không g i cho ế ậ ượ . c header nh n đ

Ví d :ụ

var contentType = response.getHeader ('content-type');

response.removeHeader (name)

Lo i b m t ạ ỏ ộ header x p hàng đ i đ g i ng m. ợ ể ử ế ầ

Ví d :ụ

response.removeHeader ("Content-Encoding");

response.write (chunk, [encoding])

c g i, nó s chuy n sang ch ượ ọ ế

luôn xu t ra các header ng pháp này có th đ N u ế hàm này đ ẩ c g i và ượ ọ ấ

response.writeHead() đã đ nẩ . Ph

ươ ẽ ể ượ ọ ể ề c g i là nhi u

đ ộ header n và l n đ cung c p các b ph n ấ ầ ể ộ ậ liên ti pế nhau.

chuck có th là m t chu i ho c m t b đ m. N u ỗ ế chuck là m t chu i, tham s th hai ố ứ ặ ộ ỗ

ộ ộ ệ xác đ nh làm th nào đ mã hóa nó thành m t dòng byte. Theo m c đ nh, mã hóa là 'utf8'. ộ ộ ặ ị ể ế ể ị

ầ ẽ ử Khi response.write() đ

ầ , nó s g i các thông tin ượ ọ ầ c g i l n th hai, Node gi ứ header đ m và ệ ạ đ nh b n ả ị

c d li u, và g i riêng thân đ u tiên cho s đ ẽ ượ ữ ệ ượ ọ l n đ u tiên c g i ầ client. Khi response.write() đ ữ ệ . d li u ử

c xu t ế

ầ ủ ữ ệ ượ ế ấ thành công đ n ế kernel buffer. Tr v false c x p hàng đ i trong b nh c a ng ộ ả ề ườ ử i s ớ ủ

ượ t c ho c m t ph n c a d li u đ c phát ra khi b đ m drain' s đ ề n u t ế ấ ả d ng. ' ụ Trả v true n u toàn b d li u ộ ữ ệ đ ộ ặ ẽ ượ ộ ệ tr ng ố m t l n n a. ợ ộ ầ ữ

response.end ([data], [encoding])

này, tín hi u đ n t c các response headers V i hàmớ ế server mà t ệ ấ ả

đã đ c g i là trên cượ

c quy đ nh c th , đó là t i. ả ờ N u d li u đ ế ữ ệ ượ ụ ể ươ ươ ỗ và ph n thân ầ ả ượ ọ ớ ọ ng v i g i

ị ế g i, ử server nên xem xét hoàn thành tin nh nắ này. response.end() ph i đ m i câu tr l response.write (data, encoding) ti p theo ng đ response.end().

d. http.ClientResponse.

Đ i t ng này đ c ố ượ ệ

ượ t oạ ra khi th c hi n m t ộ yêu c uầ v iớ http.request(). Nó đ ng cượ giao ự ệ ự ủ ố ượ yêu c uầ . response th c hi n các ự ệ 'response' c a đ i t

thông qua v iớ s ki n di nệ Readable Stream.

response.statusCode

3 ch s ữ ố mã tr ng thái ạ c aủ HTTP response. VÍ D :Ụ 404.

response.httpVersion

ủ để k t n i ặ ể ế ố . Có th ho c là

Các phiên b n ả HTTP c a máy ch ố ầ ủ response.httpVersionMajor là s nguyên đ u tiên '1.1 'ho c ặ '1.0'. Ngoài ra và response.httpVersionMinor là

.

th haiứ response.headers

Đ i t ng ố ượ response headers .

response.trailers

Trailer đ i t ng ố ượ response.

response.setEncoding ([encoding])

t thêm t ế l pậ mã hóa cho c th ph n ng ơ ể ể ế ả ứ . Xem stream.setEncoding () đ bi

Thi thông tin. response.pause ()

các s ki n đ tăng t c ạ ừ response t ừ ự ệ phát ra. H u ích ữ ố t ể i vả ề.

T m d ng response.resume ()

Ti p t c l i ừ . ế ụ ạ m t ộ response b ị t m d ng ạ

6. Đ c thêm Nodejs Docs. ọ

ng c b n đ ơ ả ượ ố ượ ư ượ ầ ủ

ượ

t c các l nh t c nên ra, v n ch a đ ẫ tìm hi u sâu v Node.js thì nên xem các tài li u c a Node API đ ệ ủ và li ệ ố Trên đây ch là các đ i t ỉ ề ấ ả ệ h th ng t p tin ể t kêệ ậ có thể có s nẵ khi làm vi c v i c đ y đ vì v y mu n ố ậ c biên so n ế ạ r t chi ti t ấ ệ ớ Node.js.

c xây d ng trên n n Node.js. IV. Các ng d ng đ ứ ụ ượ ự ề

1. ng d ng đ u tiên. Ứ ụ ầ

ụ Ứ ử ng d ng đ u tiên b n nên t o v i nodejs là ng d ng in ch ‘Hello World’ trên c a ứ ữ ầ ạ ạ ớ

ụ s console. T o m t file v i tên hello.js, v i n i dung sau: ổ ớ ộ ạ ộ ớ

console.log('Hello World!');

ng d n đ n hello.js và ở ử ổ ủ ư ườ ế ẫ

Đ ch y script, m c a s command line c a node, đ a đ ạ ể ch y l nh: ạ ệ

node hello.js

B n s th y ch ‘Hello World’ hi n lên trên c a s console. ạ ẽ ấ ử ổ ữ ệ

2. HTTP Server.

Hãy đ n v i m t ví d ph c t p h n, có th h i r i khi b n ti p xúc l n đ u. hãy đ c ể ơ ố ọ ế ầ ầ ạ ế ụ ứ ạ ớ

ơ ộ các dòng code sau và các ph n ghi chú: ầ

// Khai báo http module.

var http = require("http");

ư ộ

ượ

// T o ạ server. Hàm đ

cượ thông qua nh m t tham s

ố đ

ọ c g i là

trên

ượ

m iọ request đ

ạ c t o ra

.

// Bi nế request n mắ giữ t tấ cả các tham s request // Bi nế response cho b n làm

b tấ cứ đi uề gì v iớ response g iử t iớ

client.

http.createServer(function (request, response) {

ế

ờ // Gán listener t i th i đi m k t thúc s ki n.

ượ

ả ữ

// S ki n này đ

c g i khi client g i t t c d li u và đ i

ự ừ

response t server.

request.on("end", function () {

ế

// Vi t headers cho response.

// 200 là mã tr ng thái c a HTTP (đi u này có nghĩa là thành công)

ườ

ượ

ố // Tham s th hai gi tr

ng header trong đ i t

ng

ơ

// Chúng ta đang g i m t văn b n đ n gi n, do đó Content-Type nên

là text/plain

response.writeHead(200, {

'Content-Type': 'text/plain'

});

ế

// G i d li u và k t thúc response.

response.end('Hello HTTP!');

});

// L ng nghe t i c ng 8080.

}).listen(8080);

Th t là đ n gi n, b n có th g i d li u đ n các client b ng cách s ế ả ạ ậ ơ ằ

ể ử ả ọ ữ ệ ướ ạ c khi g i hàm ọ ử ụ d ng response.end(). L u mã ư

response.write(), nh ng b n ph i g i nó tr ư trên thành file http.js và đánh l nh sau trên console:

node http.js

ế ị ỉ http://localhost:8080. B n sạ ẽ ở ử ổ ệ th y dòng ch “Hello HTTP!”. ữ Sau đó m c a s trình duy t browser đ n đ a ch ấ

ủ TCP l ng nghe trên c ng 8080 và ắ ổ echo chu i ‘hello’ ra ỗ ộ

Đo n mã sau là m t máy ch ạ m i k t n i: ỗ ế ố

var net = require('net');

net.createServer(function (stream) {

stream.write('hello\r\n');

stream.on('end', function () {

stream.end('goodbye\r\n');

});

stream.pipe(stream);

}).listen(8080);

3. X lý các tham s URL ử ố

Nh đã nói tr c, ta ph i t làm m i th trong node. Hãy xem code c a ví d sau: ư ướ ả ự ủ ứ ụ ọ

// Khai báo http module.

var http = require("http"),

// và url module, nó r t h u ích trong vi c phân tích tham s request.

url = require("url");

// T o server.

http.createServer(function (request, response) {

ế

// Gán listener và k t thúc s ki n.

request.on('end', function () {

ư

ế

// Phân tích request cho các đ i s và l u chúng trong bi n _get.

ượ

// Hàm này phân tích các url t reqest và tr v các đ i t

ng đ i

di n.ệ

var _get = url.parse(request.url, true).query;

ế

// Vi t headers cho response.

response.writeHead(200, {

'Content-Type': 'text/plain'

});

ế

// G i d li u và ki t thúc response.

response.end('Here is your data: ' + _get['data']);

});

// L ng nghe t i c ng 8080.

}).listen(8080);

Ph n code này dùng ph ng th c ộ

ủ ng th c query, s ứ parse() c a module url, m t module lõi c a Nodejs, ẽ ủ ng th c tr l ứ ả ạ ươ ứ ừ

ầ đ convert t ể l y l ấ ạ ươ request url thành object. Ph i thông s c a URL. L u file này thành ố ủ ươ ử ổ ệ ư i object là ph get.js và th c thi trên c a s l nh: ự

node get.js

Sau đó vào đ ng d n: ườ ẫ http://localhost:8080/?data=put_some_text_here đ xemể

k t qu . ả ế

t file 4. Đ c và vi ọ ế

Đ đ c và ghi file trong Node ta dùng fs module, m t module s n có trong Node. Các ẵ ộ

hàm đ c và ghi file là ụ ể ọ ọ

fs.readFile() và fs.writeFile(). Ta có ví d sau:

// Khai báo http module,

var http = require("http"),

// và mysql module.

fs = require("fs");

// T o http server.

http.createServer(function (request, response) {

ế

// Gán listener và k t thúc s ki n.

request.on('end', function () {

ế // Ki m tra n u là user requests /

if (request.url == '/') {

// đ c file.

fs.readFile('test.txt', 'utf-8', function (error, data) {

ế

// Vi t headers.

response.writeHead(200, {

'Content-Type': 'text/plain'

});

ượ

// Tăng s thu đ

c t file.

data = parseInt(data) + 1;

ế

// Vi t s đã tăng vào file.

fs.writeFile('test.txt', data);

ế

// K t thúc response v i tin nh n.

response.end('This page was refreshed ' + data + ' times!');

});

} else {

ế

ượ

//Cho biêt n u t p tin request không đ

c tìm th y.

response.writeHead(404);

ế

// và k t thúc request mà không g i d li u nào.

response.end();

}

});

// L ng nghe t i c ng 8080.

}).listen(8080);

L u file l i thành file ư ạ ướ ộ c khi ch y file này trên c a s command, t o m t ử ổ ạ ạ

files.js. Tr

ư ụ ớ file test.txt cùng th m c v i file

file.js.

Hãy ch y và ki m tra k t qu . ả ể ế ạ

5. Nodejs v i mysql ớ

H u h t các môi tr ố ầ ế ườ ứ ề

ữ ư ệ ề ớ ả ớ

ể ọ ớ ư ư ệ ầ ổ ộ ị

ủ ủ ở ử ổ ả ỉ

ng truy n th ng ch y server side đ u có nh ng ch c năng kèm ạ t này, theo đ thao tác v i database. V i Node.js, b n ph i cài thêm th vi n. V i bài vi ế ạ tôi ch n m t th vi n khá n đ nh đ dùng. Tên đ y đ c a module th vi n là: ệ ể mysql@2.0.0-alpha2 (phía sau @ ch là tên phiên b n). M c a s command, dùng npm cài module này lên v i l nh: ớ ệ

npm install mysql@2.0.0-alpha2

ệ L nh này s download và cài đ t module, và nó cũng t o m t folder trong th m c hi n ư ụ ệ ẽ ặ

hành. B n hãy quan sát ph n code sau đ bi ộ t thao tác v i csdl: ể ế ầ ạ ạ ớ

// Khai báo http module,

var http = require('http'),

// và mysql module.

mysql = require("mysql");

ế

// T o k t n i.

ượ

// D li u là m c đ nh đ cài đ t m i mysql và nên đ

c thay đ i theo

c u hình c a b n.

var connection = mysql.createConnection({

user: "root",

password: "",

database: "db_name"

});

// T o http server.

http.createServer(function (request, response) {

ế

// Gán listener và k t thúc s ki n.

request.on('end', function () {

ơ ở ữ

ấ // Truy v n c s d li u.

connection.query('SELECT * FROM your_table;', function (error,

rows, fields) {

response.writeHead(200, {

'Content-Type': 'x-application/json'

});

// G i d li u là chu i JSON.

ả ủ

ế

ữ ế // Bi n rows gi k t qu c a các truy v n.

response.end(JSON.stringify(rows));

});

});

// L ng nghe c ng 8080.

}).listen(8080);

ả ấ ữ ệ ậ

ọ ư ệ ụ ỉ ầ ế ỗ ể ễ

ớ ứ i các k t qu mã l , b n nên ki m tra n u xãy ra l ự ế ệ ả ỗ

ư ộ ể ẽ ư ấ ố

ả ủ ng th c và g i hàm. Trong các ng d ng th c t debug, và tr l ả ạ là trong ví d này ta cũng set Content-type v i giá tr ớ ụ tr MIME c a JSON. Tham s rows s l u gi ữ ế ủ ị d li u trong rows sang c u trúc c a JSON qua ph ấ ữ ệ ươ ủ ấ Truy xu t d li u v i th vi n này r t đ n gi n, b n ch c n nh p câu l nh truy xu t ạ ệ ấ ơ i đ d dàng ể ự ế ạ i khi th c hi n c u l nh thành công hay không. L u ý ầ ệ ị x-application/json, đó là m t giá ổ k t qu c a truy v n, và ta đã chuy n đ i ứ JSON.stringify().

i v i tên ạ ớ ự ớ

mysql.js sau đó th c thi trên c a s command, v i csdl mysql đã ử ổ

đ L u file l ư c cài đ t ặ ượ

Node mysql.js

Sau đó vào đ ng d n: ườ ạ ẽ ượ ệ ắ c nh c ẫ http://localhost:8080 trên trình duy t và b n s đ

download file JSON-formatted

V. WebSocket v i Node.js và Socket.IO ớ

ư ệ ụ ứ

ạ ố t b di đ ng. Vi c s d ng th vi n này cũng r t đ n gi n và gi ng ư ệ ụ ấ ơ ệ ử ụ ư ả ộ

c server l n client. Socket.IO là m t th vi n javascript có m c đích t o ra các ng d ng realtime trên trình ộ duy t cũng nh thi ế ị ệ nhau ẫ ở ả

Sau đó cài m c a s console và cài đ t Socket.io b ng l nh sau: ở ử ổ ệ ằ ặ

npm install socket.io

1. Tìm hi u v Socket.IO ể ề

ỉ ầ ế ạ ư ệ ơ ả i, ch c n dùng Socket.IO nên b n c n ph i tìm hi u v th vi n này t ạ ầ t vài hàm c b n nh requires() đ import th vi n. Công i đây: ể ể ề ư ệ ư ả ạ V i Node.js, b n ch c n bi ạ ớ vi c còn l ỉ ầ ệ . http://socket.io/#how-to-use

ng socket b ng ph ng th c ằ ươ ươ ng th c này ứ ứ listen(port). Ph client. - Server: t o m t đ i t ạ ch đ i m t yêu c u k t n i t ờ ợ ộ ố ượ ầ ế ố ừ ộ

- Client: K t n i đ n server b ng ph ng th c ế ố ế ằ ươ ứ connect(url,{port: server_port}).

c kích ượ - Socket.IO cung c p 3 event chính là connect, message và disconnect. Chúng đ ạ ạ c thông đi p ệ

ấ ho t khi client/server: + connect: t o k t n i ế ố + message: nh n đ ậ ượ + disconnect: ng t k t n i ắ ế ố Ví d :ụ socket.on("message", function(msg){

// console.log("Received: "+ msg);

});

ng (đ ể ử ữ ệ ữ ệ ố ượ ượ ể c chuy n

send(). D li u có th là đ i t ể c qua s ki n message.

ẽ ỗ ự ệ - Đ g i d li u, ta dùng l nh ệ thành chu i json) và s nh n đ ậ ượ Ví d : ụ socket.send("Hello world");

- Socket.IO có th g i và nh n các event t ể ử ậ ươ ứ emit(). Hai phía g iử c tên c a event đó đ th c hi n giao ti p: t đ ế ượ ủ ự ạ ể ự t o v i ph ớ ệ ng th c ế ả

và nh n ph i bi ậ Ví d :ụ // g i:ử

socket.emit("hello",{msg: "welcome");

// nh n:ậ

socket.on("hello", function (data) {

console.log(data);

}

);

2. ng d ng tính k t qu bi u th c cho tr c. ả ể Ứ ứ ụ ế ướ

S d ng ch ử ụ ươ ể ạ ng trình notepad ho c công c so n th o l p trình nào đó đ t o 2 ụ ạ ả ậ ặ

file sau.

Server.js:

T o m t t p tin ộ ậ ạ

server.js v i n i dung sau: ớ ộ

var io = require('socket.io');

var socket = io.listen(8080);

socket.sockets.on('connection',function(socket){

socket.on('message', function(expr){

console.log('Received expression from client ',expr);

ớ // B t l i đ i v i bi u th c x u

try{

socket.send(eval(expr));

}catch(err){

socket.emit("error",err.message);

}

});

socket.on('disconnect', function(){

// console.log('Disconnected');

});

});

Client.html:

WebSocket Client


onclick='sendMessage();' />

. Di chuy n vào bên trong th m c ư ậ ể ắ ầ ư ụ bieuthuc và b t đ u

L u và thoát kh iỏ các t p tin ụ . ch yạ ng d ng ứ

node Server.js

ả Ứ ụ ứ ể ế ậ ỉ

đ Bây gi ượ ớ m file Client.html nh p bi u th c và nh n k t qu . ng d ng ch làm vi c ệ ậ ờ ở c v i bi u th c tính toán không có d u ngo c đ n. ặ ơ ể ứ ấ

K t qu : ả ế

3. ng d ng webchat. Ứ ụ

a. Xây d ng m t webchat server c b n. ơ ả ự ộ

Tr c tiên, ta s nh p các mô-đun Socket.IO. ướ ẽ ậ

var exp = require('express');

var app = exp.createServer();

Sau đó, ta s t o ra m t bi n toàn c c duy nh t c a Socket.IO đ c s d ng đ chia ấ ủ ẽ ạ ụ ế ộ ượ ử ụ ể

s trên nhi u ng d ng. ề ứ ẻ ụ

global.socket = require('socket.io').listen(app);

global.socket.set('log level', 1);

global.socket.set('transports', [ 'websocket', 'flashsocket',

'htmlfile', 'xhr-polling', 'jsonp-polling']);

ộ i t p tin c u hình, router, và m t mô-đun chat-socket đã có s n trong cùng m t ấ ẵ ộ

Ta s t ẽ ả ậ th i đi m. ể ờ

require('./app/config')(app, exp);

require('./app/server/router')(app);

require('./app/server/modules/chat-socket');

Và sau đó kh i đ ng server. ở ộ

app.listen(8080, function(){

console.log("Express server listening on port %d in %s mode",

app.address().port, app.settings.env);

});

b. T o module Server-Side chat socket. ạ

Đi u đ u tiên ta c n làm là xác đ nh không gian tên cho ng d ng này.Ta làm đi u này ụ ứ ề ầ ị ầ

ề v i câu l nh ớ ệ

socket.of ('namespace').

module.exports = function()

{

global.socket.of('/chat').on('connection', function(socket) {

console.log("a user has connected to the 'chat' namespace");

});

}();

Bây gi ờ ộ ố ể ườ ử ụ ắ i s d ng k t n i, phát tin nh n ế ố

ể c a h và l ng nghe khi h ng t k t n i. ủ ọ ta có th thêm m t s code đ theo dõi ng ắ ắ ế ố ọ

c tiên hãy t o m t m ng các màu mà ta ng u nhiên s gán cho ng i dùng ẽ ẫ ả ộ ườ

ướ khi h k t n i đ phân bi t nhau trong b ng chat. Nh ng tr ư ọ ế ố ể ạ ệ ả

var colors = ['#AE331F', '#D68434', '#116A9F', '#360B95', '#5F209E'];

Ti p theo ta s t o ra m t " connections object " đ theo dõi ng i dùng k t n i. ẽ ạ ể ế ộ ườ ế ố

var connections = { };

K ch b n phía client s phát ra m t s ki n "user-ready" sau khi m t ng ị ả ẽ ộ

ộ ự ệ ẽ ư ộ ị

ượ ng lai. Server cũng s giao cho ng i s d ng m i đ c k t n i m t màu ườ ế ố i k t n i c giao m t tên. Server s l u tr giá tr đó trong socket server đ s ể ử ộ ữ ườ ử ụ ớ ượ ế ố

ẽ m ng màu s c có s n. thành công và đ d ng trong t ươ ụ ng u nhiên t ừ ả ẫ ẵ ắ

global.socket.of('/chat').on('connection', function(socket) {

socket.on('user-ready', function(data) {

socket.name = data.name;

socket.color = data.color = colors[Math.floor(Math.random() *

colors.length)];

// let everyone else in the room know a new user has just connected //

brodcastMessage('user-ready', data);

});

ể ạ ỏ ế ừ ố các đ i

ắ ế ố i s d ng. Ta s l ng nghe cho đ n khi h ng t k t n i, do đó ta có th lo i b chúng t ọ ng k t n i và thông báo cho ng ườ ử ụ ẽ ắ ế ố t ượ

socket.on('disconnect', function() {

delete connections[socket.id];

dispatchStatus();

brodcastMessage('user-disconnected', { name : socket.name, color :

socket.color });

});

ự ệ ể ỉ ở ạ ớ i v i

i c a nhóm. ph n còn l

dispatchStatus và broadcastMessage ch là các shortcut đ phát s ki n tr l ầ

ạ ủ

function dispatchStatus()

{

brodcastMessage('status', connections);

}

function brodcastMessage(message, data)

{

socket.emit(message, data);

socket.broadcast.emit(message, data);

}

Khi m t ng ườ ủ ử ắ

ộ ể ớ ậ ệ ị

i dùng g i tin nh n cho thêm màu s c k t h p v i Socket c a mình vào ắ ế ợ tin nh n đ chúng tôi có th hi n th màu s c thích h p trong nh t ký trò chuy n khi phát ợ ắ tr l ể ể i c a nhóm. ắ i v i ph n còn l ầ ở ạ ớ ạ ủ

socket.on('user-message', function(data) {

data.color = socket.color;

brodcastMessage('user-message', data);

});

c. Kh i t o k t n i trên Client ở ạ ế ố

Khi m t ng ộ ặ i dùng k t n i v i ng d ng webchat, ta s cung c p cho h m t tên m c ế ố ớ ứ ọ ộ ườ ụ ẽ

c g i đi. ấ đ nh. Khi g i tin nh n, ta s l y giá tr này và thêm nó vào tin nh n đ ị ắ ượ ử ẽ ấ ử ắ ị

$('#name').val(Math.random().toFixed(8).toString().substr(2));

socket = io.connect('/chat');

ữ ứ ể

ề t cho phép các ng d ng chatcó th duy trì quy n ệ ụ ủ ứ ư ụ ề Đó là nh ng không gian tên riêng bi ụ t ch trong khi ch y nh tên mi n ph c a ng d ng Node. ạ ự ủ $('#btn-send').click(function(){ sendMessage(); })

var sendMessage = function() {

socket.emit('user-message', {name : $('#name').val() , message : $

('#msg').val() });

$('#msg').val('');

}

ả ỉ ơ ườ ng nh p tên và ậ

SendMessage ch đ n gi n là l y các giá tr đ

c l u tr trong tr ữ ng mà chúng ta có th phát ra tr

ộ ố ượ ẽ ự ộ ở ể ả # msg # vì đ ng xóa vùng văn b n

ng văn b n ủ i dùng có th g i m t tin nh n m i. ị ượ ư ấ ả # msg #, khi n chúng thành m t đ i t c g i chúng tôi s t ắ ượ ử ớ ắ tr ườ ế i máy ch . Sau khi tin nh n đ l ạ v y ng ộ ậ ể ử ườ

ầ ự ệ ạ ủ ỉ ơ ế ắ ả

i c a các mã trên client ch đ n gi n là l ng nghe cho các s ki n đ n và c p nh t các cu c h i tho i phù h p. ộ ộ ậ Ph n còn l ậ ạ ợ

socket.on('user-ready', function (data) {

$('#incoming').append('

style="color:'+data.color+'">'+data.name +' :: connected
');

});

socket.on('user-message', function (data) {

$('#incoming').append(''+data.name +' :: '+ data.message+'
');

});

socket.on('user-disconnected', function (data) {

$('#incoming').append('

style="color:'+data.color+'">'+data.name +' :: disconnected
');

ư ư ệ ồ ượ ể c đ

trong th m c node_modules t L u ý, trong trang HTML hãy ch c ch n r ng có bao g m th vi n Socket.IO đ ắ ằ ắ i th m c g c c a server. ư ụ ố ủ ư ụ ạ

ử T i th i đi m này, chúng ta đã có m t server webchat đ n gi n có th l ng nghe và g i ể ắ ả ờ ộ

i dùng k t n i không gian tên c a ng d ng "/ chat". ạ tin nh n cho t ắ ể t c ng ấ ả ườ ế ố ụ ơ ủ ứ

Đ có đ c các module và ch y, cd vào t ng ng d ng và cài đ t ph thu c c a nó: ể ượ ừ ứ ộ ủ ụ ụ ạ ặ

cd mydomain.com

npm install -d

. Di chuy n vào bên trong th m c ể ư ụ mydomain.com và b tắ ư ậ

L u và thoát kh iỏ các t p tin ụ . đ uầ ch yạ ng d ng ứ

node app.js

Bây gi m trình duy t và vào đ ờ ở ệ ườ ng d n : ẫ

http://localhost:8080

K t qu : ả ế

K t lu n ế ậ

Node.js đòi h i ph i làm thêm nhi u vi c, nh ng ph n th ư ề ệ ả ầ ỏ ưở ủ

ạ ộ ị ng c a m t ng d ng ụ ộ ứ ệ ầ ứ ẹ

ệ ớ ế ố ượ ụ ề ầ ọ

ự ự nhanh chóng và m nh m là giá tr nó. Node.js là m t công ngh đ y h a h n và là s l a ứ c ch ng ch n tuy t v i cho m t ng d ng c n có hi u năng cao, nhi u k t n i. Nó đã đ ệ minh b i các công ty nh Microsoft, eBay và Yahoo. ẽ ộ ứ ư ở