Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sde:laboratoare:12_ro_js [2020/05/05 21:49]
ioana_maria.culic
— (current)
Line 1: Line 1:
-====== Laborator 12 - Operații asincrone ====== 
  
-===== Prezentare teoretică ===== 
-Operațiile asincrone sunt operații neblocante, adică ele întorc un rezultat imediat, procesarea realizându-se în background. 
- 
-În acest laborator vom utiliza funcții asincrone pentru a realiza operații ce necesită procesare (ex. citirea din fișier). 
- 
-<note info> 
-În acest laborator veți folosi mediul de programare Node.js. 
-</​note>​ 
- 
-===== Node.js ===== 
-Node.js este un mediu de programare JavaScript care este caracterizat prin suportul pentru operații asincrone. 
- 
-Pentru a instala node.js, accesați următorul link: https://​nodejs.org/​en/​. 
- 
-=====Funcții asincrone===== 
- 
-În node.js, o funcție asincronă are următorul format: 
-<code javascript>​ 
-function foo ([p1, p2, ..., ]callbackFunction){ 
-    <​code>​ 
-    callbackFunction ([param1, param2,​...]);​ 
-} 
-</​code>​ 
- 
-Practic, funcția asincronă primește ca parametru o altă funcție, pe care o apelează odată ce termină procesarea. 
- 
-Apelul unei funcții asincrone arată astfel: 
-<code javascript>​ 
-foo ([p1, p2, ...,] function ([param1, param2,​...]){ 
-    <​code>​ 
-}); 
-</​code>​ 
- 
-Același cod poate fi scris și astfel: 
-<code javascript>​ 
-foo ([p1, p2, ...,] ([param1, param2,​...])=>​{ 
-    <​code>​ 
-}); 
-</​code>​ 
- 
-Apelul unei funcții asincrone va întoarce imediat, iar programul va continua să execute alte apeluri de funcție. Între timp, sistemul de operare va procesa cererile funcțiilor anterioare. Când procesarea unei funcții este gata, funcția de callback va fi apelată și se va executa rutina asociată acesteia. 
- 
-===fs=== 
-[[https://​nodejs.org/​api/​fs.html|fs]] este modulul Node.js care suportă operații cu fișiere. Cele mai importate funcții expuse de acesta sunt: 
-  * [[https://​nodejs.org/​api/​fs.html#​fs_fs_readfile_path_options_callback|fs.readFile]];​ 
-  * [[https://​nodejs.org/​api/​fs.html#​fs_fs_writefile_file_data_options_callback|fs.writeFile]];​ 
-  * [[https://​nodejs.org/​api/​fs.html#​fs_fs_readdir_path_options_callback|fs.readDir]]. 
- 
-Programul de mai jos folosește funcții asincrone pentru a scrie un fișier, după care citește conținutul acestuia: 
-<code javascript>​ 
-const fs = require ('​fs'​);​ 
-fs.writeFile ('​myFile',​ 'my message',​ function (err){ 
-  console.log ('​Processing done'​);​ 
-  if (err){ 
-    console.log ('​There was an error writing the file'​);​ 
-  } 
-  else{ 
-    fs.readFile ('​myFile',​ function (err, data){ 
-      if (err){ 
-        console.log ('​There was an error reading the file'​);​ 
-      } 
-      else{ 
-        console.log (data); 
-      } 
-    }); 
-  } 
-}); 
-</​code>​ 
- 
-===child_process=== 
-[[https://​nodejs.org/​api/​child_process.html|child_process]] e modulul care permite crearea de procese copil și interacțiunea cu acestea. 
- 
-Modulul expune următoarele funcții importante: 
-  * [[https://​nodejs.org/​api/​child_process.html#​child_process_child_process_execfile_file_args_options_callback|execFile]] 
-  * [[https://​nodejs.org/​api/​child_process.html#​child_process_child_process_spawn_command_args_options|spawn]] 
- 
-Diferența dintre cele două funcții este că ''​execFile''​ primește un callback ca parametru care va fi apelat odată de procesul copil își finalizează execuția, în timp de ''​spawn''​ întoarce o structură care prerezintă procesul copil, care înregistrează evenimente. 
- 
-Următorul program lansează câte un proces folosind ambele funcții: 
-<code javascript>​ 
-const child_process = require ('​child_process'​);​ 
-child_process.execFile ('​ls',​ function (err, stdout, stderr){ 
-  if (err) console.log ('​Execution had an error'​);​ 
-  console.log ('​output messages'​+stdout);​ 
-  console.log ('​error messages'​+stderr) 
-}); 
- 
-const proc = child_process.spawn ('​ls'​);​ 
-proc.on ('​data',​ function (data){ 
-  console.log ('​Spawn process output: '​+data);​ 
-}); 
- 
-proc.on ('​close',​ function (){ 
-  console.log ('​Spawn process closed.'​);​ 
-}); 
-</​code>​ 
- 
- 
-==Exemplu de pachet HTTP response== 
-<code bash> 
-HTTP/1.1 200 
-status: 200 
-content-type:​ text/html 
-connection: close 
- 
-<​html><​button>​response</​button></​html>​ 
-</​code>​ 
- 
-====URL==== 
-Atunci când lucrăm cu protocolul HTTP, care a fost special conceput pentru web, putem să considerăm că prin fiecare cerere pe care o facem serverului, în principiu, accesăm o resursă pe serverul respectiv, fie că este vorba de fișiere reale sau numai de date. Pentru fiecare resursă la care putem avea acces, există o modalitate de a ajunge la ea. Localizatorul de resurse uniform (URL) este un șir care indică o resursă specifică de pe web (de exemplu, http://​www.wyliodrin.com/​projects/​app;​user=lcss123?​id=1234abcd). 
- 
-Schema generală a unei adrese URL este următoarea:​ **%%protocol://​host:​port/​path;​params?​query#​fragment%%**. 
- 
-Nu toate componentele URL sunt necesare, în majoritatea cazurilor vom folosi doar protocol, host și path. 
- 
-====Metode HTTP==== 
-După cum am stabilit deja, HTTP funcționează cu mesaje de tip request-reponse. Aceasta înseamnă că clientul trebuie să trimită o solicitare pentru a obține o resursă, iar acest lucru se face prin URL. Cu toate acestea, putem face tipuri diferite de cereri. Acesta este motivul pentru care, o solicitare este definită printr-o metodă împreună cu adresa URL, astfel încât să putem avea diferite solicitări în funcție de scopul lor (regăsirea datelor, modificarea datelor, ștergerea datelor etc.). 
-Unele dintre cele mai utilizate metode HTTP disponibile sunt ''​GET''​ și ''​POST''​. 
- 
-<note info> 
-Este important să înțelegem că metodele sunt convenții simple și utilizarea acestora depinde de modul în care este implementat serverul. Pentru fiecare cerere, indiferent de tipul metodei, serverul trebuie să emită un răspuns. Prin urmare, fiecare server poate implementa metodele diferit. ​ 
-</​note>​ 
- 
-====Antetul mesajului HTTP==== 
- 
-După cum am menționat anterior, una dintre principalele părți ale unui mesaj HTTP este antetul. Aceasta conține informații importante despre cerere sau răspuns. 
- 
-Unele informații sunt generice și pot fi găsite atât în mesajele de solicitare cât și în răspunsuri,​ în timp ce alte proprietăți sunt specifice uneia dintre ele. De exemplu, puteți găsi proprietatea ''​Date''​ în ambele mesaje și stochează data și ora la care a fost generat mesajul. Pe de altă parte, avem proprietatea ''​Accept'',​ care este utilizată într-o solicitare pentru a specifica serverului cu ce tip de fișiere media ar trebui să răspundă. 
- 
-====Codurile de stare==== 
- 
-Codul de stare al unui răspuns informează clientul despre rezultatul cererii sale. Codurile de stare sunt împărțite în cinci categorii și, pe baza acestora, putem deduce rezultatul cererii trimise. Cele mai importante coduri sunt: 
-  * 200 - 299 - Coduri de succes - cererile au reușit; 
-  * 400 - 499 - Coduri de eroare ale clientului - solicitarea nu poate fi procesată de server, nu este în conformitate cu ce poate prelucra serverul; 
-  * 500 - 599 - Coduri de eroare server - solicitarea nu poate fi procesată deoarece serverul nu funcționează corect. 
-====Corpul mesajului HTTP==== 
-Corpul unui mesaj HTTP reprezintă datele brute care trebuie transmise. Deoarece nu toate cererile sau răspunsurile necesită transmiterea datelor, corpul este opțional în cadrul unui mesaj. 
- 
-Datele pot fi structurate sub diferite formate (de exemplu, structura JSON, structura XML, text). Acesta este motivul pentru care la trimiterea datelor adăugăm la mesaj antetul de tip Conținut, astfel încât să specificăm modul în care sunt structurate datele. 
- 
-În prezent, majoritatea serviciilor web HTTP funcționează cu structuri JSON. 
- 
-<note info> 
-Mai multe detalii despre mesajele HTTP sunt disponibile la următorul link: https://​developer.mozilla.org/​en-US/​docs/​Web/​HTTP/​Messages. 
-</​note>​ 
- 
-=====JSON===== 
-Cel mai folosit mod de reprezentare a datelor este JSON. 
- 
-JavaScript Object Notation (JSON) este o sintaxă folosită pentru stocarea și transmisia de date. Acest format a fost dezvoltat pentru a fi ușor de parsat și generat, fiind în același timp ușor de înțeles de către oameni. 
- 
-Formatul JSON se bazează pe două structuri: 
-  * O coleție de perechi cheie-valoare,​ similar cu un dicționar; 
-  * O listă de valori. 
- 
-<code javascript>​ 
-my_json = {"​first_name":​ "​Harry",​ 
-"​last_name":​ "​Potter",​ 
-"​age":​ 10, 
-"​hobbies"​ : ["​reading",​ "​magic"​]} 
-</​code>​ 
- 
-Pentru a extra o valoare dintr-o variabilă de tip JSON, se specifică cheia acesteia: ''​my_json["​age"​]''​. 
- 
-În Python se pot genera și manipula elemente JSON folosind modulul [[https://​docs.python.org/​3/​library/​json.html|json]]. Acesta expune două funcții importante:​[[https://​docs.python.org/​3/​library/​json.html#​json.dumps|dumps]] și [[https://​docs.python.org/​3/​library/​json.html#​json.loads|loads]]. 
- 
-Funcția ''​dumps()''​ transformă un obiect Python într-un string JSON. 
-<code python> 
-import json 
- 
-# a Python object (dict): 
-x = { 
-  "​name":​ "​John",​ 
-  "​age":​ 30, 
-  "​city":​ "New York" 
-} 
- 
-# convert into JSON: 
-y = json.dumps(x) 
- 
-# the result is a JSON string: 
-print(y) ​ 
-</​code>​ 
- 
-Funcția ''​loads()''​ transformă un string de forma JSON într-un obiect Python. 
-<code python> 
-import json 
- 
-# some JSON: 
-x =  '{ "​name":"​John",​ "​age":​30,​ "​city":"​New York"​}'​ 
- 
-# parse x: 
-y = json.loads(x) 
- 
-# the result is a Python dictionary: 
-print(y["​age"​]) ​ 
-</​code>​ 
-  
-====== Exerciţii de laborator ====== 
-Scopul acestui laborator este de a realiza un server web minimal pornind de la scheletul de cod de mai jos. 
-<code python> 
-import socket 
- 
-buffersize = 3072 
- 
-s = socket.socket (family=socket.AF_INET,​ type=socket.SOCK_STREAM) 
-s.bind (("​0.0.0.0",​ 8000)) 
-s.listen (0) 
- 
-while True: 
-    conn, addr = s.accept () 
- 
-    data = conn.recv(buffersize) 
- 
-    msg = data.decode("​utf-8"​) ​ 
-    print ('​received'​) 
-    print (msg) 
- 
-    conn.send (('​HTTP/​1.0 200 OK\r\nContent-type:​text/​html\r\nConnection:​ close\r\n\r\nbody'​).encode('​ascii'​)) 
- 
-    conn.close() 
-</​code>​ 
- 
-În acest exemplu am creat un server TCP care primeste date de la un client, le afișează, după care răspunde cu mesajul: 
-<code bash> 
-HTTP/1.0 200 OK - protocolul HTTP versiunea 1.0, cod de eroare 200 OK 
-Connection: close - inchidem conexiunea dupa trimiterea raspunsului catre client 
- 
-response 
-</​code>​ 
- 
-In acest mesaj, primele două linii fac parte din antet, iar ultima linie este corpul mesajului. 
- 
-<note info> 
-Mesajele HTTP trimise de la server sau de la client vor avea următorul format: 
-<code bash> 
-linie antet 
-linie antet 
-... 
-linie antet 
- 
-mesaj 
-</​code>​ 
-</​note>​ 
-===== Exercițiul 1 - GET message ===== 
- 
-  * Rulați exemplul de mai sus și accesați adresa ''​localhost:​8000''​ din browser. Observați răspunsul primit în browser și inspectați mesajul primit de server. 
-  * Accesați adresa ''​localhost:​8000/​hello/​world''​. 
- 
-===== Exercițiul 2 - HTML response ===== 
- 
-Modificați serverul anterior astfel încât acesta să răspundă cu o pagină html. Mesajul trimis de server trebuie să arate astfel: 
-<code bash> 
-HTTP/1.0 200 OK 
-Content-type:​ text/html 
-Connection: close 
- 
-<​html>​...</​html>​ 
-</​code>​ 
- 
-===== Exercițiul 3 - POST message ===== 
- 
-Descărcați aplicația [[https://​www.postman.com|postman]] și folosiți-o pentru a trimite un mesaj de tip POST serverului (la secțiunea Body selectați raw, text). Timiteți un mesaj scurt în corpul mesajului folosind Postman și inspectați tot mesajul primit de server. 
- 
-===== Exercițiul 4 - POST response ===== 
- 
-Modificați serverul astfel încât acesta să citească corpul mesajului primit, iar în funcție de acesta să trimită un alt răspuns, astfel: 
-  * la mesajul ''​age''​ să răspundă cu un număr; 
-  * la mesajul ''​name''​ să răspundă cu un număr; 
-  * la mesajul ''​country''​ să răspundă cu o țară. 
- 
- 
-===== Exercițiul 5 - JSON response ===== 
-Adăugați la server opțiunea ca la o cerere de tipul GET, pe ruta ''​localhost:​8000/​person''​ acesta să răspundă cu JSON de forma: 
-<code bash> 
-{ 
-"​name"​ : "Harry Potter",​ 
-"​age"​ : 10, 
-"​country"​ : "​UK"​ 
-} 
-</​code>​ 
- 
-===== Exercițiul 6 - Form server ===== 
-Creați un server web care va stoca datele unor persoane, primite de la clienți și care va răspunde cu aceste informații. Comportamentul serverului este următorul: 
-  * la un request ''​POST''​ la adresa ''​localhost:​8000/​insert''​ primește în body un JSON precum cel de mai jos și întoarce codul 200 în cazul în care datele au fost salvate sau 500, daca ceva nu a funcționat. ​ 
-<code bash> 
-{ 
-"​name"​ : "Harry Potter",​ 
-"​age"​ : 10, 
-"​country"​ : "​UK"​ 
-}</​code> ​ 
- 
-  * la un request ''​GET''​ la adresa ''​localhost:​8000''​întoarce un JSON cu toate datele stocate, de forma celui de mai jos: 
- 
-<code bash> 
-[{ 
-"​age"​ : int_value1, 
-"​name"​ : "​nume_persoana1",​ 
-"​country"​ : "tara persoana1"​ 
-}, 
-{ 
-"​age"​ : int_value2, 
-"​name"​ : "​nume_persoana2",​ 
-"​country"​ : "tara persoana2"​ 
-},....] 
-</​code>​ 
- 
-===== Exercitiu 7 - Form client ===== 
-Creați un client Python care să trimită mesaje serverului în locul lui Postman. În acest caz puteți simplifica mesajul astfel încât antetul să conțină doar informațiile necesare în prelucrearea pachetului. 
- 
-===== Bonus - Form client ===== 
-Modificați programul creat anterior astfel încât acesta să răspundă cu o pagină web ce conține 3 input-uri și care trimite aceste date prin apăsarea unui buton, după care acesta va afișa informațiile primite. 
sde/laboratoare/12_ro_js.1588704584.txt.gz · Last modified: 2020/05/05 21:49 by ioana_maria.culic
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0