37836
TRANSCRIPT
-
8/18/2019 37836
1/55
-
8/18/2019 37836
2/55
1
ประวัตการแก ไข
ครั งท วันท
รายละเอยดการแก ไข
1 9 ม.ค. 2559 เร มสราง และเผยแพรผลงาน2 10 ม.ค. 2559 เพ มเร อง MySQL เขาไป
ถาทานดาวน โหลดท งไวนาน แลวเพ งมาเปดอาน
กขอรบกวนให โหลดใหมอกคร ังท
http://www.patanasongsivilai.com/itebook_form.html
เผ อผมอัพเดตแก ไข pdf ตัวใหมเขาไป หรอใครไปดาวน โหลดมาจากท อ น
กอาจพลาดเวอรช ันใหมลาสดไดครับ
และรบกวนชวยกรอกแบบสอบถาม ตามลงคขางบนดวยนะครับ
แอดมนโฮ โอนอยอก
(จตรพัชร พัฒนทรงศว ไล)
9 มกราคม 2559
ถาสนใจเก ยวกับเพจดานไอท กตดตามไดท https://www.facebook.com/programmerthai/
EBook เลมนสงวนลขสทธตามกฎหมาย หามมใหผ ใด นาไปเผยแพรตอสาธารณะ เพ อประโยชนในการคา หรออ นๆโดย
ไมไดรับความยนยอมเปนลายลักษณอักษรจากผ เขยน ผ ใดละเมด จะถกดาเนนคดตามกฎหมายสงสด
-
8/18/2019 37836
3/55
2
กอนจะอานหนังสอเลมน
สาหรับใครท เพ งเปดเลมน ข นมาอาน แลวยังไมร วา Node.js คออะไร มันใชทาอะไร รวมทั งทฤษฎโนนน นั นผมไดอธบายไวแลว ในหนังสอท ผมแตง 2 เลม ไดแก
1)
“เสยดายไม ไดอาน จาวาสครปตฝ งเซรฟเวอร (Node.js ฉบับยอ) เลม 1”2)
และควรจะอานอกเลมเสรมคอ “วธตดตั ง Node.js และ npm เบ องตน”
(ลงคดาวน โหลด http://www.patanasongsivilai.com/itebook_form.html)
เกร นนา
หนังสอเลมน จะอธบายเก ยวกับ Node.js โดยจะตะลอนทัวรพาทาเวรคชอป (work shop) งาย ๆ เพ อใหเหนภาพรวมของการใชงานภาคปฏบัต มากกวาภาคทฤษฎ ซ งเน อหาคงไม ไดเจาะลกรายละเอยดข ันเทพมากมาย
แตกหวังวามันจะชวยประหยัดเวลาในการเรยนร ของคณ และสามารถชวยคณนาไปตอยอดงานในอนาคตได
สดทายน หากเน อหามอะไรผดพลาดไป เช น ใหขอมลผด สะกดอะไรผดไป มมแปกบาง ขาบาง หรออานแลวมนงงไป 7 วนั เปนตน ผมกขออภัยมา ณ โอกาสน ดวย และถาคณเขาใจ ไมเขาใจยังไง กสามารถช แนะผมไดตลอดเวลา
…อกทั งผมกตั งใจจะหมั นอัพเดตเน อหา ข นอย กับเวลา โอกาส และความสามารถจะอานวย
-
8/18/2019 37836
4/55
3
การอานและเขยนไฟล
ในบทน จะกลาวถงมอดล fs ซ งม ไวอานและเขยนไฟล โดยผมจะแนะนาการใชงานเบ องตนเทาน ัน ซ งถาใคร
เคยอานเลมแรกของผม กจะเหนวธ ใชงานผานตามาแลว ดวยประโยคคาสั ง
var fs = require('fs');
วธอานไฟล
ในตัวอยางน ผมจะใชมอดล fs อานไฟลช อ “json.text” ซ งขอความขางใน มันคอชนดขอมลแบบ JSON
โครงสรางโปรเจคกจะเปนดังน
C:\testfile|-- files
|-- json.txt
|--readfile.js
var fs = require('fs'); // โหลดมอดล fs
fs.readFile('./files/json.txt', 'utf8', function(err, buffer) {if (err) {
console.log(err); // แสดงขอความผดพลาดออกมา
}
console.log(buffer.toString()); // แสดงขอความท อย ในไฟล json.txt
});
console.log('Read a file...');
{"Font":[
{"color":"red", "lang":"thai"},
{"color":"blue", "lang":"eng"}
]}
ภายในไฟลจะเขยนโคดดังน
ออบเจกตท เรยกวา Buffer
-
8/18/2019 37836
5/55
4
เม อพมพคาสั ง “node readfile.js” กจะไดผลลัพธดังน
C:\testfile>node readfile.js
Read a file…{"Font":[
{"color":"red", "lang":"thai"},
{"color":"blue", "lang":"eng"}
]}
เม อยอนกลับไปท โคด คาอากวเมนตตัวท สองของ fs.readFile(…, 'utf8' ,…) จะเปนการบอกคา encodingหรอการเขารหัสตัวอักษร (ในตัวอยางน คอ 'utf8') ซ งเราจะระบ ไว หรอจะไมระบ ไวเลยก ได ดังโคดตัวอยาง
fs.readFile('./files/json.txt', function(err, buffer){ /*...*/ }
*** แตถาไมระบ ไว …โดยดฟอลตแลว คา encoding จะเปน null
ถาไฟล json.txt อย ท ไดเรคเทอร เดยวกันกับ readfile.js ก ไมตองระบช อพาธ ดังโคดตัวอยาง
fs.readFile('json.txt', function(err, buffer){ /*...*/ }
วธเขยนไฟล
ผมจะสรางไฟล “writefile.js” ในโปรเจคเดม …เพ อเอาไวเขยนขอความ “'I am a programmer” ลงไปใน
ไฟล “message.txt” โดยจะม โครงสรางโปรเจคดังน C:\testfile
|-- files
|-- json.txt
|--readfile.js
|-- writefile.js
จะเหนโคดในหนาถัดไป
ไม ได ใชงานสาหรับตัวอยางน
-
8/18/2019 37836
6/55
v
fs
);
c
ใ
C:E
It'
ถ
จ
r f
wr
ns
ตัว
\ted
s s
ไป
ม
s
ite
'
'
ol
อย
stfiwri
v
เป
อค
r
il
'./fi
'I a
'ut
fu
} /
.lo
าง
iletin
d!
โฟ
วา
q
(
les
8',
ct
ส
g('
เม
nt
ลเ
“
ire
/m
p
io
i
}
ส
n
อพ
dee
อร
I a
('fs
es
ro
(
(
onฟ
w
มพ
w file
C
');
ag
ra
rr)
rr)
solกช
riti
คา
rit
:\t
p
/
e.t
{
{
c
e.l น
ng
สั ง
fil
st
rog
โ
t',
er '
ns
og(
th
“n
.js
ile
ra
ล
',
ol
'It\
fi
od
\fil
เ
ม
.l
's s
e');
es
er
าร
ดล
g(
av
rit
ค
ด
ช อ
ขอ
หัส
fs
rr)
d!'
fil
วร
งน
ไฟ
คว
(ร
;
');
e.j
จะเ
รั
ท
าม
บ
”
หน
ะเ
จะ
ร
//
จะ
ช อ
ย
เข
ไม
แ
ได
ฟ
ข
น
ไ
ดง
ล
“
คว
งไ
)
ขอ
ัพ
me
าม
ห
คว
ดัง
ss
ลงไ
รอ
ม
น
ge
ป
จะ
ดพ
.tx
ชเ
ลา
”
น
ดอ
ก
อ
ก
รา
เจ
า
ข
กต
มา
Bu
แ
ffe
ะเ
r ก
ม อ
ด
ปด
อา
5
นก
-
8/18/2019 37836
7/55
6
เม อยอนกลับไปท โคดเดม ในเมธอด fs.writeFile() จะมรายละเอยดของคาอากวเมนตท นาสนใจดังน
คาอากวเมนตตัวแรกจะบอกช อไฟล ./files/message.txt ซ งมันจะถกสรางข นมาใหมทกครั ง เม อ
เรยกเมธอด fs.writeFile() ใหทางาน …แตถาระบแคช อเปน “message.txt” (ไมมพาธ) ไฟลกจะถก
สรางข นในไดเรคทอร เด ยวกันกับ writefile.js
คาอากวเมนตตัวท 2 จะเปนขอความท เขยนลงไป ซ งในท น คอ “I am a programmer” แต
ขณะเดยวกัน เรากสามารถระบเปนออบเจกต Buffer ไดดวย
คาอากวเมนตตัวท 3 จะบอกคา encoding เปน 'utf8' แตถาไมไดระบคาน โดยดฟอลตแลวจะเปน
'utf8'
หมายเหต
สาหรับรายละเอยดของ fs.readFile() กบั fs.writeFile() มันยังมตออกนะครับ ลองอานเพ มเตมด ไดท
https://nodejs.org/api/fs.html
ไมเพยงเทาน ัน ในมอดล fs กยังมเมธอดอ น ๆ อกเยอะมาก แตผมขอตัดจบกอน เพราะคดวาทานนาจะเขาใจ
หลักการทางานไมยากแหละ
-
8/18/2019 37836
8/55
-
8/18/2019 37836
9/55
8
สวนวธการเขาถงคาในบัฟเฟอร กจะเหมอนเวลาคณใชงานอารเรย ดังตัวอยาง
var buf = new Buffer('Hello World');
console.log(buf[10]); // แสดงตัวเลข 100 ออกมา (คา ASII คอ d ตัวพมพเลก) buf[10] = 90; // แก ไขตัวอักษรท อนเดกซ 10 ใหมคาเปน 90 (คา ASCII คอ Z ตัวพมพ ใหญ)
console.log(buf.toString()); // แสดงผล “Hello WorlZ”
ในตัวอยางน ตัวแปร buf คอบัฟเฟอร ท เกบคาสตรงเปน “Hello World” โดยเราสามารถเขาถงตัวอักษรท อย
ในสตรง ดวยการระบตาแหนงอนเดกซภายในวงเลบเหล ยม (buf[index]) เหมอนเปนอารเรยธรรมดาตัวหน ง
อยางท บอกในตอนตน บัฟเฟอรสามารถจัดการในระดับไบตได ดังน ันตอนสรางบัฟเฟอร เราจงสามารถระบ
ขนาดใหมหนวยเปนไบต ได แตคาเร มตนของสมาชกในบัฟเฟอร มันจะมคาแบบส ม (Random) ดังตัวอยาง
var buf = new Buffer(10); // สรางบัฟเฟอรขนาด 10 ไบต
// คาสมาชกภายในบัฟเฟอร จะถกกาหนดคาเร มตนเปนแบบส ม
console.log(buf);
// แสดงผลลัพธ
ในตัวอยางถาลองใช console.log(buf) แสดงคาสมาชกภายในบัฟเฟอรออกมา กจะเหนมันเกบคาเร มตนเปน
แบบส ม
บัฟเฟอรมันยังมเมธอด slice() เอาไวตัดแบงสตรงใหเลกลง ดังตัวอยาง
var buffer = new Buffer('Hello World');
var smaller = buffer.slice(6, 11);
console.log(smaller.toString()); // "World"
console.log(smaller === buffer); // false
ในตัวอยางน ประโยค buffer.slice(6, 11); จะตัดแบงสตรงตัวเดม จากอนเดกซตาแหนงท 6 ไปจนถงตาแหนง
ท 11 (ตัวสดทาย) แลวไดเปนบัฟเฟอรตัวใหมท เกบคาสตรงเปน "World"
-
8/18/2019 37836
10/55
9
นอกจากน แลวบัฟเฟอรยังมเมธอด copy() เอาไวกอปป คาสตรงจากบัฟเฟอรตัวหน ง ไปยังบัฟเฟอรอกตัว ดัง
ตัวอยาง
var source = new Buffer('Hello World'); var target = new Buffer(6);
var targetStart = 0;
var sourceStart =6;
var sourceEnd = 11;
source.copy(target, targetStart, sourceStart, sourceEnd);
console.log(target.toString()); // "World"
console.log(target === source); // false
ในตัวอยางน จะกอปป คาสตรงจากตัวแปร source โดยเร มจากอนเดกซตาแหนงท 6 จนถง 11 แลวนาคาสตรง
ท ไดมาใส ไว ในตัวแปร target ตั งแตอนเดกซ 0
…สาหรับผลการทางานของตัวอยางน จะเหมอนกับการใชเมธอด slice() ในตัวอยางกอนหนาน ทกประการ
หมายเหต
สาหรับรายละเอยดของ Buffer มากกวาน สามารถดเพ มเตมไดท
https://nodejs.org/api/buffer.html#buffer_new_buffer_array
-
8/18/2019 37836
11/55
10
แนวคด EMITTER PATTERN
อยางท ทานทราบ คอลแบคใน Node.js จะถกเรยกเม อเกดเหตการณเกดข นมา
แตเรากสามารถสรางเหตการณ ไดดวยตัวเอง ดวยรปแบบการเขยนโปรแกรมท เรยกวา Emitter pattern ซ ง
มันคลาย ๆ กับด ไซนแพทเทรน (Design pattern) ท เรยกวา “observer pattern”
…เอานะ ถาใครไมร จักด ไซนแพทเทรนดังกลาว เด ยวผมจะอธบายดวยรปภาพตอไปน แลวกัน
จากรป Event emitter กคอออบเจกต ท มคอลแบคมาลงทะเบยนไดแก function_1 กับ function_2 ซ ง
พวกมันจะทาหนาท เปน Listener หรอผ ฟงเหตการณท เกดข น ไดแก "data" กับ "connection"
…สาหรับเหตการณ "data" กับ "connection" เราสามารถตั งช อเปนสตรงอะไรกได แลวเม อเกดเหตการณ
ดังกลาวข นมา ตัวคอลแบคกจะถกเรยกใหทางาน ดังภาพขางลาง
ในภาพเม อ Event emitter สงเหตการณ "data" กับ "connection" ตัวคอลแบคไดแก function_1 กับ
function_2 กจะถกเรยกใหทางานตามลาดับ
ลงทะเบยนดวยเหตการณ "connection"
สงเหตการณ "connection"
สงเหตการณ "data"
ฟงกช ันคอลแบคช อ
function_2
ลงทะเบยนดวยเหตการณ "data"
ฟงกช ันคอลแบคช อ
function_1
function 2
function_1
Event emitter
Event emitter
ลงทะเบยน
ถกเรยกใหทางาน
-
8/18/2019 37836
12/55
11
เพ อไม ใหเปนการเสยเวลา ดตัวอยางโคดกันดกวา …มันงายมากเลย
var events = require('events');
var eventEmitter = new events.EventEmitter(); // สรางออบเจกต Event emitter eventEmitter.on('data', function(){ // ลงทะเบยนคอลแบค ดวยเหตการณ "data"
console.log('Listen data');
});
eventEmitter.on('connection', function(){ // ลงทะเบยนคอลแบค ดวยเหตการณ "connection"
console.log('Listen connection');
});eventEmitter.emit('data'); // สงเหตการณ "data"
eventEmitter.emit('connection'); // สงเหตการณ "connection"
โคดในตัวอยางน มันจะแสดงผลลัพธเปน
Listen data
Listen connection
ในโคดจะมรายละเอยดท นาสนใจดังน
เมธอด eventEmitter.on() คอการลงทะเบยนคอลแบค พรอมทั งระบเหตการณท จะรับฟง
สวน eventEmitter.emit() คอการสงเหตการณ เพ อเรยกคอลแบค (ท ลงทะเบยนไว) ใหทางาน
นอกจากน แลว Event emitter มันยังมเมธอดอ นอก นอกจาก on() กับ emit() ตัวอยางเชน
เมธอด คาอธบายaddListener ใชงานเหมอนกับเมธอด onremoveEventListener ลบคอลแบคท ไดลงทะเบยนไว removeAllEventListeners ลบคอลแบคทั งหมดท ไดลงทะเบยนไว
-
8/18/2019 37836
13/55
12
นอกจากน แลวเราสามารถสรางคลาสข นมา แลวสบทอดมาจาก Event emitter ดวยเมธอด util.inherits()
ดังตัวอยางโคดตอไปน
var util = require('util'); var events = require('events');
class Ticker{ // ประกาศคลาสใน ES6
constructor(){ // ประกาศคอนสตรัคเตอร ใน ES6
let handler = () => this.emit('tick'); // ฟงกชั นลกศรท ช อ handler
// เม อออบเจกตถกสรางข นมาจากคลาส Ticker
// กจะทางานแบบอะซงโครนัส ดวยการดเลยเรยกฟงกชั น handler ทก ๆ 1 วนาท
setInterval(handler, 1000); // 1000 milliseconds
}
}
// คลาส Ticker สบทอดมาจาก events.EventEmitter
util.inherits(Ticker, events.EventEmitter);
let ticker = new Ticker(); // สรางออบเจกตดวยโอเปอเรเตอร new
ticker.on('tick', function() { // ลงทะเบยนคอลแบคดวยเหตการณ 'tick'
console.log("tick tock");
});
ในตัวอยางน ผมเขยนโคดดวย ES6 (เขยน ES5 แบบเดมก ได แตย งยากมาก) ซ งการทางานกจะไดตามภาพ
เรยกใช emit('tick')
ลงทะเบยนดวย on('tick', ….)
ออบเจกต
ticker
function() {
console.log("tick");
}
-
8/18/2019 37836
14/55
-
8/18/2019 37836
15/55
ใ
เว
ไม
เ
ผ
C:C:
ใ
n
ค
ชั
ห
ถั
ผ
บ
รค
กน
ร
จะ
\m \c
พ
m
สั ง
อ
า
ไป
เข
น
อ
สม
ม
สร
kdi
พ
in
น จ
ไร
เห
กยั
ยน
ผม
งา
ตา
ป
างโ
ir eb
าสั
it -
ะส
มแ
ต
งได
ะ
ะ
ยง
แ
รเ
ฟล
eap
ง n
y
าง
พก
รง
แ
รั
าค
ย
ล
ค
เดอ
ap
p
ฟ
เก
ๆ
ท
“
ณ
…เ
(เ
ห
ร
p
ดั
“
อะ
แล
ม
ธ
อง
ร
ย
พ
e
งต
pa
ไร
ว เ
นะ
ดต
เท
ะถ
กั
อ
a
ไป
ka
ดต
รา
นา
ง
ว
าไ
ปะ
ก
p
น
ge.
งล
า
ห
o
บ
วร
พ
)
อ
เอา
so
บ
าร
รา
e.j
ไป
ค
ไวเ
n”
ง เ
ถตั
งไว
s แ
ดว
ม
น
ซ ง
ปน
ข ั
ก
ละ
เ
ส
ดว
อ
จะ
ตน
ต
พ อ
n
างเ
ธส
ย ข
ช
ไฟ
น
ใช
m
แ
วบ
ราง
งโ
ธบ
ลน
า
ร
เบ
อ
แอ
เว
รเ
าย
จะ
สร
าร
งต
พ
แ
จค
ปร
ก
าง
จัด
น”
ล
ลเค
พ
แล
เจ
รา
pa
า
)
เค
ชั น
วย
ะ
ขอ
งข
cka
โป
ชั
เบ
N
d
งเ
ม
ge
รเจ
ขอ
งต
d
เขา
า (
แ
.js
คใ
ว
า
นด
.js
ปใ
m
ว
n
อ
มภ
วย
กเ
นไ
ta
ย ใ
ปเ
าค
าย
N
หม
เร
at
โ
ลย
ตไ
น
de
อน
คเ
a)
ลเ
ได
งา
ฟล
.js
เวล
อร
ชน
อ
ส
ยข
p
โด
าค
ดัง
โ
w
าม
น
ck
จะ
ณไ
ลา
รเ
eb
รถ
(ล
ag
อธ
เ
ว
ค
ap
ขา
อง
.js
บา
อน
วย
ออ
ด
ไ
าน
n
เป
ถ น
คา
ะไ
งร
ยัง
ห
นแ
อส
สั ง
เว
หัว
งส
14
นว
าน
อร
ขอ
อท
-
8/18/2019 37836
16/55
-
8/18/2019 37836
17/55
16
มาเขยนไฟลจาวาสครปต เพ อสรางเวบแอพกันเถอะ
ผมจะโหลดมอดลท ช อ “express” เขามา ดวยประโยคคาสั งดังตัวอยาง
var express = require('express');
var app = express();
เราสามารถใชออบเจกต app มารับรเควสต (Request) จากเวบบราวเซอรเปนแบบ GET ดวยโคดดังตัวอยาง
app.get('/', function(req, res) {
res.send('Hello world '); // สงเรสปอนส (Response) ตอบกลับออกไป
});
ในตัวอยางจะเหนวา เมธอด app.get() จะรับคาอากวเมนตตัวแรกคอ path (URL) สวนตัวท สองจะเปนคอล
แบค ซ งมพารามเตอร 2 ตัว ไดแก
ตัวแปร req จะรับคาเปนออบเจกต (ตัวแทนรเควสต)
ตัวแปร res จะรับค าเปนออบเจกต ซ งมเมธอด send() เอาไวสงเรสปอนสตอบกลับไปยังหนาเวบ
บราวเซอรท เรยกเขามา จรง ๆ แลวคอลแบคดังกลาว มันยังมพารามเตอรตัวสาม ซ งรับคาเขามาเปนฟงกชั นคอลแบคอกท
เพ อเรยกตอไปยัง middleware ตัวถัดไปใหทางาน (เด ยวจะไดเหนในบทถัด ๆ ไป)
***นอกจากน แลว app ยังมเมธอดอ นอก ตัวอยางเชน app.post(), app.put() และอ น ๆ อก …ซ งช อเมธอด
จะตรงกับช อ METHOD ของโปรโตคอล HTTP อกดวยนะครับ
ขอเพ มเตมสักเลกนอย สาหรับออบเจกต res ในตัวอยางเดม มันยังมเมธอดท นาสนใจดังน
เมธอด หนาท res.download() ให ไคลเอนตดาวน โหลดไฟล ไปใชงานres.end() ส นสดการสงเรสปอนส res.json() สงเรสปอนสเปนแบบ JSONres.jsonp() สงเรสปอนสเปนแบบ JSONP
res.redirect() เปล ยนทศทางรเควสตท ตดตอเขามาres.render() สั งใหเทมเพลต (temple engine) แสดงผลบนหนาเวบ (จะเหนการใชงานในบทถัดไป)
-
8/18/2019 37836
18/55
-
8/18/2019 37836
19/55
-
8/18/2019 37836
20/55
19
ขอแทรกดวย RESTful
คาวาเวบเซอรวสในมมผ เขยน มันคอเซอรวสฝ งเซรฟเวอรท ใหบรการอะไรสักอยาง โดยท ไคลเอนตเวลาตดตอ
กับฝ งเซรฟเวอร ทั งค จะไมแครวาอย บนฮารดแวร หรอ OS อะไร (ไมสนใจแพลทฟอรม) และไมสนใจวาทั งสอง
ฝ งใชภาษาโปรแกรมอะไรในการคยกัน แตทั งน เวลาไคลเอนตขอใชบรการจากเซอรวส ขอมลจะตองว งอย บน
โปรโตคอลของเวบไซตคอ HTML …ดวยเหตน เขาถงเรยกมันวา เวบเซอรวส
ถงอยางไรกตามฝ งเซรฟเวอรผ ใหบรการ กับฝ งไคลเอนต จะตองตกลงกันกอนวา จะใหคยกันดวยรปแบบไหน(ว งอย บน HTML น ันแหละ) ซ งในปจจบันจะนยมใชเปน SOAP หรอ RESTful (เรยกสั น ๆ วา REST)
แต ในบทน จะกลาวถงเวบเซอรวสแบบ REST อยางเดยว ซ งสามารถสงขอมลไดเปน ขอความ, JSON และ
XML …และเพ อไม ใหเปนการเสยเวลา กจะใหดตัวอยางในหัวขอถัดไปแลวกันนะ
เตรยมไฟล JSON ตัวอยาง
{"Font":[
{"color":"red", "lang":"thai"},
{"color":"blue", "lang":"eng"}
]}
ผมจะบันทกไฟลน อย ในโปรเจคเดมเปนช อ “font.json”
C:\webapp
|-- node_modules\...
|-- package.json
|-- app.js
|-- font.json
HTTP ในหัวขอน ผมจะพาทาเวบเซอรวส (Web Service) …ซ งช อ
ของมันข นตนดวยเวบกจรง แตมันไม ใชเวบไซตนะ
Web service
-
8/18/2019 37836
21/55
20
แก ไขไฟล app.js
ในตัวอยางน ผมไดนาไฟล app.js ของตัวอยางเดม มาแก ไขเสยใหมดังน
var express = require('express');
var app = express();
var fs = require("fs");
app.get('/listFont', function(req, res) { // http://ipaddress:8081/listFont
fs.readFile( __dirname + "/" + "font.json", function (err, data) {
if (err){
console.error('Error read a file:', err.stack);
}
res.end( data );
}); // ส นสดคอลแบค
});
app.listen(8081, function() {
console.log('Server running at http://localhost:8081/');
});
console.log("Start server");
เม อนาไฟล app.js มารันจะไดผลลัพธดังน
C:\code\webapp>node app.js
Start server
Server running at http://localhost:8081/
เปล ยนพอรตจาก 8080 เปน 8081 (ตั งเปนอะไรก ได)
ตัวแปร __dirname จะมขดลางสองอันวางตดกันซ งจะแทนท ดวยช อไดเรคเทอร ซ งไฟล app.js มันอาศัยอย
อานเน อหาในไฟล font.json
แลวสง data (Buffer) กลับออกไปหาไคลเอนต
-
8/18/2019 37836
22/55
เม
เซ
...
จ
มเ
ส
ห
ส
ht
อไ
รฟ
ด
กไ
ร อ
หร
า
หร
tp:
ลเ
เวอ
เร
ล
ท
บเ
เห
บร
//
อน
รก
สา
fo
ม
สา
โป
สาDE
ใน
อง
ต
าย
xp
ตต
ะ
า
t.j
อง
รั
แก
รัLE
ัว
เว
ะเ
res
ต
อ
ถ
so
เมา
ใค
รม
RE,
ยา
เซ
ย
sjs.
เข
กล
ดส
แ
สม
รท
า
ESP
น
รว
ข
co
าม
บอ
อบ
สด
อย
ังไ
ัวเ
ใ ST
ช
สแ
ง
m/
ดว
อก
กา
โช
ด
มร
ปน
ตั ได
ES
บบ
xp
en
ยโ
ป
ท
อ
น
ัก
ค
อยอก
T
R
re
4x
รโ
ดว
งา
ก
RE
เอ
างดว
ับ
ST
s
/a
ตค
ยข
อ
าด
T
ต
จ
อ
ผ
าก
i.h
ล
ม
าง
งภ
…เ
น
ใช
ล
ก
กว
tm
ht
J
งา
าพ
าไ
า
M
x
ะแ
น
l
p (
O
ๆ
จา
แล
T
re
สด
ถา
แบ
(
ดว
เป
สง
O
s
งา
น
บ
าน
ยก
ต
รเค
เ
แ
ย ๆ
จก
E
มา
ารเ
งใ
วส
น
จร
ผ
อา
h
) เ
จา
ปด
เว
ต ไ
GE
ง
น
เพ
ttp
น
ไฟ
หน
บบ
ขอ
T
แ
าร
มเ
://l
ht
ล
าเว
รา
ใช
ตจ
ว
ช
มไ
oc
JS
p:
on
บข
เซ
ร
รง
ยัง
Ex
ดท
alh
ON
/l
t.js
นม
อร
าร
ๆ
ม
re
os
ca
on
า แ
งร
จา
ลว
ด
ss
:8
lh
ลว
เคว
เซ
ยัง
ทา
หเ
81
st:
กร
สต
รฟ
า
งเล
น
/li
80
ก
แ
วอ
าร
อก
ป
tF
1/
UR
สา
รก
ถใ
อ น
ไอ
nt
list
L
มา
ด
เป
ใ
ดย
Fo
จะ
ถเ
P
แ
เท
nt
เห
ย
UT
นไ
น
p
...
ข
,
ด
อน
p.j
ง
คว
ครั
21
าม
บ
-
8/18/2019 37836
23/55
ส
ค
“เ
ข ั
ต
n
ก
จ
ใ
บเ
g
…
หร
ม
รง
ตั ง
m
น
กภ
ได
กร
n
ลอ
บว
ก
ว
อ
มอ
in
ะไ
าพ
รค
อนะ
ra
ลน
ธน
ทา
”
ท
ดล
ta
ข ั
ใน
(เม
แต
ท เ
ทอ
นธ
or
นะ
ผม
า
ต
1
ex
l e
ต
นโ
อ
ถาเ
น
รดั
าผ น
ซ ง
ครั
กดั
ข ั
วา
pr
xp
น
ดว
se
ปน
ะเ
ท ก
ได ัน
เจ
เ
ดแ
ต
เรา
ss
res
ดไ
ก ใ
na
M
น
ลา
แนลก
าข
า
ล
น
ตอ
ge
s-g
ป
ห ไ
m
ac
ฟ
ม
ะนท ง
องเ
อง
มา
อไ
พ
ne
en
อย
ท
ค
S
e
โ
ชบ
า Eเก
ดย
เดย
ส
จา
ปน
พ
at
ra
าก
“C
อช
หร
pr
ยม
นว
xpนไ
กั
วกั
ร
กล
เล
า
r
tor
ห
:\
โ
L
es
นจ
นโ
resป
กั
บ
ง
ค
...
งเ
วย
-g
ณ
se
ลเ
in
(ใ
ะใ
วส
sจง
เย
xp
ว
แ
ซ ง
อะ
คา
อ
s\
อ
x
บ
เป
น
นเ
res
ละ
ัน
หน
ั ง
เป
s
ขอ
ให
นตั
แตะน
รก
s
อ
ht
จะ
อย
อไ
ได
rn
งผ
ไป
ac
วรั
มาใ
ซ
งมั
p:/
รา
แ
น
เร
m
ชง
“
OS
คา
เม
ได
ะใ ใ
ับ
ส
เ
/ex
งเ
ๆ
ท
e \
าน
/u
ห
สั ง
ใช
รค
หค ม
ท
าง
pre
บไ
ๆ
ร ด
p
น
r/l
อ
“e
แฟ
อ
ณลอด
าฟ
เว
น
ssj
ดร
งต
D
คร
oc
Lin
xp
ลก
ซ ง
มมล
(ต
ได
แ
.co
ดเ
ไป
ta
อง)
l/
ux)
es
ปน
ได
นไex
ง ๆ
าย
m/
รว
น
R
ha
กั
”
–
ด
กre
โ
กว
เ
en
ส
a
re
e
จ
จ
ง
อนss-
ะ)
า
ง
sta
กับ
in
np
xp
ะได
ต
p
ช
ว
rter
ท
g\n
m”
es
เห
ตั ง
เ
น
น
/ge
น
p
.c
ใ
มอ
อา
Ma
ner
อ
”
d
ข ัน
ดล
ว
cO
ato
ex
(ใ
ตอ
วท
S
r.h
re
บ
นถั
รอ
ml
s
วน
ดไ
Li
แ
โด
u
ะ
ส)
ณ
ท
ซ ง
มต
ป
จะ
22
อง
วา
ย
-
8/18/2019 37836
24/55
23
ข ันตอนท 2
จะใหพมพคาสั งแบบน ครับ
express myapp
ซ งคาสั งน จะสรางโฟลเดอร myapp โดยดผลการทางาน จากหนาจอขางลางเลยครับ
C:\>express myapp
create : myapp
create : myapp/package.json
create : myapp/app.js
create : myapp/public
create : myapp/public/javascripts
create : myapp/public/images
create : myapp/public/stylesheets
create : myapp/public/stylesheets/style.css
create : myapp/routes
create : myapp/routes/index.js
create : myapp/routes/users.jscreate : myapp/views
create : myapp/views/index.jade
create : myapp/views/layout.jade
create : myapp/views/error.jade
create : myapp/bin
create : myapp/bin/www
install dependencies:> cd myapp && npm install
run the app:
> SET DEBUG=myapp:* & npm start
สรางมาใหเราใชงานเสรจสรรพ
พมพคาสั งน ในข ันตอนท 3
พมพคาสั งน ในข ันตอนท 4
ช อ โปรเจคเรา จะสรางเปนช ออะไรก ได
-
8/18/2019 37836
25/55
24
ข ันตอนท 3
จะให cd เขาไปในโฟลเดอร myapp ท ถกสรางข นมา (ในข ันตอนท 2)
C:\>cd myapp
C:\myapp>
ซ งมันจะม โครงสรางโปรเจคดังตอไปน
C:\myapp>
|-- bin
|-- www|-- public
|-- images
|-- javascripts
|-- stylesheets
|-- style.css
|-- routes
|-- index.js|-- users.js
|-- views
|-- error.jade
|-- index.jade
|-- layout.jade
|-- app.js
|-- package.json
ไฟลท เหนทั งหมด เด ยวจะอธบายภายหลังนะครับ …แตจะใหลองเปดด ไฟล package.json ข นมากอน ซ งจะ
เหนช อ dependencies ตาง ๆ แตทวามันยังไมถกดาวน โหลดมาตดตั งใหนะครับ
ดวยเหตน เราจงตองตดตั งดวยมอตนเอง ดวยคาสั งขางลาง (เสยเวลารอนานหนอย)
C:\myapp>npm install
เอาไวเกบรปภาพ, จาวาสครปต, CSS
เปนเทมเพลตหนาเวบ
ใชกาหนดคาเร มตนตาง ๆ ซ งภายหลังจะถกไฟล www โหลดเขาไป
ทาตัวเปนเราเตอร (Router)
เพ อเลอกไฟล *.jade มาแสดงผล
ถกใชรันเปนเซรฟเวอร โดยเปดพอรต 3000 เอาไว
-
8/18/2019 37836
26/55
ข ั
ข ั
s
ซ
C:
>
>
แ
$
ข ั
ล
จ
ต
t
จะ
\m
m
no
y
ถา
DE
งเ
ได
อ
น
EB
ให
ya
a
de
ap
ค
BU
อ
ด
ผล
ท
จะ
UG
ล
p
p
./
:s
ใช
G=
ท
วบ
ัพ
4
เป
=
พธ
se
0.
in
rv
า
m
5
บร
ดัง
ก
ya
ดัง
t
.0
w
er
บ
ap
วเ
ภา
รรั
pp
EB
st
w
is
M
p:*
อ
ไ
:*
UG
rt
en
ac
n
เพ
ล
n
=
C:\
ing
S
m
อก
"w
p
ya
m
o
หร
st
อ
w
s
pp
ap
p
อ
rt
U
" ห
art
:*
p
ort
in
RL
รอ
n
3
x
เป
ั งใ
p
00
ใ
น
เอ
เว
s
+
ใช
tt
าไ
บแ
art
m
า
:/
d
อพ
งเ
lo
b
ลเ
ลา
al
g
ชั
น
ho
ทา
ทน
t:3
งา
00
ก
0
ห ใ
กั
ชค
h
าสั
tp
://localhos :3 00 /u er
25
ก
-
8/18/2019 37836
27/55
ด
ใ
ส
เข
**
"s
ส
กา
หัว
หร
าม
*ใ
cri
"s
หร
ร
ขอ
บไ
อ
ไฟ
ts
ar
บไ
าง
น
ล
ล
: {
":
ล
า
มจ
./
ac
no
ap
ข
ะพ
in
ka
de
p.j
ง
าม
w
e.j
./
มั
ป
ด
w
so
in
เ
รเ
าร
มัน
ถ
w
นม
ค
า
จะ
เร
w
อด
าน
ทา
าไป
"
ลต
ขอ
าน
เป
วห
R
โป
เป
ด
ง
s
e
รเ
เซ
มัน
ท ใ
o
r
u
ค
รฟ
จะ
กา
se
eq
sp
รัน
st
เวอ
ั งร
หน
o
ue
on
ฟ
ob
ap
ร (
นโ
ดค
je
t
se
je
p
ป
รเ
าต
ct
w
t
น
พ
จค
ง
กว
รต
ว
ใ
อร
า
3
คา
กั
ต
ตผ
00
สั ง
เว
Mi
00
มจ
) ซ
ังต
บแ
dd
0
ะอ
เบ
อไ
อพ
.
le
บ
อง
น
ลเค
/bi
โ
ar
ยด
ลั
ชั น
p
n/
หล
e
วย
มั
ต
.j
w
ด
รอ
รป
จะ
ม
s
w
r
า
ห
าพ
p
ut
..
แ
ด
ตัว
.js
ing
วกั
อด
ย
น
ล
งข
ะ
p
าง
26
.js
าง
-
8/18/2019 37836
28/55
-
8/18/2019 37836
29/55
-
8/18/2019 37836
30/55
29
แตทั งน เราตองเลอกวา จะให middleware หมายเลข 4 หรอ 5 ตัวไหนมันทางาน เพราะวา
Middleware หมายเลข 4 จะใชงานในโหมด development
Middleware หมายเลข 5 จะใชงานในโหมด production
การใชงานแบบ production กคอการกาหนดคาในตัวแปร NODE_ENV ซ งตองทากอนรันโปรเจค ดังน
ใชคาสั ง
***แตถาเราไม ไดกาหนดคาอะไรไวเลย กจะหมายถง development โดยดฟอลต
Template engine
การใชงาน Express เราสามารถกาหนด template engine …ซ งมันเปนกลไก เอาไวใชแสดงผลบนหนาเวบ
บราวเซอร และในไฟล app.js กจะเหนโคด 2 บรรทัด ดังน
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
ในตัวอยางน จะใช template engine เปน Jade ซ งจะใช ไฟลนามสกล *.jade เปนตัวแสดงผล สาหรับไฟล
*.jade ภายหลังจะถก render หรอแปลงรางกลายเปน HTML บนเวบบราวเซอรอกท
และเม อด โคดใน app.js กจะมการกาหนดคา routing เปนดังน
export NODE_ENV=production
SET NODE_ENV=production
บน OS X หรอ Linux
บนวนโดวส
C:\webapp
|-- views
|-- error.jade
|-- index.jade
|-- layout.jade
Template engine จะใชเปน jade
จะช ไปยังโฟลเดอร views
-
8/18/2019 37836
31/55
v
v
…
…
a
a
ม
ก
โด
ส
แ
r r
r
…
…
p.
p.
ด
ห
ยท
นไ
ถา
ou
se
…
…
s
s
r
ดใ
ไฟ
ฟล
เก
tes
rs
('/'
('/
ut
หเ
i
us
e
=
r
, r
se
es
น
d
ers
rro
re
q
ut
rs',
กับ
ro
x.j
.js
r ข
ui
ire
s);
us
u
tin
จ
จะ
ม
e('
('./
er
er
g ใ
ะเป
ง
ก
./r
ro
);
s ม
นเ
นต
อค
จะ
ut
te
นจ
ธอ
วเ
วา
ตั
s/
s/u
ะโ
ด
อก
ก
M
in
ser
ล
p
เส
บไ
id
ex'
s');
มา
.u
ท
ปห
le
i
า
');
จา
e()
ง เ
าเว
a
nde
น
กไ
…
พ อ
บบ
re
.jad
r
ล .
ดย
re
รา
า
uti
/r
ระ
nd
เซ
ren
ng
ut
พ
r
อร โ
de
s/
ธเ
ฟ
ดย
r ไ
ind
น
in
ตร
ล
ex
/
de
เ
err
.js
บ
.ja
น '
or.
แ
/us
de
're
ad
ส
ะ
er
ให
po
e (
อ
ง
./r
ต
แส
nd
ห
บเ
อ
ut
ม
ดง
wi
โค
ก
เจ
es
าด
ล
th
ด
r
ต
us
บ
น
a r
pp
ut
ro
rs.
นา
es
.js
er
te
js
เว
ur
อก
ออ
r อ
แล
บ
ce'
ทน
ไป
อก
ถ
าว
ะค
ป
นา
ซอ
บ)
30
ไป
ร
-
8/18/2019 37836
32/55
31
สาหรับ index.js กับ users.js เวลากาหนดใหเปน routing น ัน …ผมจะอธบายดวยภาพขางลางแลวกัน
จากรป สามารถอธบายได โดยยอดังน
ถารเควสตเขามาเปน URL http://ipaddress:3000 กจะใช index.jade เปนตัวแสดงผลหนาเวบ
แตถาเปน http://ipaddress:3000/users กจะสงขอความ "respond with a resource" กลับไป แตถาเกด error ข นมา กจะใช error.jade เปนตัวแสดงผลหนาเวบ
จะขอยอนกลับไปท โคดในไฟล index.js กับ users.js มันจะเรยกใชออบเจกตเราเตอร (Router) ดังน
var router = express.Router(); // เปนออบเจกตเราเตอร
….
router.get('path', function(req, res, next) {
/*… โคดเรา …*/
});
ในตัวอยางน router นอกจากจะมเมธอด get แลว …มันยังมเมธอด post, delete และอ น ๆ ตามช อ
METHOD ของโปรโตคอล HTTP อกดวย
สงขอความ
extends
render
….….Response
error.jade
render
routing
Request
/ /usersMiddleware
จัดการ error
index.jade
layout.jade
"respond with a
resource"
users.js index.js
-
8/18/2019 37836
33/55
เม
<
<
y
l>
วา
เอ
ดไ
PE
-
8/18/2019 37836
34/55
ถ
ห
สม
า
มต
แ
เรา
ดง
กร
ผล
ก
ท
xt
UR
n
L
เน
s
นา
คอ
น
T
ดเ
ง
มา
คา
'N
ะส
L
น
าก
อก
e
ot
รา
ข
ht
หา
r.
Fo
ห
มา
p:
น
es
un
าต
ใ
/l
เว
sa
'
าเ
ห
ca
ไ
e
าห
บ
าถ
lh
พ
งใ
ยอ
ดไ
st:
(
ท
ดใ
30
rr
น
0
r 4
ท ใ
00
ม
ซ
ัก-
ไฟ
ท ไ
ล
น
rr
ท
r.j
ข
d
ตัว
ก
ฟ
ะ
e
กา
ro
รท
.ja
างา
e
นต
ไ
กั
d
กจ
าม
m
บวา
eve
ะท
า
iddl
ะเ
lop
33
ew
น
en
re
rod
t
ัวถั
ucti
ไปข
on
นอ
รอ
-
8/18/2019 37836
35/55
ม
าง
เห
E h
ๆ
มา
ref
มา
า
="/s
กม
เว
tyle
าย
ไซ
she
เช
ตห
ets/
if
ลัก
ห
styl
e
ขอ
นา
.cs
lse
เข
ตา
s">
แ
า h
วบ
ละ
ttp
H
า
://
งอ
ad
L
น
e-l
ไ
an
ตา
.c
งอ
m
ะไร
กบั
อง
ภา
ศก
ษา
าเ
ค
พ ม
ป
เต
ทั ว
ได
ๆ
ครั
ไป
34
ดัง
-
8/18/2019 37836
36/55
ใ
(C
…
ใ
ใ
ห
ต
บ
o
ดย
ภา
ภา
าเ
ง
น
p
EJ
พน
พน
วบ
ะ
ne
S
ห
ห
ผ
แล
ด
nt)
ค
าเ
าเ
ย
ะเ
งม
โด
t
บ
บ
มา
อไ
อด
ยแ
m
ะ
ะ
ให
ใ
ล
ตล
la
ระ
ระ
ม
เป
JS
ค
te
กอ
กอ
นจ
นก
ซ ง
มโ
en
ไ
ไ
ะเ
รเ
มไ
พเ
in
ด
ด
นโ
สย
แ
น
เ
ยค
ยค
คร
วล
ง
สา
ม
อม
อม
รา
ก
od
เท
นา
มา
น
พเ
พเ
ง
จะ
y
ม
จอ
รถ
บ
นน
นต
รอ
หค
พ
ออ
ก
Ja
ต ไ
b
เท
ณ
f
ล
กเ
reu
e
ดแ
dy
เพ
โค
en
ot
o
oo
น
se
ต
ก
แ
ลต
ดท
u
r
y
er
ว
หร
ัน
e
ะ
(T
ช
าเ
ๆ
อน
ะเ
u,
oo
m
สด
โด
าก
น
b
te
pl
งผ
ยแ
บ
น
dy
(น
te
ห
ตล
าใ
ะ
, f
าก
าเ
ะช
งา
อ
ot
ับ
ถก
บ
ส
นใ
เซ
er
าใ
ปร
น
si
น
ม
ท
แล
ชง
ะก
นา
de
า
ด
ัน
si
นใ
บ
ถัด
ar
เร
ดัง
de
หม
น
ป
ก
า
ar
อก
า
า
รั ง
าก
อ
)
คอ
โพ
โ
เน
เน
35
ต
นต
-
8/18/2019 37836
37/55
36
โปรแกรมเมอร ไทย
ในใจนะเจบปวด
ในตัวอยางน ไฟล “home.ejs” จะเขยนเปนโครงรางหนาเวบเอาไวกอน โดยมันจะมนามสกล .ejs …และคณ
นาจะเหนแทก ท ตกรอบสแดงใชมั ยครับ …พวกมันจะถกแทนท ดวยแทก HTML แลวกลายเปน
หนาเวบท สมบรณภายหลัง โดยผมจะอธบายโคดหมายเลข 1, 2, 3 ตามลาดับดังน
ตัวอยางการใช EJS
ถกแทนท ดวยไฟล head_bootstrap.ejs
ใช bootstrap ซ งเปน CSS เฟรมเวรคยอดนยมตัวหน ง
สาหรับเอาไวแสดงผลหนาเวบแบบ responsive ซ งตอน
ท เขยนหนังสอยังเปนเวอรชั น 3 (เวอรชั น 4 เปน alpha)
2
1
3
1
-
8/18/2019 37836
38/55
-
8/18/2019 37836
39/55
38
ในตัวอยางน จะม โครงสรางโปรเจคดังตัวอยาง
c:\ejs
|-- node_modules\...
|-- views
|-- page
|-- about.ejs
|-- home.ejs
|-- template
|-- footer.ejs
|-- head_bootstrap.ejs
|-- menu.ejs
|-- server.js
|-- package.json
ในตัวอยางน ไฟล home.ejs, footer.ejs, head_bootstrap.ejs และ menu.ejs จะนามาจากหัวขอกอนหนา
น แหละ …สวนไฟล about.ejs กับ server.js จะสรางเพ มข นมาใหมเอ อมออง ซ งจะเหนไดดังตอไปน …
ผมจะสรางไฟล “about.ejs” ดังน
น คอการใช EJS
โดยแอดมนโฮ โอนอยออก
ใชคาสั ง npm init –y สรางข นมา (จะสรางหรอไมก ได)
ใช ไฟล .ejsท มอย แลว
EJS จะเร มหาไฟล *.ejs ตาง ๆ ท อย ในโฟลเดอร views
-
8/18/2019 37836
40/55
39
ไฟล about.ejs กมหลักการทางานเดยวกันกับ home.ejs ซ งพวกมันจะเปนหนาเวบท รางโครงข นมากอน พอ
ถงเวลาประมวลจรง ๆ กจะนาไฟล *.ejs มาหยอดใส ใหกลายเปนหนาเวบ HTML ท สมบรณภายหลัง
ตอมาผมจะสรางไฟล server.js ซ งโคดขางในจะเปนการใชงานมอดล Express รวมกับ EJS ดังตอไปน var express = require('express');
var engine = require('ejs-locals'); // ในตัวอยางน ผมจะใชมอดล ejs-locals ไม ได โหลดมอดล ejs โดยตรงนะครับ
var app = express();
app.engine('ejs', engine);
app.set('view engine', 'ejs');
app.get('/', function(req, res) { // ตดตอเขามาดวย http://ipadress:8080/
res.render('page/home');
});
app.get('/about', function(req, res) { // ตดตอเขามาดวย http://ipadress:8080/about
res.render('page/about');
});
app.listen(8080, function() { // ทาตัวเปนเซรฟเวอร และเปดพอรต 8080 console.log('Server running at http://localhost:8080/');
});
console.log("Using EJS example");
ไฟล server.js จะทาตัวเปนเซรฟเวอรและเปดพอรต 8080 เม อเวบบราวเซอรตดตอเขามาดวยพาธ ไดแก /
หรอ /about กจะนาไฟล home.js หรอ about.js ไปแสดงผลหนาเวบบราวเซอร …หรอพดอกนัยหน ง
server.js มันทาตัวเปนทั งเซรฟเวอร และเราเตอรเพ อเลอกไฟล (*.ejs) มาแสดงผล
แตกอนอ นอยาลมรันคาสั ง “node server.js” เพ อใหเวบแอพทางาน ดังน
c:\ejs>node server.js
Using EJS example
Server running at http://localhost:8080/
ซ งภาพรวมของการทางานในโปรเจคน จะเปนดังภาพในหนาถัดไป
บอก Express วาจะใช EJS
เปน Template egine
นาไฟล home.js ไปแสดงผล
นาไฟล about.js ไปแสดงผล
-
8/18/2019 37836
41/55
-
8/18/2019 37836
42/55
ใ
ท
โด
อั
น
W
เซ
เซ
อ
ห
บ
ชต
ย
เด
ค
eb
รฟ
รฟ
าก
ง
น
ดต
e
ยว
บ
So
เว
เวอ
ให
(หร
ะแ
อส
bS
ส
ย
ke
ร
ร
คณ
อ
สด
ส
c
น
สั
t
ละ
รอ
ลอ
ef
ตัว
รร
et
อม
สน
มข
เรา
เซ
งน
res
H
อย
ะห
จ
ลท
กัน
อเ
กใ
ฟเ
ถง
h
T
าง
าง
ม
สง
)
ร
เจ
อ
โป
วเ
C
าร
ไค
อง
า
บเ
าท
สง
รโต
ง)
lie
สร
เอ
า
น
ย
อน
า
คอ
แล
t
พ
ว
งเ
ต
กา
จะ
เ
น แ
าไ
ล
วถ
อม
เม อ
บ
(H
รต
ว ง
มอ
ล
คล
T
นา
ั งเป
นาย
ฝ งใ
อ
อ
T
ต
ย
นก
ส
อน
L
ขอ
ดกา
และ
นะ .
ปด
พ
C
ส
นโ
บท
งข
ต
เว
มล
รตด
สงข
อ .
อน
...ซั
an
การ
เค
lie
สา
ปร
อท
ม
ว
าท
จา
ตอค
อมล
..ฉัน
น นา
พอ
dsh
ดต
เ
ช ัน
t)
รแ
ต
เป
ไป
ทอ
หน
เซ
างท
ไปก
ัพพ
ยตด
ต
ke
ช
ช
แบ
แล
บ
อล
คา
กล
สง
าเว
ฟเ
งไว
ลับไ
อรต
ตอเ
eb
(HT
งทา
น
บเ
ะเซ
f
T
งไ
บห
พ
บส
วอ
Per
ดสอ
W
าม
oc
P
งกา
ย
รฟ
ll-
P
เ
ากั
งอั
งรเ
ม
sist
งทศ
bS
ได
et
pd
ส อ
บ
ไท
เวอ
du
อก
อเ
ไ
เด
คว
าแ
nt
ทาง
cke
ลว
รอเ
te)
าร
เร
ม
ร (
le
อ
2
ยว
ต
ดง
on
t
ะโว
ปลา
จะ
ย
วย
HT
x
าม
ต
แ
ป
ผล
nec
ย
วะ
ดตั
ไ
กา
TP
ตด
รป
ระ
ท
ถา
าเ
บน
ion
ลง
ใช
Se
ตอ
า
หว
ทา
ฝ ง
ร
หน
W
rve
ส อ
ลา
างไ
ง ไ
ดป
เว
าเว
eb
r)
สา
ง (
คล
มว
ดท
ร
บ
o
ได
มัน
อ
จ
อก
น
ke
2
ม ใ
ต
เป
อน
าเว
เ
t ซ
ทศ
ช โ
เว
ไ
จ
บจ
จะ
อ
แ
งเป
ทา
รโ
บ
ลเ
ค
ะต
ชม
อง
บบ
นโ
งบ
ตค
าว
อน
กัน
ง
อด
กา
W
รโ
s
ล
ซอ
ส
ไม
ระ
ล s
ต
eb
ตค
oc
HT
ร)
ไป
ด
พร
oc
ต
o
41
อล
et
TP
กับ
หา
ท
ket
ส อ
ke
.io
สา
t
-
8/18/2019 37836
43/55
42
แตถาใช WebSocket เราสามารถตดตอแลกเปล ยนขอมลกับเซรฟเวอร โดยไมตอง refresh หนาเวบ จรง ๆ
แลวมันจะคลายกับ AJAX แตจะมประสทธภาพดกวาเยอะ (คาวา AJAX นาจะเขาใจกันอย แลวเนอะ)
*** ถาใครใช HTML5 มากอน กนาจะเคยเหนการใช WebSocket มาแลว ซ งมหลักการเดยวกันแหละครับ
มอดล socket.io
การใชงาน WebScoket ใน Node.js สามารถใช socket.io แตเราตองตดตั งมันกอนดวยคาสั ง
npm install socket.io --save
หลังจากน ตอไป ผมจะอธบายการเขยนโคดทละข ันตอนแลวกัน ดังรายละเอยดตอไปน
ข ันท 1
เม อตดตั งมอดลเสรจเรยบรอย กจะใหเขยนโคดจาลองเซรฟเวอร และเปดพอรตข นมา (เปนอะไรกได) เพ อใช
ตดตอส อสารแบบ WebSocket ดังน
var io = require('socket.io').listen(8080); // จะจาลองเซรฟเวอร และเปดพอรต 8080 คางไว
ข ันท 2
ผมจะเพ มซอรสโคดในฝ งไคลเอนต (ในไฟล HTML) กับฝ งเซรฟเวอร ดังน
จากโคดท ยกมาใหด เวลาไคลเอนตตดตอเขามาเปน URL ธรรมดา ไดแก http://localhost:8080 …เม อน ัน
คอลแบคของเมธอด on() ในฝ งเซรฟเวอร กจะถกเรยกใหทางาน
// ฝ งเซรฟเวอร
io.sockets.on('connection', function (socket) { // เม อไคลเอนตตดตอเขามา
// โคดสวนน กจะทางาน
});
// ฝ งไคลเอนต
io.connect('htt ://localhost:8080'); WebSocket
เกดเหตการณ 'connection'
-
8/18/2019 37836
44/55
43
ข ันตอนท 3
ผมจะแสดงใหเหนวา เวลาไคลเอนตกับเซรฟเวอรสงขอมลไปมาหาส กัน จะมวธเขยนโคดดังตอไปน
ตองเขาใจอยางน นะครับ มอดล socket.io จะใชกลไกตดตอส อสารเปนแบบ message-oriented หรอกคอ
สงเปนขอความธรรมดาไดเลย โดยเบ องหลังมันจะแอบใช WebSocket อกทหน ง (สบายแฮะ)
จากโคดตัวอยางดังกลาว เวลาสงขอความและรับขอความ กสามารถทาไดดังน
การสงขอความไปใหอกฝ งหน ง จะใชเมธอด emit() สวนอกฝ งเม อรับขอความ กจะใชเมธอด on()
แตทั งน ขอความท สงหากัน คณจะตองระบช อเหตการณเปนอะไรก ไดดวยนะ หรออาจมองวาเปนการตดฉลาก
เขาไปก ได ดังตัวอยาง
ประโยค socket.emit('clientChat', 'Hi server'); ในฝ งไคลเอนต
จะสงขอความ 'Hi server' ดวยการระบช อเหตการณเปน
'clientChat'
ประโยค socket.on('clientChat', function(content){…} ); ในฝ งเซรฟเวอร
คอลแบคจะรับขอความผานทางตัวแปร content แตตองมช อเหตการณเปน
'clientChat'
// ฝ งเซรฟเวอร
io.sockets.on('connection', function (socket) {
socket.on('clientChat', function(content) {
console.log(content);
});
socket.emit('serverChat', "I'm OK");
});
พารามเตอร socket จะรับคาเปน
ออบเจกตท มเมธอด on กับ emit // ฝ งไคลเอนต
var socket =
io.connect('http://localhost:8080');
socket.emit('clientChat', 'Hi server');
socket.on('serverChat', function(content) {
// console.log(content)
});
ออบเจกต socketจะมเมธอด on กับ emit
คอนเซปทคลาย ๆEmitter pattern
-
8/18/2019 37836
45/55
44
ขณะเดยวกันเหตการณ "serverChat" กจะมหลักเกณฑทางานเดยวกัน แตมันจะทางานกลับดานกัน …กคอ
ฝ งเซรฟเวอรจะเปนคนสงขอความมาหาไคลเอนตเอง
ข ันตอนท 4
จากข ันตอนท 1 – 3 ผมจะรวบยอดเขยนเปนโคดในฝ งไคลเอนต (HTML) กับฝ งเซรฟเวอร ดังน
Socket.IO example
var div = document.querySelector('#div1') ;
var socket = io.connect('http://localhost:8080'); // ตดตอกับเซรฟเวอร ดวยโปรโตคอล WebSocket
socket.emit('clientChat', 'Hi server'); // สงขอความไปใหเซรฟเวอร
socket.on('serverChat', function(content) { // รับขอความมาจากเซรฟเวอร div.innerHTML = content; // นาขอความท ไดรับมาแทรกลงในแทก
});
// ไฟล server.js
var io = require('socket.io').listen(8080); // จะจาลองเซรฟเวอร และเปดพอรต 8080 คางไว (เปน WebSocket)
io.sockets.on('connection', function (socket) { // เม อหนาเวบตดตอเขามาครั งแรก คอลแบคกจะถกเรยกใหทางาน
socket.on('clientChat', function(content) { // รับขอความมาจากหนาเวบ
console.log(content);
});
socket.emit('serverChat', "I'm OK"); // สงขอความไปใหหนาเวบ
});
console.log('Server running at http://localhost:8080/');
ตองระบวาจะใช socket.io
ในไฟล HTML
-
8/18/2019 37836
46/55
ไ
C:
เม
C:S
ห
ห
ใ
เซ
แ
น
ล
\w
อพ
\wrv
ังจ
า
ภา
รฟ
ถา
ค
งส
eb
|- |-
|-
|--
มพ
ebr
าก
อค
พจ
เวอ
เรา
บ
อง
oc
n _ p
in
se
คา
ocun
น ัน
อน
ะเ
ร เ
กร
พร
ว
ke
d _ck
de
rve
ั ง
kenin
ห
โซ
น
อ
อก
าะ
ยก
_ag
.h
r.js
“n
>ng
บเ
ใน
าร
แล
U
ซร
มา
_ o.js
m
d
odt
ล
ฝ ง
เป
เป
L เ
เว
ห
_ ulon
l
s
ett
คล
ซร
ไฟ
ล ย
ปน
อร
(i
_ es
rv
er ://
ไฟ
เว
ล i
ข
h
ัน
d
...
er.j
er lo
ล
อร
d
ค
tt
ปด
x.
s”
.jsal
C:\
ดัง
x.
าม
:/
พ
t
กจ
os
we
น
t
ได
lo
รต
l
ะแ
t:8
bs
l
แก
al
80
บ
ด
08
c
จ
“
os
80
ser
ผล
/
et
าน
i s
t:8
เป
ve
ลัพ
in
น
er
08
โ
.js)
ธดั
de
ง
er
/
รโ
จะ
น
.h
กั
บ
ค
อย
t
คร
เว
ล
ใน
l เ
ง
I’
บ
W
ปร
อ
งจ
าว
bS
เจ
เป
ะห
K”
เซ
oc
ท ม
มัน
า
ซ ง
ร
ket
โค
ข น
ถง
กัน
ท
…
งส
มา
…
แล
ก
ตเ
รา
ซ ง
ไค
ะกั
รดั
รา
ดัง
ค
ลเ
บเ
มว
น
จะ
น
ล
ธแ
เห
ส
ลก
กดั
ห
งต
ไฟ
ห
าจ
วต
ล จ
าถ
อเ
ต
ะท
ดไ
บ
ไ
าไ
45
กับ
ยัง
ได
-
8/18/2019 37836
47/55
46
ตัวอยางโคดตอไปน จะนาไฟล server.js มาแก ไขเสยใหม ดวยการผสมผสานวธ ใชงานมอดล Express รวมกับ
socket.io และเพ อไม ใหเปนการเสยเวลา ก ใหคณด โคดดกวาจะไดเขาใจไปเลย ดังตัวอยาง
// ไฟล server.js
var fs = require('fs'); // มอดล fs
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(8080); // จะจาลองเซรฟเวอร ดวยการเปดพอรต 8080
app.get('/', function(req, res) {
fs.readFile(__dirname + '/index.html', // อานไฟล index.html function(err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);} // ส นสดคอลแบค
); // ส นสด readFile()
});
io.sockets.on('connection', function (socket) {
socket.on('clientChat', function(content) {
console.log(content);
});socket.emit('serverChat', "I'm OK");
});
console.log('Server running at http://localhost:8080/');
ในตัวอยางน คอนเซปทกคอ จะเปดพอรต 8080 คางเอาไว และแทนท คณจะเปดไฟล index.html (ไฟลเดม)
กเปล ยนไปเปดเวบบราวเซอร แลวกรอก URL เปน http://localhost:8080/ ไมเพยงเทาน ันพอรตน ยัง
รองรับโปรโตคอล WebSocket ไดอกดวย
เคลดกระบวนทาผสานรวม
Express เขากับ socket.io
ใหกลายเปนหน ง
โคดเหมอนตัวอยางท แลวเปะ
อานเน อหาในไฟล index.html
แลวสง data (Buffer) กลับออกไปหาไคลเอนต
-
8/18/2019 37836
48/55
แ
เม
เว
ดั
ห
ส
ht
ท
อเ
บ
ภา
า
หร
tp:
าโ
บ
ห
พข
เห
บร
//s
ดใ
รา
ังจ
าง
ต
าย
oc
น
เซ
าก
าง
ะเ
et
er
อร
ั น
ย
.io
er
งร
น
ข
.js
เค
าเว
ง
ัน
สต
บจ
oc
กร
ับ
มา
ะต
ket
อก
อ
ยังเ
ต
.io
U
อ
ซร
มา
มา
L
พ
เว
หา
กก
ด
คว
อร
เซ
วา
ตร
ร เ
ใน
ฟเ
ถ
ง
ร
se
อ
าส
ะว
rve
ให
ใจ
า…
r.js
อ
กอ
จ
ค
านเ
ตอ
งด
พ ม
งอ
วย
เต
น
W
ได
ฟล
b
ท
in
oc
de
ke
.h m
ดย
l แ
ผล
ว
กา
งก
ทา
ลับ
งา
ป
ก
งห
ะเ
47
นา
น
-
8/18/2019 37836
49/55
48
ตดตอฐานขอม ล MySQL
….เอาละแตกอนอ นเราตองตดตั งมอดล mysql ข นมากอน ดวยคาสั ง
npm install mysql --save
*** สาหรับวธตดตั ง MySQL ก ให ไปดวธตดตั งไดท www.patanasongsivilai.com/itebook_form.html
โคดตอไปน จะใชตดตอฐานขอมลเปน MySQL
var mysql = require('mysql'); // โหลดมอดล mysql
var connection = mysql.createConnection({
host : 'localhost',
u