Capitolul 1
1.Introducere
Tranzacțiile reprezinta o categorie aparte a sistemelor distribuite.Aceasta lucrare isi propune proiectarea, implementarea si testarea unei componente XPCOM pentru a realiza opera iuni asupra unor date cu ajutorul tranzacțiilor intr-un sistem distribuit. Codul componentei va fi scris in limbajul C++.
Lucrarea este impartita in 6 capitole, dupa cum urmeaza :
Capitolul 1. Introducere
Ofera o vedere de ansamblu asupra intregii lucrari.
Capitolul 2. Fundamentare teoretica
Acest capitol prezinta cateva chestiuni teoretice legate de sistemele distribuite.Incepe cu o introducere in problematica sistemelor distribuite,avantajele și dezavantajele lor in comparație cu sistemele centralizate,cateva aspecte care trebuie avute in vedere la proiectarea lor.In continuare este abordata problema comunicarii in sistemele distribuite,se prezinta pe scurt suportul de comunicare folosit .Tot in acest capitol se va prezenta beneficiile aduse de programarea orientata pe componente și in special a componenteleor XPCOM utilizate de platforma Mozilla Firefox.
Capitolul 3. Specificatii si arhitectura sistemului
In capitolul 3 sunt prezentate specificatiile sistemului distribuit.Se prezinta modelul de comunicare ales,arhitectura sistemului,stabilirea conexiunilor,funcțiile sistemului.
Capitolul 4. Proiectare in detaliu
Acest capitol prezinta proiectarea si implementarea interfetei.Structura programului și distribuirea componentelor.
Capitolul 5. Utilizarea componentei
In acest capitol este prezentat modul de utilizare a componentei XPCOM
Capitolul 6. Concluzii
Acest capitol conține cateva concluzii legate de performanțele și fiabilitatea sistemului
Bibliografie
2.1 Introducere in sistemele distrbuite
Datorita progresului tehnologic rapid,acest domeniu avanseaza in ritm alert,iar diferen ele intre colectarea,transportul,stocarea i prelucrarea informa iei dispar pe zi ce trece.Pe masura ce posibilitațile noastre de a colecta,prelucra si distribuii informa ia cresc tot mai mult,cererea pentru o prelucrare si mai sofisticata a informa iei cre te i mai rapid. Intrepatrunderea dintre domeniul calculatoarelor si cel al comunica ilor a avut o influenta profunda asupra modului in care sunt organizate sistemele de calcul.Vechiul model al unui singur calculator care serve te problemelor de calcul ale organiza iei a fost inlocuit de un model in care munca este facuta de un numar mare de calculatoare separate dar interconectate Aceste sisteme se numesc re ele de calculatoare.In literatura de specialitate se face deseori confuzie intre o retea de calculatoare si un sistem distribuit.
Intr-un sistem distribuit,existen a mai multor calculatoare autonome este transparenta pentru utilizator.Acesta poate tasta o comanda pentru a executa un program i programul il va executa.Este sarcina sistemului de operare sa aleaga procesorul cel mai potrivit,apoi sa gaseasca i sa transfere toate datele de intrare catre respectivul procesor i sa depuna rezultatele in locul corespunzator.Intr-o re ea,utilizatorii trebuie sa se conecteze explicit la o anumita masina,sa comande explicit execu ia proceselor la distan a sa transfere explicit fi ierele i,in general,sa personalizeze toata administrarea re elei.Intr-un sistem distribuit nu este nimic de facut in mod explicit totul este realizat automat de catre sistem,fara cuno tinta utilizatorului.
Un sistem distribuit este o colectie de calculatoare si procesoare autonome (avand o unitate de comanda proprie), interconectate (capabile de a schimba informatii intre ele).
Sistemele distribuite au aparut ca o necesitate pentru:
- schimbul de informatii intre noduri;
- siguranta in functionare: daca un nod 'cade', intregul sistem trebuie (daca este posibil)
sa fie capabil sa asigure in continuare functionarea, prin redirijarea (rutarea) mesajelor prin nodurile functionale.
Fig.1 Sistem distribuit alcatuit din noduri
Fiecare nod din figura 1 reprezinta un calculator iar linia dintre doua noduri(calculatoare) reprezinta legatura de comunicare dintre ele.
Fig.2 Sistem distribuit detaliat
In figura 2 este prezentat același sistem distribuit ca și in prima figura dar de data aceasta puțin mai detaliat.Fiecare calculator are propria memorie locala iar modul de transmitere
a informațiilor intre doua calculatoare din acest sistem distribuit se poate realiza prin trimiterea
unor mesaje de la un nod la altul folosind legatura de comunicare dintre ele.
Principalele dificultati in proiectarea sistemelor distribuite sunt:
- Asincronia - timpul absolut la care au loc evenimentele nu poate fi cunoscut precis;
- Cunoasterea locala - fiecare entitate de calcul poate dispune doar de informatia pe care o primeste, are doar o imagine locala asupra situatiei globale;
- Caderea componentelor(failures) - entitatile de calcul se pot defecta independent lasand
anumite componente operationale iar altele nu.
Modelul Client/Server
Modelul standard pentru aplicații in rețea este "client-server". Serverul este un proces care așteapta sa fie contactat de un proces client pentru a oferi diverse servicii (acces la resurse). Resursele pot fi fișiere, structuri de date, informații diverse sau resurse fizice ca imprimante, fax-uri, scannere, etc.
Serverul este startat primul, dupa care se deschide un canal de comunica ie pe sistemul pe care se afla și se informeaza "hostul" local ca se pot primi cereri de la clienți la o adresa data. Serverul va asteapta cererile la adresa respectiva.
Un client este un proces care dorește utilizarea unei resurse, avand și el o secvența de acțiuni de desfașurat. Astfel, el va deschide un canal de comunicație și se va conecta la un anumit host, la o adresa data (a serverului). Apoi,va trimite mesajul-cerere catre server și va aștepta primirea raspunsului. La terminarea acțiunii,clientul va inchide canalul de comunicație. Deschiderea unui canal de comunicație de catre server este cotata ca o acțiune pasiva, in timp ce un client deschide un canal in mod activ.
In general, un server este o aplicație care ofera servicii utilizatorilor de internet, un
client este o alta aplicație care solicita un serviciu.Exista aplicații alcatuite atat dintr-o parte
client cat și dintr-o parte server,ele pot rula pe același sistem sau pe sisteme diferite.Utilizatorii
invoca partea client a aplicației, care efectueaza o cerere referitoare la un serviciu pe care o trimite partii server a aplicației folosind protocolul TCP/IP pe post de vehicul de transport.Protocolul TCP/IP este explicat in mod detaliat in secțiunea 2.3
Serverul este un program care primește o cerere, indeplinește serviciul cerut și transmite
rezultatul drept raspuns. Un server poate rezolva, de regula, mai multe cereri (deservii mai mulți
clienti) in același timp.Comunicarea intre nodurile unei retele consta in transmiterea(receptionarea) de pachete catre (de la) gazde ale aceleasi retele sau ale unei alte retele.
Modelul utilizat pe scara larga in sistemele distribuite (si care va fi cel folosit in continuare) este sistemul Client/Server.
In acest model exista:
- o multime de procese Server, fiecare jucand rolul de gestionar de resurse pentru o colectie de resurse de un anumit tip;
- o multime de procese Client; fiecare executa activitati care necesita acces la resurse hard/soft disponibile (partajate) de servere.
Un gestionar de resurse poate avea si el nevoie de resurse gestionate de un alt proces Server. Drept urmare, unele procese pot fi atat de tip Client, cat si de tip Server. Doar serverele gestioneaza resurse.
Serverele sunt cele care isi incep primele activitatea. In mod tipic, un server ofera succesiv clientilor posibilitatea de a se conecta la el (spunem ca accepta conexiuni de la clienti). La inceput clientul isi manifesta dorinta de a se conecta si, daca serverul este gata sa accepte conexiunea, aceasta se realizeaza efectiv; este vorba deci de o actiune de la client catre server. Apoi transmisia informatiilor devine bidirectionala, fluxul de informatii putand circula acum in ambele sensuri.Teoretic, activitatea unui server se desfasoara la infinit.
2.3 Protocolul TCP
Comunicarea intre componentele unei retele (respectiv unui sistem distribuit) se face prin multimi de reguli, numite generic protocoale.TCP(Transmission Control Protocol este un protocol de nivel intermediar care are la baza conceptul de conexiune.
Protocolul TCP este orientat pe conexiunea punct-la-punct dintre sursa și destinație realizand transfer sigur de informații,fara erori.TCP folosește mesaje de confirmare a recepției corecte pentru fiecare pachet și cere retransmisia celor eronate.
In antetul TCP sunt specificate, pe 16 biți,numerele porturilor logice asociate aplicațiilor sursa și destinație,intre care se stabilește comunicația virtuala.Fiecare capat al conexiunii TCP se numeste socket.
Un protocol cuprinde atat formatul mesajului ce este efectiv transmis, cat si modul in
care trebuie raspuns la mesajul respectiv.
Incapsularea datelor consta in adaugarea unor informații suplimentare la inceputul(header),eventual și la sfarsitul blocului de date,in funcție de protocol.Datele circula in
stiva de protocoale de sus in jos,in cazul transmisiei,și de jos in sus,spre aplicații,la recepție.
In cazul folosirii TCP ca protocol de transport pentru o aplicație rulata intr-o rețea de calculatoare,incapsularea datelor se realizeaza in mai multe etape de pe un nivel pe altul,conform figurii 2 :
La nivelul de aplicații,datele utilizatorului sunt incapsulate cu un antet de aplicație intr-un mesaj de aplicație.
TCP are urmatoarele caracteristici principale:
a) Transfer de date in flux continuu - datele circula in acelasi timp, in ambele sensuri ale conexiunii. Spunem ca TCP este o conexiune duplex.
b) Siguranta transmisiei - recupereaza pachetele transmise cu erori, pierdute sau cu numar de secventa eronat. Aceasta caracteristica este asigurata prin stabilirea unui numar de secventa fiecarui pachet transmis si necesitatea unui mesaj de confirmare (ACK) din partea receptorului.Daca,dupa un anumit interval de timp,expeditorul nu primeste un mesaj de confirmare, pachetul este considerat pierdut si este retransmis.
c) Controlul fluxului de date - in fiecare mesaj ACK, trimis de receptor, este continuta o 'fereastra' care indica numarul permis de octeti pe care emitatorul ii poate transmite (Principiul ferestrei glisante). In urma unui astfel de mesaj, emitatorul isi va dimensiona pachetele transmise la lungimea indicata de receptor. Aceasta lungime este valabila pana la receptionarea urmatorului mesaj ACK, care contine o alta marime de 'fereastra'.
d) Multiplexarea - permite mai multor procese, care ruleaza pe acelasi host, sa utilizeze facilitatile protocolului TCP simultan.
e) Controlul conexiunii - in transferul de date dintre doua procese putem distinge trei etape: stabilirea conexiunii, controlul conexiunii, inchiderea conexiunii.Controlul conexiunii presupune: stabilirea numarului de secventa si a dimensiunii ferestrei, pentru fiecare pachet TCP.
Portul
Portul nu este o locatie fizica, ci o extensie software corespunzatoare unui serviciu. Portul este un capat al unei conexiuni logice in re elele TCP/IP. De fiecare data cand se face o conexiune intre doua calculatoare (client/server) se face o legatura care implica cate un port de pe fiecare calculator.Serverul poate oferi mai multe servicii, pentru fiecare existand un numar de
port. Porturile din intervalul 0..1023 sunt in general rezervate pentru servicii speciale si pentru clienti privilegiati.
Clientul initiaza conexiunea prin retea, specificand adresa serverului si portul prin care doreste sa comunice. Serverul trebuie sa precizeze numai portul; apoi el trebuie sa execute o comanda prin care sa anunte ca este gata sa accepte conexiuni pe portul respectiv drept urmare el ramane in asteptare pana cand un client doreste sa se conecteze si conexiunea este stabilita cu succes.Un server poate accepta conexiuni de la mai multi clienti:pentru fiecare creaza un fir de executare.
Anumite servere asteapta cererile la un port bine cunoscut astfel incat clien ii lor tiu catre ce socket IP sa i indrepte cererile lor.
Adresa IP/LocalHost
Pentru a putea fi folosita intr-o re ea TCP/IP, o interfa a trebuie sa aiba asociata o adresa
IP care folose te pentru identificarea interfe ei respective cand comunica cu restul lumii..
Adresa 127.0.0.0 este rezervata pentru traficul IP local catre gazda locala De obicei,
adresa 127.0.0.1 va fi asociata unei interfețe speciale numita interfața loopback , care se comporta ca un circuit inchis. Orice pachet IP trimis prin aceasta interfața, va fi returnat ca i cum ar fi venit de la un calculator din re ea. Acest lucru ne ofera posibilitatea sa dezvoltam și sa testam software de re ea fara sa folosim re ea reala. Alta aplica ie folositoare este atunci cand vrem sa folosim software de re ea pe un calculator care nu este in re ea.
2.4 XPCOM
Programarea bazata pe componente este o ramura a ingineriei programarii, in care obiectivul cheie este descompunerea inca din faza de proiectare a unui proiect amplu in componente care au un scop bine definit si o interfata care contine intrarile si iesirile prin care componenta se leaga de alte componente sau de sistem.
Pentru a nu fi confundate cu obiectele, putem spune ca componentele sunt construite din mai multe obiecte, prezinta un nivel mai inalt de abstractizare si ofera o anumita functionalitate cu ajutorul interfetelor implementate.
Prin definitie o componenta este un obiect scris pentru o specificatie si care indeplineste
urmatoarele criterii de baza:
refolosire - o componenta trebuie sa fie proiectata si implementata astfel incat sa poata fi folosita in diverse programe;
nespecifica unui context - ar trebui sa poata fi folosita si de alte programe care nu au legatura cu domeniul in care este folosita componenta;
sa poata comunica cu alte componente - interfata trebuie astfel conceputa incat alipirea la alte componente, scrise chiar si in alt limbaj de programare, sa se faca cat mai usor;
sa fie incapsulata - cei care folosesc componenta nu vor stii ce se intampla de fapt in interiorul acesteia;
autonomie fata de alte componente - o componenta nu va depinde niciodata de nimic. Acest lucru, ca si comunicarea cu alte componente, sunt posibile cu ajutorul IDL (Interface Description Language), care este un limbaj comun de descriere a interfetelor componentelor.
De asemenea, pentru ca o componenta sa poata fi refolosita eficient, aceasta trebuie sa raporteze mesaje de eroare folositoare si sa fie testata intens pentru a descoperii orice neajunsuri care pot aparea in cazul unei folosiri neprevazute.
Cand a aparut prima data aceasta idee de programare bazata pe componente nu existau standardele necesare crearii lor ca in ziua de azi (COM, XPCOM, etc.), astfel ca programatorii nu erau motivati sa proiecteze un sistem in vederea refolosirii unor "bucati" din el in alte proiecte. De-a lungul timpului, odata cu necesitatea implementarii de programe tot mai complexe in timpi tot mai scazuti, programatorii au fost constransi sa adopte ideea de refolosire a unor bucati de cod, ajungandu-se in cele din urma la standardele de azi.
In momentul de fata exista mai multe companii dezvoltatoare de software care folosesc asemenea componente care sunt create pe diferite interfete dezvoltate de acestea. Printre cele mai importante putem enumera:
XPCOM (Cross Platform Component Object Model) de la Mozilla - folosita in lucrarea de fata - este, ca si COM de la Microsoft, un framework (o interfata cadru) care permite dezvoltatorilor sa
creeze programe din module mai mici numite componente care apoi sunt asamblate la rularea programului;
Motivul principal al alegerii in lucrarea de fata a tehnologiei XPCOM este posibilitatea dezvoltarii de aplicatii care pot rula pe mai multe sisteme de operare (Windows, Linux, MAC) si fata de CLX, resursele disponibile cu privire la modalitatea dezvoltarii unor astfel de componente sunt mult mai ridicate.
XPCOM reprezinta o metodologie de programare a aplicatiilor distribuite, inspirata de COM(Component Object Model), independenta de platforma hardware si software: fragmente de cod ofera interfete independente de limbaj și platforma spre alte obiecte care pot sa acceseze diferite servicii. Astfel, proiectarea și compilarea aplicatiei se pot realiza indiferent de implementarea obiectelor, programatorii trebuind sa cunoasca numai interfete oferite de obiecte. Aceste interfete vor fi descrise intr-un limbaj special denumit XPIDL, extensie a limbajului de definire a interfetelor IDL (Interface Definition Language) folosit de COBRA si COM. XPConnect este tehnologia prin intermediul careia interfetele descrise de XPIDL sunt conectate la partile de cod care implementeaza obiectele in JavaScript, limbajul utilizat de XUL.
Nucleul navigatorului, purtand numele de Gecko, reprezinta o componenta modulara, bazata pe clientii Netscape/Mozilla, care poate fi inclusa atat in aplicatii Web de mari dimensiuni cu propriile lor interfete-utilizator cat si in dispozitive miniaturizate. Filosofia dezvoltarii actuale si viitoare a nucleului tine cont de urmatoarele aspecte:
a) Gecko nu reprezinta un browser Web, neavand propria sa interfata, si nu are integrate servicii auxiliare (de exemplu, clientul de posta electronica sau editorul HTML) si nu ofera facilitati suplimentare (e.g. bookmarks) ;
b) se bazeaza numai pe standarde deschise redactate de Consortiul Web: HTML 4.0, CSS1, CSS2, DOM1, DOM2, XML, RDF etc., iar HTML dinamic este simulat prin DOM;
c) sta independent de platforma (prin tehnologia NSPR), foarte compact (prima versiune putea fi stocata pe o singura discheta) si rapid;
d) partea de comunicare in retea este ea insasi modulara, purtand numele de Necko;
e) este extensibil, sursele fiind publice;
f) ofera suport pentru navigatoarele mai vechi.
In acest mod, nucleul poate fi folosit de mai multe navigatoare sau aplicatii, in diferite circumstante si ruland pe diverse platforme, interfata cu acesta putand fi aleasa de utilizator, beneficiind de flexibilitatea oferita de XUL.
Folosind tipul info, un program poate determina fiecare parametru sau atribut al oricarei metode date pe unele interfete. Cu aceste cunostinte, el poate muta datele inainte si inapoi intre interfata si alte cateva medii. Acele alte medii pot fi motoare de scriptare sau proxi-mecanisme pentru trecerea firului, procesului sau a retelei de granite. In cazul unui motor de scriptare, reiese modul in care o componenta este definita in mediul de scriptare, astfel incat modul scriptat poate invoca metode pe o componenta a interfetei.
XPConnect este un strat suplimentar construit in partea de sus a XPCOM, care poate transforma o interfata XPCOM intr-un motor JavaScript, citind un fisier XPCOM de tip bibleoteca. XPConnect permite, de asemenea, componentelor XPCOM sa fie scrise in intregime in JavaScript, astfel putem avea un cod C++ numit ca un JS component, sau putem folosi JS pentru a incarca sau manipula un component C++ compilat. Alaturi de JavaScript, limbajul Python a fost adaugat ca o alta scriptare alternativa, folosind un mecanism similar cu XPConnect.
Fig1.Componenta XPCOM in interfata cadru
Cand construim o componenta sau un modul(mai multe componente) și le compilam intr-o librarie se exporta o singura metoda numita NSGetModule.Aceasta funcție este punctul de intrare pentru a accesa libraria.Aceasta funcție este apelata in timpul inregistrarii componentei dar și atunci cand XPCOM vrea sa descopere ce interfețe sau clase implementeaza respectivul modul/librarie.
Pe langa funcția NSGetModule se poate observa in structura existenta doua interfețe: nsIModule i nsIFactory.Aceste interfețe controleaza crearea componentei.Pentru a intelege cand o componenta dintr-o librarie este apelata trebuie sa intelegem procesul de inițializare a XPCOM.Cand o aplicație pornește ea poate sa inițializeze XPCOM.Secvența de evenimente care pornește inițializarea unui XPCOM poate veni atat din partea clientului cat și din partea aplicației cand pornește.
Exista 6 pași importanți pentru pornirea unui XPCOM
1.Aplicația pornește XPCOM
2.XPCOM trimite o notificare ca vrea sa porneasca
3.XPCOM gasește și proceseaza "component manifest"(fișier special care conține informații despre componentele din sistemul local)
4.XPCOM gasește și proceseaza "type library manifest"(fișier special care conține informații
despre librariile din sistem
5.Daca exista componente noi,XPCOM le inregistreaza
-XPCOM apeleaza autoinregistrarea
-XPCOM inregistreaza noua componenta
-XPCOM apeleaza sfarșitul autoinregistrarii
6.Pornirea XPCOM este completa,XPCOM anunta ca a pornit.
2.5 Tranzacții
O tranzacție este specificata de client ca un set de operații pe un obiect cu scopul de a fi rulate de o "unitate invizibila" de pe serverul care conține respectivele obiecte.O tranzacție se desfasoara in mai multe etape.
Pentru inceput un proces anunța ca dorește sa realizeze o tranzacție impreuna cu unul sau mai multe procese.Se negociaza opțiuni,se creeaza obiecte și se realizeaza operațiile necesare.Cand toata munca a fost terminata inițiatorul tranzacției anunța ca dorește ca toate schimbarile facute sa devina permanente.Daca celelalte procese participante sunt de acord starea sistemului este salvata,dar daca cel puțin unul refuza sau din cauza unei erori nu poate fi deacord,sistemul este adus in starea inițiala,din momentul in care a inceput tranzacția.
Scopul unei tranzacții este de a garanta integritatea tututoror obiectelor manipulate de un server sa ramana intr-o stare consistenta atunci cand sunt accesate.Tranzac ia se aplica obiectelor recuperabile i are inten ia sa fie atomica.Mai este numita i tranzac ie atomica
Exista doua aspecte asupra acestei atomicita i
Totul sau nimic:O tranzac ie fie se realizeaza cu succes i rezultatele acesteia se scriu in obiecte sau daca apare o eroare nu se inregistreaza deloc.
Acest efect totul sau nimic are deasemenea 2 particularita i:
a)atomicitatea erorii - efectele sunt atomice chiar daca serverul cade(crash)
b)durabilitate - dupa ce o tranzac ie s-a completat cu succes toate efectele sale sunt salvate in memoria permanenta adica datele salvate vor rezista chiar daca serverul o sa pice.
Izolare:Fiecare tranzac ie trebuie realizata fara existen a unei interferen e din partea
unei alte tranzac ii.Ea nu trebuie sa fie vazauta de alta tranzac ie Pentru a face posibila
durabilitatea i atomicitatea unei erori obiectele de pe server trebuie sa fie recuperabile.Cand un
proces de pe server cade"crash" din cauza hardweare sau softweare,schimbarile efectuate de
tranzac iile anterioare trebuie sa fie disponibile in memoria permanenta astfel ca atunci cand
procesul picat este inlocuit de un proces nou sa poata sa recupereze obiectele.
Consistenta : constantele sistemului nu sunt modificate,chiar daca in timpul executarii tranzacției,pentru o perioada scurta de timp,exista modificari la sfarsitul tranzacției ele sunt aduse in starea inițiala
Un server care accepta tranzac ii trebuie sa tie sa sincronizeze opera iile suficient de
repede astfel incat sa se asigure condi iile de izolare.O cale de a face acest lucru posibil este
executarea tranzac ilor intr-un mod serial: fiecare pe rand intr-o ordine arbitrara.Din pacate aceasta solu ie nu se poate aplica(e dificila) la un server al caror resurse sunt impar ite cu un alt user.
Daca un server nu este construit cu grija atunci operațiunile clien ilor pot cateodata sa interfereze intre ele.Aceasta interferența ar putea produce valori eronate obiectelor
Opera ii atomice la server
Folosirea mai multor fire de execuție "threads" este un beneficiu in perfoman a multor
servere.Deasemenea folosirea lor permit opera ilor de la mai mul i clien i sa ruleze intr-un mod
concuren ial pentru accesarea obiectelor.Metodele obiectelor trebuie construite in a a fel incat sa permita folosirea mai multor fire.
Firele de execuție seamana cu procesele, pot fi la fel planificate pentru execuție.
Principala diferența este ca firul se executa in spațiul de adresare al procesului caruia aparține și
poate modifica valori care sunt vazute și de celelalte fire care aparțin aceluiași proces.Din
aceasta cauza apare necesitatea ca firele sa comunice intre ele, adica trebuie sincronizat accesul
la datele utilizate in comun. Sincronizarea asigura siguranța datelor, adica prin sincronizare se
previn situațile ca un fir sa modifice o variabila care este utilazata de catre un alt fir de execuție.
Daca un fir de execuție "thread" invoca o metoda sincronizata dintr-un obiect atunci
obiectul respectiv este inchis "locked" astfel incat daca un alt fir "thread" invoca una din metodele sincronizate ale respectivului obiect va fi blocat pana cand primul inchis "lock" se va
deschide Aceasta forma de sincronizare forteaza execu ia firelor "threads" sa se efectueze separat
in timp i asigura faptul ca variabilele unui obiect sunt accesate intr-un mod controlat i ordonat.
Fara sincronizare doua invocari pentru un "deposit" ar putea citi balan a curenta inainte ca aceasta sa fie incrementata rezultand o valoare incorecta.Orice metoda care acceseaza o variabila instanta care poate varia trebuie sa fie obligatoriu sincronizata.Acestea se numesc opera ii atomice Folosirea metodelor sincronizate in Java este o cale de a rezolva problema.Dar in alte limbaje de programare pentru serverele "multi - thread" oprea ile pe obiecte au deasemenea nevoie de oprea ii atomice pentru a ine obiectele consistente.Acest lucru se poate realiza prin folosirea excluderilor mutuale MUTEX
Un mutex este un obiect de sincronizare care poate fi deținut (posedat, acaparat) doar de
un singur proces (sau thread) la un moment dat. Drept urmare, operațiile de baza cu mutex-uri
sunt cele de obținere(lock) și de eliberare(unlock). Odata obținut de un proces, un mutex devine
indisponibil pentru orice alt proces. Orice proces care incearca sa acapareze un mutex indisponibil, se va bloca (un timp definit sau nu) asteptand ca el sa devina disponibil. Mutex-
urile sunt cel mai des folosite pentru a permite unui singur proces la un moment dat sa acceseze
o resursa.
2.6 Mozilla Firefox
Mozilla este o platforma portabila open-source care pune la dispozitia programatorilor functionalitatile necesare dezvoltarii unor aplicatii,care prezinta o interactivitate ridicata pentru utilizatori. Acest lucru este posibil datorita functionalitatii pe care se bazeaza proiectul prezentat, si anume programarea bazata pe componente.Aceasta platforma inglobeaza mai multe tehnologii, dupa cum se poate observa in figura urmatoare, insa despre cele mai importante (NSPR si XPCOM)
Interfetele componentelor sunt descrise cu ajutorul unui limbaj independent de platforma numit XPIDL (Cross Platform Interface Definition Language), care este varianta proprie adoptata de XPCOM pentru limbajul IDL. Aceasta interfata are rolul de a face conversiile de variabile de intrare si de iesire si a le transmite din limbajul in care se programeaza (in cazul de fata C++) intr-un fisier cu extensia idl, necesare pentru crearea componentei.
Pe cealalta parte se afla XPConnect, un strat al XPCOM care ofera accesul la componente cu ajutroul variabilelor prin intermediul unor limbaje (ex: JavaScript) folosite pentru realizarea comunicarii in interfata cu utilizatorul. Aceasta interactiune intre XPConnect si
JavaScript se realizeaza cu ajutorul unui Contract ID (reprezentat de un sir de caractere unic in care se specifica domeniul, modulul, numele componentei si numarul versiunii) sau a unui UUID (Universal Unique Identifier), care este un numar unic de identificare format din 32 de caractere (cifre si litere).
Partea responsabila pentru interfeta cu utilizatorul in cazul acestei aplicatii este un
browser web, care contine un limbaj independent numit DOM (Document Object Model), cerut de limbajul JavaScript pentru a vedea sau modifica o pagina web in mod dinamic.
API-ul NSPR
NSPR (Netscape Portable Runtime) este o interfata de programare (sau API) folosita pentru a oferi componentelor create cu ajutorul acesteia portabilitatea necesara pentru a putea fi rulate pe diverse sisteme de operare. Pana in momentul de fata acest API poate fi folosit in crearea de aplicatii pe principalele sisteme de operare existante pe piata (Windows, Linux si Mac OS).
Modul de functionare: obiectivul NSPR-ului este de a oferi un serviciu uniform pe o gama larga de medii de sisteme de operare. Acesta se straduieste sa nu exporte cel mai mic numitor comun, dar sa exploateze cele mai bune caracteristici ale fiecarui sistem pe care ruleaza si inca sa ofere serviciu
uniform.
Principalele facilitati oferite sunt:
crearea, administrarea si planificarea firelor de executie intr-un mod propriu de prioritati independent de sistemul de operare;
sincronizarea firelor de executie prin operatii de tip mutex;
operatii de intrare/iesire de tip socket;
masurarea exacta a intervalelor de timp si a sincronizarilor prin operatii specifice;
administrarea memoriei printr-un mecanism propriu de alocare si golire a memoriei;
posibilitatea de folosire a librariilor puse la dispozitie de catre setul de
aplicatii Gecko SDK.
Firele sunt principalele particularitati ale NSPR. Oferta de fire pentru industrie este destul de variata. NSPR, departe de perfectiune, ofera un singur API, la care clientii pot programa si pot astepta comportament rezonabil de consistent. Sistemele de operare ofera totul, incepand de la concept non-fire si mergand in sus pana la sofisticat, scalabil si implementari eficiente. NSPR face mai mult decat sistemele pot oferi. Este un scop al NSPR-ului ca el sa impuna pe cat posibil accesul la caracteristicile sistemului.
Referitor la retea, partea de NSPR se ocupa cu manipularea adresei de retea. NSPR defineste o retea-obiect, care este adresa IP. Atat timp cat acest obiect nu este declarat opac, API ofera metode care permit si incurajeaza clientii sa trateze adresele ca elemente polimorfice. In acest domeniu, scopul este de a oferi o cale de migrare intre IPv4 si Ipv6. In acest scop, este posibil sa se efectueze traduceri din siruri de caractere ASCII (nume DNS) in structurile de adrese de retea ale NSPR-ului, fara vreo retinere pentru ca tehnologia de adresare este Ipv4 sau Ipv6. API-ul NSPR este inclus in setul de aplicatii si unelte Gecko SDK.
3.1 Schema bloc a sistemului
Fig.1 Schema bloc a sistemului
Se considera un sistem format din doua componente majore: un server(Coordonator de Tranzacții) și un numar de clienți(Componente de Tranzacții).
Coordonatorul de Tranzacții este cel care va coordona mesajele de primire/trimitere in sistem.El va trebui sa știe sa comunice cu toate componentele tranzacțiilor pentru a putea coordona acțiunile lor pana ce tranzacțiile se vor comite.
3.2 Arhitectura Coordonatorului de Tranzacții
Fig.1 Arhitectura Coordonatorului de Tranzacții
Nivelul de rețea al aplicației va fi unul local.Vom folosi o interfa a loopback , care se comporta ca un circuit inchis. Orice pachet IP trimis prin aceasta interfața, va fi returnat ca i cum ar fi venit de la un calculator din re ea.Sistemul de Operare folosit va fi Windows XP.Aplicația va utiliza platforma Mozilla o platforma portabila open-source care pune la dispozitia programatorilor functionalitatile necesare dezvoltarii unor aplicatii,care prezinta o interactivitate ridicata pentru utilizatori. NSPR (Netscape Portable Runtime) este o interfata de
programare (sau API) folosita pentru a oferi componentelor create cu ajutorul acesteia portabilitatea necesara pentru a putea fi rulate pe diverse sisteme de operare. Pana in momentul
de fata acest API poate fi folosit in crearea de aplicatii pe principalele sisteme de operare existente pe piata (Windows, Linux si Mac OS).
Nivelul Decizional,Coordonatorul de Tranzacții și Canalul de Comunicare luate impreuna alcatuiesc Componenta XPCOM.Canalul de comunicare care va fi folosit este unul bazat pe protocolul TCPIP.Acesta este un canal sigur de transmitere de informații recuperand pachetele transmise cu erori, pierdute sau cu numar de secventa eronat.Datele circula in acelasi timp,in ambele sensuri ale conexiunii.Coordonatorul de Tranzacții va face parte dintr-o tranzacție distribuita și va trebui sa știe sa comunice cu ceilalți participanți la tranzacție.
Nivelul Decizional este locul unde se va lua o decizie finala in privința unei tranzacții.Datorita celei mai importante proprietați a unei tranzacții:atomicitatea(totul sau nimic) remarcam faptul ca atunci cand o tranzacție distribuita ajunge la sfarsitul execuției toate componentele ei trebuie sa fie completate cu succes.In caz contrar daca o parte dintr-o tranzacție este anulata(aborted) atunci toata tranzacția trebuie sa fie anulata.Un mod simplu de a completa o tranzacție respectand atomicitatea ei este acela in care coordonatorul de tranzacții comunica cererea de comitere sau anulare catre toți participanții unei tranzacții.Acest exemplu este inadecvat deoarece atunci cand un participant cere sa comita o tranzacție el nu lasa coordonatorului libertatea de a lua o decizie unilaterala pentru a anula tranzacția.
Protocolul in doi pași este construit in așa fel incat orice participant poate sa anuleze partea lui de tranzacție.Daca o parte dintr-o tranzacție este anulata atunci toata tranzacția trebuie sa fie anulata. In timpul procesului de tranzacție participanții(Componentele Tranzacției) vor trimite o confirmare de participare la tranzacție.Cererea unui participant de a comite(realizare cu succes) sau abort(anulare) a unei tranzacții trebuie sa fie trimisa la Coordonatorul de Tranzacții.Coordonatorul trebuie sa informeze ceilalți participanți atunci cand una din Componente face abort.Intr-o tranzacție distribuita coordonatorul comunica cu participanții pentru a realiza protocolul de comitere in doi pasi.
Pentru acest lucru Coordonatorul va folosi o funcție "CanCommit?" prin care intreaba toți participanții daca vor sau nu vor sa comita tranzacția in care sunt implicați.Participantul poate sa raspunda cu Da/Nu.Inainte sa spuna "Da" participantul(Componenta de Tranzacție) se pregatește sa comita salvand obiectul/obiectele in memoria permanenta.Daca votul este negativ
"Nu" atunci participantul va face abort la respectiva tranzacție in care este implicat.Coordonatorul va culege toate voturile de la toți participanții.Daca toate voturile sunt
"Da" atunci Coordonatorul va decide sa comita tranzacția și trimite o cerere DoCommit(comitere cu succes) la toți participanții si va trimite "DoAbort"(anulare tranzactie) in caz contrar.
3.3Arhitectura Componentei tranzactionale
Fig.1 Arhitectura componentei tranzacționale
Dupa cum se poate observa arhitectura Componentei de Tranzacție este asemanatoare cu cea a Coordonatorului de Tranzacție.Arhitectura componentei se diferențiaza printr-o interefața intereacțiune.
Aceasta interfața intereacțiune este compusa din urmatoarele funcții :
1.Funcția InregistrareTranzacție
Aceasta funcție va avea rolul de a inregistra informațiile despre o anumita tranzacție.Utilizatorul iși manifesta dorința de a incepe o anumita tranzacție.Aceasta informație este trimisa catre Coordonatorul de Tranzacții.
2.Funcția PrimeșteNotificare
Avand in vedere ca o componenta XPCOM nu va putea comunica cu celelate componente printr-o comunicare bazata pe evenimente singura metoda de interacțiune pe care o vom putea folosi este metoda de comunicare prin interogare periodica(pooling).Pentru a realiza acest tip de comunicare Componenta va "intreaba" periodic Coordonatorul daca are de realizat ceva.
3.Funcția StartRaspuns
Daca Coordonatorul de Tranzacție va trimite unei Componente o cerere de incepere a unor operații care fac parte dintr-o anumita tranzacție in care și Componenta respectiva este implicata atunci Componenta,prin intermediul acestei funcții,va fi nevoita sa ii raspunda Coordonatorului daca este pregatita sau nu este pregatita sa inceapa tranzacția.
4.Funcția ExecutaTranzacție
Aceasta funcție va trimite o valoare afirmativa sau negativa cu privire la execuția parții de tranzacție pe care Coordonatorul de Tranzacții a solicitat-o unei Componente.
5.Funcția Finalizare
Aceasta funcție la fel ca și funcția de execuție va trimite un raspuns catre Coorodonatorul de Tranzacții daca componenta este deacord sau nu este deacord sa finalizeze partea de tranzacție in care este implicata.
3.4 Cazurile de utilizare
3.4.1 Cazul de utilizare pentru Coordonatorul de Tranzacții
Fig.1 Cazul de utilizare pentru Coordonatorul de Tranzacți
Coordonatorul de tranzacții va inregistra prima data tranzacția pe care a primit-o de la utilizator adaugandu-i un identificator unic.Acest identificator unic va fi alocat de Coordonatorul de Tranzacții și trimis inapoi la Componenta de Tranzacții.
Coordonatorul de Tranzacții va avea obligația sa informeze și celelalte Componente care vor fi parte activa la aceasta tranzacție sa inceapa executarea operațiunilor.
Pe baza raspunsurilor pe care le va primi de la componentele din tranzacția ceruta de utilizator,dupa ce componentele și-au efectuat partea de tranzacție cu succes sau cu esec,Coordonatorul trebuie sa se hotarasca și sa stabileasca o decizie finala de comitere sau anulare a tranzacției.
Ultimul pas este finalizarea tranzacției.In acest ultim pas Coordonatorul de Tranzacție asteapta raspunsul afirmativ sau negativ de comitere a tranzacției de la fiecare Componenta de Tranzacție participanta.
3.5 Cazul de utilizare pentru Componenta Tranzacționala.
Fig.1 Cazul de utilizare pentru Componenta tranzacționala
Componenta tranzacționala va trebuii sa realizeze urmatorii pași :
-Sa comunice Coordonatorului tranzacția pe care utilizatorul dorește sa o efectueze dar și celealte tranzacții la care respectiva Componenta poate participa.Acest lucru se realizeaza prin trimiterea unui mesaj de inceput catre coordonator.
-Coordoantorul va trimite un mesaj de confirmare catre Componenta in care specifica acesteia ca poate sa porneasca partea ei de tranzacție.
-Componenta pornește tranzacția și realizeaza operațiile necesare pentru a completa partea tranzacției pe care o are de indeplinit.
-Componenta trebuie sa trimita un mesaj afiramtiv sau negativ de efectuare a parții de tranzacție in care este implicata.
-Ultimul pas este cel de finalizare in care Componenta trimite un mesaj pozitiv sau negativ cu privire la finalizarea parții de tranzacție in care este implicata.
Capitolul 4. Proiectarea in detaliu
4.1 Structura programului
4.1 Structura interna a Coordonatorului de Tranzacții
Fig1. Structura interna de conectare a Coordonatorului de Tranzacții
Pentru fiecare componenta conectata la Coordonatorul de tranzacții se creaza un obiect din clasa "PentuConectare".Acest obiect conține toate informațiile despre Componenta.Cu ajutorul firelor de execuție(threads) va realiza schimbul de mesaje intre Coordonatorul de Tranzacții și toate Componentele de Tranzacție care vor lua parte la efectuarea unei tranzacții ceruta de utilizator.Conexiunea dintre cele doua entitați se realizeaza cu ajutorul unui obiect de tip socket.
4.2 Structura interna pentru Componenta de Tranzacție
Fig.2 Structura interna de conectare pentru Componenta de Tranzacție
Componenta are o structura simpla de conectare formata dintr-un obiect Socket și un obiect Conectare.Transmiterea și primirea de mesaje la fel ca și in cazul Coordonatorului de Tranzacții se realizeaza cu ajutorul a doua fire de execuție.
Obiectul Socket este realizat cu ajutorul funcțiilor NSPR utilizand header-urile
#include <prio.h>; #include <prerror.h>; #include <prnetdb.h>
4.3 Diagrama de secvența
Fig.1 Diagrama de seventa
Dupa cum se observa in diagrama de secventa, comunicarea dintre Coordonatorul de Tranzacții și Componentele Tranzacției care sunt implicate intr-o anumita tranzacție se va realiza parcurgand urmatoarele etape:
4.4 Diagrama de Clase pentru Coordonatorul de Tranzacții
Sistemul este format din mai multe clase construite cu libraria libnspr de tip NSPR care ofera funcționalitați simple :fire de execuție,socluri și elemente de legatura cu clasele la un nivele mai inalt.Canalele de comunicație moștenesc soclurile și firele de execuție,pentru a oferi un control mai avansat al fluxului de mesaje.Peste aceste canale sunt construite serviciile,care deja au functionalitați complexe.In aplicația noastra avem doua tipuri de servicii,un serviciu Client care reprezinta defapt o "Componenta de Tranzacție" și un serviciu Server care reprezinta "Coordonatorul de Tranzacții".
In aceasta parte vom prezenta intr-un mod mai detaliat clasele componente ale Coordonatorului de Tranzacții.Una dintre cele mai importante clase la acest membru de aplicație este clasa PentruConectare.Aceasta clasa creaza un obiect pentru fiecare client care se va conecta la Coordonator pentru a stoca informațiile componentei: tranzacțiile la care poate participa componenta respectiva.Aceasta clasa mostenește clasele Socket și TwinThread deoarece va folosi doua fire de execuție: t, t2 care se vor ocupa de primirea și trimiterea measjelor și un socket pentru conectare.Primul fir de execuție se va ocupa cu cititul datelor de pe socket astfel incat mesajele care vor fi primite se vor direcționa catre funcția processInMesage() pentru a fi procesate.Al doilea fir de execuție se ocupa cu trimiterea datelor pe socket pentru a ajunge la Componenta.Prima data se extrage un mesaj primit de la o Componenta dintr-o lista Mutex,acest mesaj trebuie procesat dupa care Coordonatorul de Tranzacții creaza un raspuns pe baza mesajului primit.In headerul acestei clase avem construita o structura de tip MesajH pentru mesajele care vor fi trimise catre componente.Tot aici exista o lista std::list< unsigned int > m_tranzactiiCunoscute unde sunt stocate toate tranzacțiile cunoscute de Coordonatorul de Tranzactii.Pentru fiecare Componenta exista cate un obiect PentruConectare.Aceste obiecte sunt puse intr-o lista care aparține clasei Conectare.Deasemenea clasa Conectare conține și structura unei componente struct componente(stare; stareTranz; timpulActiunii ).Tot aici am adaugat și structura unei tranzacții care este compusa din:
tranzId(id ul tranzacției)
std::list < componente* > parțileTranzacției(parțile compomponente ale tranzacției
Un obiect care sta la baza transportului de date este derivat din clasa MesajH.Aceasta clasa conține toate setarile necesare pentru ca datele sa ajunga la destinație.Clasa reprezinta defapt headerul(antetul) mesajului.Acest antet conține subtipul mesajului care poate fi de tip Server(Coordonator de Tranzacții) sau Client(Componenta).Pe langa subtipul mesajului mai avem și un Id care este un identificator unic,el reprezinta tranzacția la care se adreseaza mesajul curent.O alta componenta importanta in antetul mesajului este status care conține starea mesajului ce poate lua valoarea de true sau false.Ultima componenta din antetul mesajului este dataSize care face referire la datele din mesaj.
Clasa Conectare moștenește clasele ServerSocket și TwinThread.In aceasta clasa se realizeaza conectarea.Constructorul clasei creaza un socket.La fel ca și clasa Pentru Conectare aceasta clasa folosește doua fire de execuție.Primul fir de execuție accepta noi socketuri și le pune intr-o lista de tip Mutex.Rolul celui de-al doilea fir de execuție este acela de a șterge conexiunile moarte.
Clasa ServerSocket moștenește clasa Socket și implementeaza metode pentru a pune serverul in starea de "ascultare" și pentru a accepta cereri de conexiune.Mai conține și membrul m_port folosit pentru a specifica pe ce port sa se porneasca ascultarea.Clasa Socket este construita cu ajutorul functilor de tip NSPR gen PR_NewTCP Socket();PR_Send();PR_Recv().
4.5 Diagrama de Clase pentru Componenta de Tranzacție
A doua parte a aplicației este Componenta de Tranzactie.Aceasta componenta este construita pe aceleași principii care au stat la baza construirii Coorodnatorului de Tranzacții. Este formata din mai multe clase construite cu ajutorul librariei libnspr de tip NSPR care ofera funcții utile pentru construcția firelor de execuție,socluri și mutex.Canalele de comunicație moștenesc soclurile și firele de execuție,pentru a oferi un control mai avansat al fluxului de mesaje.
Clasa cea mai importanta a componentei de tranzacții este clasa Tranzacție care conține toate funcțiile importante pentru realizarea cu success a unei tranzacții.Aceasta clasa conține funcția de pornire Tranzactie(),executare Executare() si finalizare Finalizare() a parții de tranzacție in care este implicata o componenta.Funcția getNotificare() rezolva problema comunicarii,o componenta XPCOM nu poate posta evenimente catere alte componente.Singura metoda de interacțiune cu alte componente este metoda de comunicare prin interogare periodica numita și pooling aceasta funcție realizeaza acest lucru.
Clasa Conectare este foarte importanta deoarece se ocupa de partea de conectare a Componentei.Deasemenea adauga la inceputul listei de tip mutex m_outMessageList mesajele aferente fiecarui Id al tranzacțiilor existente pe componenta respectiva astfel Coordonatorul știe ce tranzazcții poate realiza fiecare Componenta in parte daca se vor conecta mai multe Componente.Structura de schimb de mesaje este identica cu cea din partea Coordonatorului.Se folosesc doua fire de execuție,primul fir de execuție se ocupa cu cititul datelor de pe socket astfel incat mesajele care vor fi primite se direcționeaza catre funcția processInMesage() pentru a fi procesate.Al doilea fir de execuție se ocupa cu trimiterea datelor pe socket pentru a ajunge la Coordonatorul de Tranzacții.Prima data se verifica daca s-a primit mesaj de la Coordonatorul de tranzacții,acest mesaj trebuie procesat dupa care Componenta creaza un raspuns pe baza mesajului primit.
Clasa ClientSocket moștenește clasa Socket și implementeaza metode pentru a realiza o conexiune cu un server.Aceasta clasa inițiaza o cerere de conexiune dupa care verifica starea soclului.Printre membrii acestei clase se pot menționa urmatorii: pAddr și m_iPort prin care se specifica adresa și portul la care sa se faca conectarea și m_bConnected este utilizat pentru stabilirea starii soclului.
Clasa Thread implementeaza datele necesare pentru funcționarea unui fir de execuție pe baza funcțiilor din NSPR.Printre datele membru putem aminti m_Thread care este descriptorul firului de execuție și doua variabile de tip Boolean m_bRunning și m_bExited utilizate pentru a
semnala starea firului.Funcțiile membru start(),stop() sunt folosite pentru a porni și pentru a opri
firul de execuție.Pentru a lansa un fir de execuție trebuie derivate o clasa din Thread și suprascrisa metoda Run(),instanțiata clasa,apoi se va apela metoda start().Firul de execuție va rula pana cand metoda Run() iși va incheia execuția sau este apelata metoda stop().
Clasa TwinThread incapsuleaza doua fire de execuție,unul prin moștenirea clasei Thread,iar al doilea printr-un membru de tipul clasei ThreadRunner care moștenește la randul ei clasa Thread.Metodele t2start().t2stop(),t2isRunning și t2isExited() se folosesc pentru a porni,opri,respectiv interoga starea celui de-al doilea fir de execuție.
Clasa Socket incapsuleaza funcționalitatea unui soclu utilizat pentru a stabili o conexiune TCP/IP intre Coordonatorul de Tranzacții și Componenta.Funcțiile importante din aceasta clasa sunt getData() si sendData(),aceste doua funcții sunt folosite pentru a recepționa și pentru a trimite date pe soclu.
Clasa Mutex la fel ca și clasele Socket si Thread sunt construite cu ajutorul unor funcții speciale din libraria de tip NSPR.Aceste funcții sunt PR_Lock construiește o incuietoare(lock),PR_Unlock elibereaza o incuietoare(lock) specificata.Daca se incearca sa se deschida o incuietoare(lock) care nu este blocata atunci va rezulta o eroare.Funcția PR_DestroyLock este folosita pentru a distruge o incuietoare.
4.6 Funcțile utilizate in Componenta de Tranzacții
1. InregistreazaTranzacția(string ID) // Inregistreaza o noua tranzacție ID
2. getNotificare(ID) //Interogheaza periodic Coordonatorul pentru a vedea ce trebuie facut
4.Executat(bool) //trimite Coordonatorului o valoare de tip boolean pentru a confirma sau infirma executarea tranzacției.
5.Finalizare(bool stare) // Finalizarea tranzacției.comisa sau anulata
4.7 Protocolul de Comunicare
La nivelul de aplicații,datele utilizatorului sunt incapsulate cu un antet de aplicație intr-un mesaj de aplicație.
Fig.1 Exemplu de Mesaj aplicație.
Fig.2 Definirea antetului aplicației și datele utilizatorului.
Figura 2 reprezinta antetul mesajului de comunicare definit de catre programator cu scopul de a transmite mesaje intre componenta-coorodnator sau invers pentru realizarea etapelor necesare efectuarii unei tranzacții.Lungimea mesajului este de 6 octeți.
Acest protocol este imparțit in 3 bucați.Prima parte definește "Tipul" mesajului care poate fi interpretat de Client(Componenta) sau Server(Coordonator Tranzacții)
-Tipurile de mesaje :
MTT_INREGISTREAZA_TRANZACȚIE = 1, // Componenta inregistreaza tranzacție
MTT_CERERE_START_TRANZACȚIE, //Componenta face o cerere pentru inceput
Tranzacție
MTT_START_TRANZACȚIE, //Coordonatorul accepta start tranzacție
MTT_START_RASPUNS, //Componenta raspunde la start tranzacție
MTT_EXECUTA_TRANZACȚIE, //Coordonatorul intreaba Componenta daca s-a
executat tranzacția
MTT_EXECUTA_RASPUNS, //Raspunsul Componentei pentru Executare
MTT_FINALIZARE_TRANZACȚIE, //Coordonatorul intreaba Componenta daca a
finalizat tranzacția
MTT_FINALIZARE_RASPUNS, //Raspuns finalizare adevarat/fals
-A doua componenta pentru antetul de mesaj este "Stare mesaj".Cu aceasta componenta se poate verifica starea de succes/fail a mesajului trimis.Componenta este de tip boolean si poate lua valorile:
1: pentru true
0: pentru false
-A treia componenta pentru atentul de mesaj este ID-ul.Aceasta componenta marcheaza identificatorul unic al tranzacției la care tipul mesajului face referire.
Exemplu de trimitere mesaj :
4.8 Utilizarea librariei nspr.lib
Aplica ia folosește bibleoteca nspr.lib.Prin intermediul funcțiilor membre ale acestei bibleoteci atat serverul cat și clientul construiesc partea de socket incluzand urmatoarele header-uri #include<prio.h> #include <prerror.h> #include <prnetdb.h> cu urmatoarele funcții:
PRFileDesc :
Este folosita sa reprezinte descrierea unui socket
Socket::Socket(void* sock)
PR_NewTCP Socket() :
Creaza un nou IPv4 TCP socket
Daca se completeaza cu succes atunci este creat un pointer catre obiectul PRFileDesc
IPv4 este a patra revizuire a IP(Internet Protocol).Este un protocol de conectivitate in rețea pentru realizarea transferului pachetelor(secvențe de pachete).Aceste pachete sunt "buffered" și "queued" in funcție de traficul rețelei respective.
bool ServerSocket::makeSocket( void )
PR_Close()
Inchide un socket
if ( (status<0) && (m_socket !=NULL) )
PR_Recv()
Primește bytes de la un socket conectat
readed = PR_Recv(m_socket, &buffer[total],bufferSize - total, 0, PR_INTERVAL_NO_TIMEOUT );
- m_socket este un pointer catre un obiect PRFileDesc reprezentand un socket
- &buffer[total] este un pointer catre bufferul care ține datele primite
- bufferSize - total este dimensiunea bufferului in bytes
- (flags)0 acest parametru trebuie sa fie tot timpul zero.
PR_Send()
Trimite bytes de la un socket conectat.
sended = PR_Send (m_socket,&buffer[total],bufferSize - total, 0, PR_INTERVAL_NO_TIMEOUT);
PR_NetAddr
Este o structura folosita impreuna cu funcțiile de manipulare pentru a specifica o adresa in rețea
PRNetAddr socketInfo;
PR_InitializeNetAddr()
PR_InitializeNetAddr inițializeaza sau reinițializeaza o adresa din rețea.Depozitarea adresei de rețea este alocata si ramane responsabilitatea clientului apelant.
PR_InitializeNetAddr(PR_IpAddrAny, m_uiPort, &socketInfo)
PR_IpAddrAny este valoarea care se atribuie adresei IP din rețea.
m_uiport este valoarea portului unde este atribuita structura
&socketInfo este un pointer catre structura PRNetAddr
PR_Bind():
Cu ajutorul acestei funcții serverul leaga socketul la un port cunoscut
Aceasta funcție are urmatorii parametrii:
- un pointer catre un obiect PRFileDesc
- un pointer catre un obiect PRNetAddr care reprezinta specificarea unei adrese de rețea
if (PR_FAILURE == PR_Bind(sock, &socketInfo))
4.9 Crearea unei componente XPCOM folosind cod in C++
1. Se descarca Gecko SDK pentru sistem,care se poate gasi la https://ftp.mozilla.org/pub/ mozilla.org/mozilla/releases/mozilla1.7/ , urmand a fi extras intr-un fisier local.
2. Se creaza un GUID pentru interfata principala, pentru Windows se poate folosi guidgen, iar pentru Linux se utilizeaza uuidgen.
3. Se creaza fisierul definirii interfetei -IMyTransaction.idl.
4. Se genereaza header-ul interfetei si fisierul typelib inafara fisierului care defineste interfata, folosind utilitarul xpidl pe care primit cu Gecko SDK. Se inlocuieste in comenzile urmatoare "_DIR_" cu intreaga cale catre xpcom/idl intalnita sub directorul de baza al Gecko SDK:
xpidl -m header -I_DIR_ IMy
Transaction
.idl
va crea fisierul-header IMy
Transaction
.h
xpidl -m typelib -I_DIR_ IMy
Transaction
.idl
va crea
fisierul-typelib IM
yTransaction
.xpt
5. Header-ul interfetei IMyTransaction.h
contine sabloane utile pentru la crearea fisierului header al componentei si al fisierului implementatie. Se pot copia si lipi
sabloanele pentru a crea aceste fisiere, fiind nevoie doar de
schimbarea numelui componentei.
6). Se creaza fisierul
header al componentei
- MyTransaction.h
.
Acest lucru se incepe prin inserarea codului de protectie dubla-includere(#ifndef _MY_TRANSACTION_H_.
), dupa care
se adauga #include 'IMyTransaction.h'
pentru a include defenitia interfetei. Apoi se creaza
un GUID pentru componenta, la
care se adauga liniile urmatoare, care definesc numele componentei,
ID-ul si GUID:
#define
MY_
TRANSACTION
_CONTRACTID
'@mydomain.com/XPCOMSample/MyComponent;1"
#define
MY_
TRANSACTION
_CLASSNAME
'
Tranzactie
#define
MY_
TRANSACTION
_CID
GUID
componentei
7) Se creaza fisierul implementatie al componentei - MyTransaction.cpp
Se dauga #include
'MyTransaction.h'
pentru a include definitiile noii
componente.
8) Se creaza fisierul definitiei modulului - MyTransactionModule.cpp
. Se adauga #include
'nsIGenericFactory.h'
pentru a include
definitiile Mozilla GenericFactory #include 'MyTransaction.h'
pentru a include definitiile componentei,
NS_GENERIC_FACTORY_CONSTRUCTOR(MyTransaction)
pentru a defini constructorul pentru noua componenta,
static nsModuleComponentInfo components[] =
pentru a defini numele clasei, ID-ul si GUID-ul
componentei si NS_IMPL_NSGETMODULE
('My
Transaction
Module',
components)
pentru a exporta informatiile de mai sus catre Mozilla.
Compilarea
componentei
Se inregistreaza noua
componenta in Mozilla. Se copiaza fisierele
MyTransaction.dll
si
IMyTransactuib.xpt
in directorul cu componentele Mozilla. In
Windows, acest director se gaseste, in general, la: C:Program FilesMozilla Firefoxcomponents,
Se
ruleaza comanda regxpcom primita cu Gecko SDK pentru a
inregistra noua componenta,se sterg fisierele xpti.dat si compreg.dat din directorul de profil al Mozilla,
iar acestea vor fi compilate automat de catre Mozilla data viitoare cand va fi
restartat.
Se
testeaza noua componenta ,incepand prin restartarea Mozilla,
dupa care se deschide fisierul M
yTranzacție
Test.html
Inregistrarea componentei XPCOM
Componentele se creaza si se inregistreaza cu ajutroul setului de unelte Gecko SDK astfel:
se creaza un .dll din proiectul facut in visual C++;
se creaza un fisier .idl care contine un UUID (universal unique identifier) si contine functii pentru a prelua variabilele din .dll prin intermediul interfetelor de tip nsiSupport si Iunknown (interfata din care este derivata interfata XPCOM);
cu ajutorul utilitarului xpidl.exe din Gecko se creaza header-ul .h si libraria de tipuri .xpt a interfetei componentei;
se creaza header-ul componentei care contine: includerea header-ului interfetei; Contract ID-ul explicat in "Platforma Mozilla. Arhitectura"; numele componentei si un GUID (General Unique Identifier);
se creaza o interfata JavaScript de tipul celei de mai jos;
se copiaza fisierele .xpt si .dll in directorul de componente al aplicatiei Mozilla;
se ruleaza aplicatia Gecko regxpcom.exe pentru a inregistra o noua componenta;
dupa restartul browser-ului Mozilla, se poate rula JavaScriptul pentru a rula aplicatia.
Pentru testarea aplicatiei realizate, s-a construit o alta aplicatie, o pagina Web. Aceasta aplicatie este realizata cu ajutorul unor elemente de baza ale Limbajului HTML, precum si cu anumite elemente ale Limbajului Java Script.
Limbajului HTML
HTML (Hypertext Markup Language) este un limbaj creat in scopul de a descrie, in mod text, formatul paginilor Web; fi ierele create in acest limbaj vor fi interpretate de navigatoare, care vor afi a paginile in forma dorita (cu texte formatate, liste, tabele, formule, imagini, hiperlegaturi, obiecte multimedia
Limbajul JavaScript
JavaScript este unul din cele mai populare limbaje de programare 'client side', pentru crearea paginilor WEB. Este un limbaj de tip 'interpretor' fiind recunoscut de majoritatea browser-elor, cum ar fi: Internet Explorer, Mozzila Firefox, Opera etc. A fost dezvoltat de Sun Microsystems fiind asemanator cu C , C++
JavaScript a fost proiectat sa ofere noi facilitați pentru interacțiune cu paginile HTML.
Este o unealta de programare pentru design-erii de WEB.
JavaScript este un limbaj de scriptare interpretat.
Este un limbaj simplu i u or de folosit.
Instruc iunile acestui limbaj sunt direct inserate in paginile HTML.
JavaScript este un limbaj interpretat. (programele sunt executate fara a fi compilate).
Ce se poate face cu JavaScript ?
Se pot insera texte dinamice in pagini WEB
JavaScript poate reacționa la diverse evenimente
JavaScript poate scrie și citi elemente HTML
JavaScript se poate folosi la validari de date pe partea clientului
Poate detecta browser-ul clientului
Prin realizarea acestui proiect s-a evidentiat facilitatiile oferite de programarea distrbuita bazata pe componente pentru realizarea unor tranzacții.Acest stil de programare cu ajutorul componentelor XPCOM faciliteaza dezvoltarea unor aplicații care pot fi impartite in mai multe bucatii pentru o intelegere mai usoara a programului de catre o gama larga de utilizatori fara a fi nevoie obligatoriu de programatorul care a conceput respectiva aplicație.Aceasta perspectiva de concepere a aplicațiilor are un mare avantaj deoarece componentele rezultate din aplicație pot fi folosite in mai multe programe.
Bibliografie
Andrew S. Tanebaum, Maarten van Steen - Distribuited Systems,principles and paradigms'Prentice Hall 2002
Andrew S.Tanenbaum - "Retele de calculatoare. Editia 4", Ed. Byblos 2004;
[4] Dr.Kris Jamsa & Lars Kandler - Totul despre C si C++ Manual fundamental de programare;Ed. Teora 2007;
D. Turner, I. Oeschger, Creating XPCOM Components, Brownhen Publishing, 2003;
https://en.wikipedia.org/;
[7] https://mb.eschew.org/16 - XPCOM Objects ;
[8] https://inf.ucv.ro/courses/CB3105/resources/Introducere%20in%20UML.pdf;
[9] https://www.cs.cmu.edu/~mihaib/articles/tranzactii/tranzactii-html.html;
[10] https://thor.info.uaic.ro/~pnoro/NET/limbaj/18%20fire%20de%20executie.pdf;
[11] https://fpce9.fizica.unibuc.ro/telecom/transm_ctrl_prot_tcp.htm;
[12] https://freedownloadbooks.net/;
Politica de confidentialitate |
.com | Copyright ©
2024 - Toate drepturile rezervate. Toate documentele au caracter informativ cu scop educational. |
Personaje din literatura |
Baltagul – caracterizarea personajelor |
Caracterizare Alexandru Lapusneanul |
Caracterizarea lui Gavilescu |
Caracterizarea personajelor negative din basmul |
Tehnica si mecanica |
Cuplaje - definitii. notatii. exemple. repere istorice. |
Actionare macara |
Reprezentarea si cotarea filetelor |
Geografie |
Turismul pe terra |
Vulcanii Și mediul |
Padurile pe terra si industrializarea lemnului |
Termeni si conditii |
Contact |
Creeaza si tu |