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);
// =>
ề
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:
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
window.onload = function(){
var input = document.getElementById('input');
var output = document.getElementById('output');
var socket = io.connect('localhost',{port: 8080});
socket.on("connect",function(){
console.log("Connected to the server");
});
socket.on('message',function(data) {
output.innerHTML = '=' + data;
});
socket.on('error', function (data) {
console.log("error:",data);
}
);
window.sendMessage = function(){
socket.send(input.value);
};
}
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. ẽ ộ ứ ư ở