avansat
Tehnologii Web
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
programare Web
⍟
JavaScript la nivel de server – Node.js
(aspecte esențiale)
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
„Cine a văzut vreodată o bijuterie frumos cizelată
de bijutier cu ajutorul ciocanului?”
Jan Amos Comenius
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
JavaScript
un limbaj de programare pentru Web
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Inventat de Brendan Eich (1995)
detalii în cadrul prelegerilor
Limbajul de programare JavaScript.
Aspecte esențiale
profs.info.uaic.ro/~busaco/teach/courses/cliw/web-film.html#week5
Limbajul de programare JavaScript.
Aspecte moderne: ES6, ES7, ES8
profs.info.uaic.ro/~busaco/teach/courses/cliw/web-film.html#week7
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
“Node.js® is a JavaScript runtime built on Chrome’s
V8 JavaScript engine. Node.js uses an event-driven,
non-blocking I/O model that makes it lightweight and
efficient. Node.js’ package ecosystem – npm – is the largest
ecosystem of open source libraries in the world.”
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
“Node.js® is a JavaScript runtime built on Chrome’s
V8 JavaScript engine. Node.js uses an event-driven,
non-blocking I/O model that makes it lightweight and
efficient. Node.js’ package ecosystem – npm – is the largest
ecosystem of open source libraries in the world.”
“Node.js is designed to build
scalable network applications.”
Ryan Dahl concepe Node.js (2009) – nodejs.org
rulează pe mașini respectând POSIX + Windows (2011)
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
adoptat de industrie (din 2012)
e.g., Cloud9 IDE, eBay, Google, LinkedIn, Netflix, Storify, Twitter
hackernoon.com/@nodejs
Node.js Foundation (2015)
IBM, Intel, Joyent, Microsoft, RedHat, SAP, The Linux Foundation,…
io.js – o variantă Node.js concepută în ES6
al cărei cod-sursă a fost încorporat în Node.js 4 (2015)
Node.js 8.10 LTS – Long Term Support (martie 2018)
versiune stabilă actuală pentru uz în producție
Node.js 9.8.0 – varianta curentă (martie 2018)
https://github.com/nodejs/node
node.js
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Oferă un mediu de execuție în linia de comandă,
pe baza unor biblioteci C++ și a procesorului V8
node program.js
node.js
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Permite dezvoltarea de aplicații Web
la nivel de server în limbajul JavaScript
recurge la V8 – procesor (interpretor) JavaScript
creat de Google, implementat în C++ și disponibil liber
developers.google.com/v8/
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Oferă suport pentru cele mai importante
protocoale Web și Internet
HTTP (HyperText Transfer Protocol)
DNS (Domain Name System)
TLS (Transport Layer Security)
functionalități de nivel scăzut (socket-uri TCP)
node.js
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Intern, se recurge la
diverse biblioteci open source C sau C++
libuv (asynchronous I/O) – docs.libuv.org
c-ares (asynchronous DNS requests) – c-ares.haxx.se
OpenSSL (crypto + SSL/TLS) – www.openssl.org
zlib (compression) – zlib.net
V8 (JavaScript engine) – v8docs.nodesource.com
node.js:
Uzual, o aplicație Web caracterizare
realizează un număr mare de
operații – în acest caz, asincrone – de intrare/ieșire
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
G. Yeh (2014): www.slideshare.net/garyyeh165/basic-understanding-and-implement-of-nodejs
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Operațiile de intrare/ieșire sunt asincrone
fiecare cerere (operație) adresată aplicației
– e.g., acces la disc, la rețea, la alt proces – poate avea
atașată o funcție de tratare a unui eveniment specific
evented I/O
cod JS executat de cod JS rulat pe partea
client (browser Web) de server (node.js)
procesare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
așteaptă și tratează
evenimente de bazată pe așteaptă și tratează
interacțiune evenimente cereri (evenimente)
(onclick, onmouseover, evented/ provenite de la client(i)
onkeypressed,…) event-based
programul trebuie să fie programul trebuie să fie
responsiv atunci când responsiv atunci când
așteaptă încărcarea asincronism așteaptă încărcarea
datelor de pe rețea (e.g., operatii datelor locale/externe
(e.g., JSON, XML, imagini, neblocante) (preluate din baze de
video) via Ajax/Comet date, fișiere,
ori socket-uri Web servicii Web, API-uri,…)
adaptare după Ben Sheldon (2012)
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
O aplicație node.js rulează într-un singur proces
event loop ≡ “an entity that handles & processes external
events and converts them into callback invocations”
blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
O aplicație node.js rulează într-un singur proces
event loop ≡ “an entity that handles & processes external
events and converts them into callback invocations”
codul JavaScript nu este executat paralel,
dar tratează în mod asincron diverse evenimente I/O
blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/
Aplicația node.js „reacționează” la evenimente
context mainode.js: caracterizare
larg: reactive programming – reactivex.io
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
G. Yeh (2014): www.slideshare.net/garyyeh165/basic-understanding-and-implement-of-nodejs
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
O aplicație node.js rulează într-un singur proces
deosebire esențială față de serverele de aplicații Web
tradiționale ce recurg la servere multi-process/threaded
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
O aplicație node.js rulează într-un singur proces
server tipic server node.js
adaptare după Ben Sheldon (2012)
operații de intrare/ieșire sincrone
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
versus
operații de intrare/ieșire asincrone
bijoor.me/2013/06/09/java-ee-threads-vs-node-js-which-is-better-for-concurrent-data-processing-operations/
HTTP: server Web
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
strongloop.github.io/strongloop.com/strongblog/node-js-is-faster-than-java/
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Mediul node.js e disponibil gratuit – open source –
pentru platformele UNIX/Linux, Windows, MacOS
nodejs.org/en/download/
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
funcționalități suplimentare
oferite de module administrate cu npm – npmjs.org
node.js: caracterizare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Utilitarul npm poate gestiona dependențe imbricate
detalii la docs.npmjs.com
node.js: exemplu
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Un prim program care emite mesaje de salut
// salutari.js: un program (de sine-stătător) care emite un salut
console.log ('Salutari banale din Node.js');
invocarea unei
metode oferită de
un obiect predefinit
node.js: exemplu
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Un prim program care emite mesaje de salut
// salutari.js: un program (de sine-stătător) care emite un salut
console.log ('Salutari banale din Node.js');
> node salutari.js
Salutari banale din Node.js
/* Un program JavaScript ilustrând comportamentul asincron
al operațiilor I/O implementate de Node.js */
var fs = require ('fs'); // acces la sistemul de fișiere
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
fs.readFile ('salutari.txt', 'utf-8', function (eroare, date) {
if (eroare)
throw eroare; // excepție de citire
console.log (date);
})
console.log ('Gata!');
execuția (cod interpretat) pornește
de la prima linie a programului JavaScript
/* Un program JavaScript ilustrând comportamentul asincron
al operațiilor I/O implementate de Node.js */
var fs = require ('fs'); // acces la sistemul de fișiere
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
fs.readFile ('salutari.txt', 'utf-8', function (eroare, date) {
if (eroare)
throw eroare; // excepție de citire
console.log (date);
})
console.log ('Gata!');
începe execuția unei operații asincrone
(aici, citirea conținutului unui fișier text)
care returnează imediat
/* Un program JavaScript ilustrând comportamentul asincron
al operațiilor I/O implementate de Node.js */
var fs = require ('fs'); // acces la sistemul de fișiere
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
fs.readFile ('salutari.txt', 'utf-8', function (eroare, date) {
if (eroare)
throw eroare; // excepție de citire
console.log (date);
})
console.log ('Gata!');
execuția continuă cu ultima linie de program
> node asincronism.js
Gata!
/* Un program JavaScript ilustrând comportamentul asincron
al operațiilor I/O implementate de Node.js */
var fs = require ('fs'); // acces la sistemul de fișiere
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
fs.readFile ('salutari.txt', 'utf-8', function (eroare, date) {
if (eroare)
throw eroare; // excepție de citire
console.log (date);
})
console.log ('Gata!');
…după care sunt afișate datele preluate din fișier
> node asincronism.js
Gata!
Un prim salut...
Acesta este al doilea salut.
// Un program JavaScript care salută toți posibilii săi clienți Web
var http = require ('http'); // folosim 'http', un modul Node predefinit
http.createServer ( // creăm un server Web
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
// funcție anonimă ce tratează o cerere și trimite un răspuns
function (cerere, raspuns) {
// afișăm la consola serverului mesaje de diagnostic
console.log ('Am primit o cerere...');
// stabilim valori pentru diverse câmpuri din antetul mesajului HTTP
raspuns.writeHead (200, { 'Content-Type': 'text/html' });
// emitem răspunsul propriu-zis conform tipului MIME (aici, cod HTML)
raspuns.end ('<html><body><h1>Salutari…</h1></body></html>');
}
// serverul ascultă cereri la portul 8080 al mașinii locale
).listen (8080, "127.0.0.1");
console.log ('Serverul creat asteapta cereri la http://127.0.0.1:8080/');
programul JavaScript creat funcționează ca un server Web
pentru fiecare cerere emisă de un posibil client (browser,
aplicație desktop etc.) conform modelului client/server
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
pe partea de server – așteptare de cereri
> node salutari-web.js
Serverul creat asteapta cereri la http://127.0.0.1:8080/
Am primit o cerere...
Am primit o cerere...
programul JavaScript creat funcționează ca un server Web
pentru fiecare cerere emisă de un posibil client (browser,
aplicație desktop etc.) conform modelului client/server
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
pe partea de server – așteptare de cereri
> node salutari-web.js
Serverul creat asteapta cereri la http://127.0.0.1:8080/
Am primit o cerere...
Am primit o cerere...
la client – recepționarea răspunsului conform cererii GET
emise de un program desktop și de un navigator Web
> node client-salutari.js
Am primit raspuns de la server -- cod HTTP: 200
Continut receptionat: <html><body>
<h1>Salutari din Node.js</h1></body></html>
// Un program JS care implementează un client pentru serviciul de salut
var http = require ('http');
http.get ('http://127.0.0.1:8080/', // emite o cerere HTTP
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
function (raspuns) {
console.log ('Am primit raspuns de la server -- cod HTTP: '
+ raspuns.statusCode); // statusCode: 200, 404,…
})
// tratăm diverse evenimente via funcții (eventual, anonime) de tip callback
.on ('error', // eroare
function (e) { console.log ('Eroare: ' + e.message); })
.on ('response', // receptare răspuns de la server
function (raspuns) { // există date de procesat
raspuns.on ('data', function (date) {
console.log ('Continut receptionat: ' + date);
});
}
);
node.js: module
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Funcția require () specifică utilizarea unui modul Node.js
module predefinite (built-in):
privitoare la tehnologii Web – http, https, url, querystring
referitoare la fișiere – fs, path
vizând rețeaua – net, dns, dgram, tls,…
resurse privind sistemul de operare – os, child_process
alte aspecte de interes – buffer, console, util, crypto
suport multi-core – cluster
node.js: module
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
documentația online aferentă
nodejs.org/en/docs/
devdocs.io/node/
atenție:
o parte dintre funcționalități
node.js: module
sunt experimentale
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
nodejs.org/api/documentation.html
node.js: module – http
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dezvoltarea de aplicații Web via modulul http
funcționalități HTTP de bază
crearea unui server Web: createServer()
realizarea de cereri HTTP: request() get()
node.js: module – http
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dezvoltarea de aplicații Web via modulul http
servire de cereri HTTP – clasa http.Server
metode uzuale:
listen() setTimeout() close()
evenimente ce pot fi tratate:
request connect close clientError etc.
node.js: module – http
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dezvoltarea de aplicații Web via modulul http
răspuns emis de server – clasa http.ServerResponse
metode uzuale:
writeHead() getHeader() removeHeader() write() end() etc.
evenimente: close finish
proprietăți folositoare: statusCode headersSent
node.js: module – http
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dezvoltarea de aplicații Web via modulul http
cerere emisă de client – clasa http.ClientRequest
metode uzuale:
write() abort() end() setTimeout() setSocketKeepAlive()
evenimente ce pot fi tratate:
response connect continue socket etc.
node.js: module – http
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dezvoltarea de aplicații Web via modulul http
mesaj vehiculat – clasa http.IncomingMessage
metode: setEncoding() setTimeout() pause() resume()
evenimente ce pot fi tratate: data end close
proprietăți de interes:
httpVersion headers method url statusCode socket
node.js: module – url
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Procesarea adreselor Web via modulul url
metode oferite:
parse() format() resolve()
nodejs.org/api/url.html
var url = require ('url');
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
var adresaWeb = url.parse (
'http://undeva.info:8080/oferta/jucarii/produs/?nume=Tux&marime=17#descriere',
true // generează un obiect 'query' ce include câmpurile din querystring
);
console.log (adresaWeb);
if (adresaWeb['query'].marime > 13) {
console.log ('Jucaria e in regula.');
} else {
console.log ('Jucaria e stricata.');
}
> node url.js
{ protocol: 'http:',
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
slashes: true,
auth: null,
host: 'undeva.info:8080',
port: '8080',
hostname: 'undeva.info',
hash: '#descriere',
search: '?nume=Tux&marime=17',
query: { nume: 'Tux', marime: '17' },
pathname: '/oferta/jucarii/produs/',
path: '/oferta/jucarii/produs/?nume=Tux&marime=17',
href: 'http://undeva.info:8080/oferta/jucarii/produs/?nume=…'
}
Jucaria e in regula.
node.js: module – net
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Crearea de aplicații Internet – modulul net
partea de server:
createServer()
+
clasa net.Server
metode: listen() close() address() getConnections()
evenimente: listening connection close error
node.js: module – net
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Crearea de aplicații Internet – modulul net
partea de client:
connect()
createConnection()
node.js: module – net
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Crearea de aplicații Internet – modulul net
acces la socket-uri – clasa net.Socket
metode: connect() write() setEncoding() destroy() end() etc.
evenimente: connect data end timeout drain error close
proprietăți utile: localAddress localPort
remoteAddress remotePort bytesRead bytesWritten bufferSize
node.js: module – fs
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Acces la sistemul de fișiere via modulul fs
metode folosite uzual – comportament asincron:
open() read() write() close()
truncate() stat() chmod() rename() exists()
isFile() isDirectory() isSocket()
mkdir() rmdir() readdir()
node.js: module – fs
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Acces la sistemul de fișiere via modulul fs
studiu de caz (Victor Porof, 2013 – absolvent FII):
generare de liste de melodii via iTunes și Last.fm
(ilustrează și maniera de creare a modulelor proprii)
github.com/victorporof/plgen
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
abstractizează accesul la date stocate parțial
(partially buffered data)
se emit evenimente ce pot fi tratate de codul aplicației
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
pot fi citite – stream.Readable
pot fi scrise – stream.Writable
duplex (citite și scrise) – stream.Duplex
realizând o transformare a datelor – stream.Transform
detalii la nodejs.org/api/stream.html
medium.freecodecamp.org/node-js-streams-everything-you-need-to-know-c9141306be93
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
fluxuri ce pot fi citite (readable streams)
e.g., create de fs.createReadStream() http.ServerRequest
http.ClientResponse net.Socket child.stdout process.stdin
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
fluxuri ce pot fi citite (readable streams)
e.g., create de fs.createReadStream() http.ServerRequest
http.ClientResponse net.Socket child.stdout process.stdin
emit evenimentele readable data end error
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
fluxuri ce pot fi citite (readable streams)
e.g., create de fs.createReadStream() http.ServerRequest
http.ClientResponse net.Socket child.stdout process.stdin
au asociate metodele pause() resume() destroy()
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
fluxuri ce pot fi scrise (writeable streams)
e.g., create de fs.createWriteStream() http.ServerResponse
http.ClientRequest net.Socket child.stdin process.stdout
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
fluxuri ce pot fi scrise (writeable streams)
e.g., create de fs.createWriteStream() http.ServerResponse
http.ClientRequest net.Socket child.stdin process.stdout
emit evenimentele drain error
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
fluxuri ce pot fi scrise (writeable streams)
e.g., create de fs.createWriteStream() http.ServerResponse
http.ClientRequest net.Socket child.stdin process.stdout
oferă metodele write() end() destroy()
// Program ce preia ceea ce tastează utilizatorul la intrarea standard
// și scrie într-un fișier – conform M. Takada (2012)
var fs = require ('fs');
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
var fisier = fs.createWriteStream ('./spion.txt');
// la apariția datelor, le scriem în fișier
process.stdin.on ('data', function (date) { fisier.write (date); } );
// tratăm evenimentul de terminare a fluxului
process.stdin.on ('end', function() { fisier.end (); } );
// "reactivăm" intrarea standard; implicit, e în starea 'paused'
process.stdin.resume ();
obiectul process e global – detalii la nodejs.org/api/process.html
node.js: fluxuri de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Accesul la date poate fi realizat
prin intermediul fluxurilor (streams)
exemple de fluxuri de tip duplex:
socket-uri TCP create cu net.Socket()
privind arhivele create cu zlib – nodejs.org/api/zlib.html
date criptate via crypto – nodejs.org/api/crypto.html
node.js: rulare temporizată
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Se poate planifica execuția codului JavaScript
recurgerea la funcțiile globale
setTimeout ()
clearTimeout ()
setInterval ()
clearInterval ()
// creăm un server Web care trimite fiecărui client secvența valorilor unui contor
var server = http.createServer ().listen (8080, '127.0.0.1');
// stabilim un comportament la apariția evenimentului 'request' (cerere de la un client)
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
server.on ('request', function (cerere, raspuns) {
console.log ('Cerere de la clientul ' + cerere.headers['user-agent']);
raspuns.writeHead (200, { 'Content-Type': 'text/html' });
var contor = 0;
var interval = setInterval ( // generăm valori ale contorului conform intervalului de timp
function () {
raspuns.write ('<p>Contorul are valoarea ' + contor + '</p>');
console.log ('Contorul are valoarea ' + contor);
contor++;
if (contor >= 7) {
clearInterval (interval); // ștergem intervalul
raspuns.end (); // închidem fluxul de răspuns
console.log ('Am trimis raspuns clientului ' + cerere.headers['user-agent']);
}
}, 1000); // cod rulat la interval de 1000 milisecunde
});
Cerere de la clientul … Mozilla/5.0 (Windows NT 10.0 …) … Firefox/59.0
Contorul are valoarea 0
Contorul are valoarea 1
Contorul are valoarea 2
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Contorul are valoarea 3
Cerere de la clientul … Edge/14.14393
Contorul are valoarea 4
Contorul are valoarea 0 codul este rulat
Contorul are valoarea 5
Contorul are valoarea 1
asincron
Contorul are valoarea 6
Am trimis raspuns clientului … Mozilla/5.0 (Windows NT 10.0 …) … Firefox/59.0
Contorul are valoarea 2
Contorul are valoarea 3
Contorul are valoarea 4
Contorul are valoarea 5
Contorul are valoarea 6
Am trimis raspuns clientului … Edge/14.14393
Cerere de la clientul … Mozilla/5.0 (Windows NT 10.0 …) … Firefox/59.0
Contorul are valoarea 0
Contorul are valoarea 1
Contorul are valoarea 2
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Contorul are valoarea 3
Cerere de la clientul … Edge/14.14393
Contorul are valoarea 4
Contorul are valoarea 0
Contorul are valoarea 5
Contorul are valoarea 1
Contorul are valoarea 6
Am trimis raspuns clientului … Mozilla/5.0 (Windows NT 10.0 …) … Firefox/59.0
Contorul are valoarea 2
Contorul are valoarea 3
Contorul are valoarea 4
Contorul are valoarea 5
Contorul are valoarea 6
Am trimis raspuns clientului … Edge/14.14393
browser-ul Web va aștepta ca întreaga secvență de valori
de ce? să fie trimisă de către server
node.js: evenimente
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Emiterea (lansarea) și tratarea (prinderea)
evenimentelor specificate de programator
se realizează via event.EventEmitter
clasă utilizată intern de multe biblioteci de bază
nodejs.org/api/events.html
node.js: module externe
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Funcția require () specifică utilizarea unui modul Node.js
module disponibile on-line (instalate via utilitarul npm)
de studiat Understanding NPM
unpm.nodesource.com
node.js: module externe
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Funcția require () specifică utilizarea unui modul Node.js
instalare globală a unui modul: npm install modul –g
listarea modulelor ce sunt instalate local: npm list
căutarea unui modul: npm search modul
eliminarea unui modul: npm uninstall modul
actualizarea unui modul: npm update modul
node.js: module – acces la baze de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Operații cu baze de date relaționale SQLite
recurgerea la modulul sql.js implementat în JavaScript
via compilatorul emscripten
nu depinde de alte module
detalii la www.npmjs.com/package/sql.js
exemple demonstrative (interpretor SQL ca aplicație Web):
kripken.github.io/sql.js/GUI/
node.js: module – studiu de caz
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dorim să realizăm un mini-robot care procesează
conținutul diverselor resurse disponibile pe Web
rol de client pentru un server Web
prelucrează codul HTMLWeb scraping
metode consacrate:
DOM (Document Object Model)
SAX (Simple API for XML)
detalii în
viitoarele cursuri
var http = require ('http');
var qs = require ('querystring');
var dom = require ('xmldom').DOMParser;
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
// de exemplu, dorim să obținem reprezentarea corespunzătoare resursei
// de la http://www.google.ro/search?q=web+programming+node.js
var cerere = http.get ("http://www.google.ro/search?" +
qs.stringify ({ q: 'web programming node.js' }), function (raspuns) {
var rezultat = ''; // răspunsul poate sosi în fragmente de date
raspuns.on ('data', function (date) { // tratăm evenimentul privitor la
rezultat += date; // apariția datelor
});
// tratăm evenimentul de finalizare a transferului de date de la server
raspuns.on ('end', function() {
console.log (procesareHTML (rezultat));
});
});
conectare la un server Web
// realizează procesarea dorită (Web scrapping)
function procesareHTML (document) {
var adrese = [ ];
// instanțiem un procesor DOM
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
try {
var doc = new dom().parseFromString (document, "text/html");
// preluăm toate elementele <a>
var noduri = doc.getElementsByTagName ('a');
// obținem valoarea atributului 'href' (URL-ul)
for (var i = 0; i < noduri.length; i++) {
// plasăm în tablou doar dacă e relativ și e prefixat de "/url?q="
var uri = noduri[i].getAttribute ('href');
if (!uri.match (/^http(s?)/gi) && uri.match (/^\/url\?q=/g))
adrese.push (uri);
}
} catch (e) { console.log (e.message); }
return (adrese);
} procesare document cu DOMParser
developer.mozilla.org/DOMParser
node.js: module
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
lista modulelor Node.js
nodejsmodules.org
node.js: framework-uri web
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Uzual, încurajează dezvoltarea de aplicații Web
în care interacțiunea cu utilizatorul
se realizează într-o singură pagină
(SPA – Single-Page Applications)
real-time single-page Web apps
node.js: framework-uri web – exemple
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Alte facilități notabile:
MVC (Model-View-Controller) și variantele
transfer de date în timp-real – e.g., cu Socket.IO
servicii Web – paradigma REST
suport pentru baze de date NoSQL
machete de redare a conținutului (templates)
node.js: framework-uri web – exemple
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
nodeframework.com
node.js: framework-uri web – connect
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Framework extensibil de tip middleware
dedicat deservirii de cereri HTTP
github.com/senchalabs/connect
node.js: framework-uri web – connect
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
O cerere HTTP dată poate fi procesată – via use() –
de una sau mai multe extensii (plugin-uri) specifice
această înlănțuire se denumește stivă (stack)
utilizarea unei extensii poate depinde de URL cererii
dirijare (routing) – e.g., util în contextul REST
node.js: framework-uri web – connect
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Extensii utile:
body-parser – procesări diverse
(e.g., text, date dintr-un formular Web, date JSON,…)
compression – procesarea mesajelor compresate (gzip)
cookie-parser – prelucrarea de cookie-uri
cookie-session express-session – sesiuni Web
errorhandler – tratarea erorilor
morgan – suport pentru jurnalizare (logging)
csurf – protecție CSRF (Cross-Site Request Forgery)
serve-static – deservirea conținutului static (i.e. fișiere)
vhost – suport pentru găzduire virtuală
node.js: framework-uri web – express
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Framework minimalist
ce încurajează dezvoltarea de aplicații Web
tradiționale – reprezentări multiple via hipermedia
bazate pe un unic punct de acces: SPA (Single Page App)
hibride (Web + aplicații native)
expressjs.com
/
│ app.js
│ package.json diverse configurări ale aplicației
├───bin
├───data specificarea modelelor de date
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
├───node_modules
│ ├───body-parser
│ ├───cookie-parser module Node.js adiționale
│ ├───debug
│ ├───express
│ │ ├───lib
│ ├───jade
│ ├───morgan
├───public conținut static destinat clientului
│ ├───images
│ ├───javascripts (e.g., foi de stiluri CSS, biblioteci JS
│ └───stylesheets procesate de browser, imagini,…)
│ style.css
├───routes rute vizând deservirea cererilor pe
│ index.js
│ users.js baza URL-urilor solicitate de client
└───views
error.jade specificarea interfeței (view-ul)
index.jade via machete de vizualizare descrise
layout.jade
cu JADE: http://jade-lang.com/
eșafodajul unei aplicații Web bazate pe Express
node.js: framework-uri web
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
MEAN (MongoDB, Express, Angular, Node.js) – mean.io
full stack Web development
exemplificări:
devcenter.heroku.com/articles/mean-apps-restful-api
scotch.io/tutorials/creating-a-single-page-todo-app-with-node-and-angular
node.js: suport es6
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Node.js 4+ oferă suport pentru ECMAScript 2015 (ES6)
facilități deja incluse:
declararea variabilelor cu let și const
specificarea claselor
colecții de date (Map, WeakMap, Set, WeakSet)
generatori
execuție asincronă (Promises)
....
nodejs.org/en/docs/es6/
node.js: suport es6
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
situația curentă a facilităților ECMAScript implementate
de instrumente de conversie, navigatoare Web și Node.js
http://kangax.github.io/compat-table/es2016plus/
node.js: suport es6
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Node.js – starea actuală de implementare
a facilităților oferite de ECMAScript: node.green
node.js: utilizări pragmatice
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Deservirea unui volum mare de conexiuni
concurente cu necesar minim de resurse
(procesor, memorie) într-un singur proces
node.js: utilizări pragmatice
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Procesarea în timp-real
a datelor JSON oferite de API-uri (multiple)
inclusiv, crearea de aplicații
oferind fluxuri de date (streaming data)
node.js: utilizări pragmatice
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Procesarea în timp-real
a datelor JSON oferite de API-uri (multiple)
caz practic: redirectarea unui flux de mesaje Twitter
spre dispozitive via PubNub (Marinacci, 2016)
www.pubnub.com/blog/2016-04-14-connect-twitter-and-pubnub-in-one-line-of-code-with-nodejs-streams/
node.js: utilizări pragmatice
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Dezvoltarea rapidă de servicii Web
sau API-uri conform paradigmei REST
(REpresentational State Transfer)
câteva framework-uri pentru dezvoltarea de API-uri:
actionHero.js, facet, Frisby, restify, restmvc, percolator,…
node.js: utilizări pragmatice
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Crearea de aplicații native (desktop)
folosind tehnologii Web moderne precum HTML5
NW.js (fost node-webkit)
utilizarea modulelor Node.js direct la nivel de DOM
nwjs.io
node.js: instrumente de dezvoltare
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Mediu de dezvoltare tradițional (desktop)
exemplificări:
Node.js Tools for Visual Studio
www.visualstudio.com/vs/node-js/
Node on Train (scaffolding tool for full stack developer)
nodeontrain.xyz
node.js: utilizări pragmatice
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
dezvoltare „în nori” de aplicații Web – e.g., Cloud9 și Koding
S. Buraga, Cu codul în „nori” (2015) – www.slideshare.net/busaco/cu-codul-n-nori
node.js: resurse utile
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Node.js Tutorials for Beginners
blog.risingstack.com/tag/node-js-tutorials-for-beginners/
Node.js Notes for Professionals
books.goalkicker.com/NodeJSBook/
Node.js Style Guide
github.com/felixge/node-style-guide
Node Weekly
nodeweekly.com
node.js: resurse utile
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
Awesome Node.js
github.com/sindresorhus/awesome-nodejs
Best Practices for Node.js Development
devcenter.heroku.com/articles/node-best-practices
Node.js Production Practices
www.joyent.com/node-js/production
Built in Node
builtinnode.com
rezumat
Dr. Sabin Buragaprofs.info.uaic.ro/~busaco/
⍟
dezvoltarea de aplicații Web la nivel de server
de la JavaScript la Node.js
caracteristici, module, exemple