Dezvoltarea unei aplica ii de tip chat ț utilizând XMPP propusă de David Ionu -Cătălin ț Sesiunea: februarie, 2017 Coordonator științific Asist. Dr…. [605449]

UNIVERSITATEA „ALEXANDRU IOAN CUZA” IAȘI
FACULTATEA DE INFORMATICĂ
LUCRARE DE LICENȚĂ
BlueChat
Dezvoltarea unei aplica ii de tip chat ț
utilizând XMPP
propusă de
David Ionu -Cătălin ț
Sesiunea: februarie, 2017
Coordonator științific
Asist. Dr. Vasile Alaiba
1

DECLARAȚIEPRIVIND ORIGINALITATEȘI RESPECTAREA
DREPTURILOR DE AUTOR
Prin prezenta declar că Lucrarea de licență cu titlul „ BlueChat –
Dezvoltarea unei aplicații de tip chat utilizând XMPP ” este scrisă de mine
și nu a mai fost prezentată niciodată la o altă facultate sau instituție de
învățământ superior din țară sau străinătate. De asemenea, declar că
toate sursele utilizate, inclusiv cele preluate de pe Internet, sunt indicate
în lucrare, cu respectarea regulilor de evitare a plagiatului:
toate fragmentele de text reproduse exact, chiar și în traducere
proprie din altă limbă, sunt scrise între ghilimele și dețin referința
precisă a sursei;
reformularea în cuvinte proprii a textelor scrise de către alți autori
deține referința precisă;
codul sursă, imaginile etc. preluate din proiecte open-source sau
alte surse sunt utilizate cu respectarea drepturilor de autor și dețin
referințe precise;
rezumarea ideilor altor autori precizează referința precisă la textul
original.
Iași, data
Absolvent: [anonimizat]
_______________________
2

DECLARAȚIE DE CONSIMȚĂMÂNT
Prin prezenta declar că sunt de acord ca Lucrarea de licență cu titlul
„BlueChat – Dezvoltarea unei aplicații de tip chat utilizând XMPP ”,codul
sursă al programelor și celelalte conținuturi (grafice, multimedia, date de
test etc.) care însoțesc această lucrare să fie utilizate în cadrul Facultății de
Informatică.
De asemenea, sunt de acord ca Facultatea de Informatică de la
Universitatea „Alexandru Ioan Cuza” Iași să utilizeze, modifice, reproducă și
să distribuie în scopuri necomerciale programele-calculator, format
executabil și sursă, realizate de mine în cadrul prezentei lucrări de licență.
Iași, data
Absolvent: [anonimizat]
_________________________
3

Cuprins
Introducere………………………………………………………………………………………………………………… 5
Context…………………………………………………………………………………………………………………. 5
Motivație………………………………………………………………………………………………………………. 5
Contribuții…………………………………………………………………………………………………………….. 6
Capitolul 1: Dezvoltarea aplicației client ……………………………………………………………………….. 7
1.1 Arhitectura aplicației …………………………………………………………………………………………. 7
1.2 Implementare………………………………………………………………………………………………….. 12
1.2.1 Conectarea utilizatorului …………………………………………………………………………… 12
1.2.2 Preluarea listei de prieteni …………………………………………………………………………. 13
1.2.3 Prezența………………………………………………………………………………………………….. 14
1.2.4 Trimiterea/Tratarea cererilor de prietenie …………………………………………………….. 14
1.2.5 Trimiterea/Primirea mesajelor ……………………………………………………………………. 15
1.2.6 Stările conversației …………………………………………………………………………………… 15
1.2.7 Ultima activitate ………………………………………………………………………………………. 16
1.3 Interfața aplicației client …………………………………………………………………………………… 16
1.3.1 Componenta părinte ………………………………………………………………………………….. 16
1.3.2 Fereastra Tabs ………………………………………………………………………………………….. 16
1.3.3 Fereastra Conversations …………………………………………………………………………….. 16
1.3.4 Fereastra Friends ……………………………………………………………………………………… 17
1.3.5 Fereastra Friend Requests ………………………………………………………………………….. 18
1.3.6 Fereastra Profile ……………………………………………………………………………………….. 20
1.3.7 Fereastra Chat ………………………………………………………………………………………….. 20
1.4 Tehnologii folosite …………………………………………………………………………………………… 21
1.4.1 AngularJS 2…………………………………………………………………………………………….. 21
1.4.2 Typescript……………………………………………………………………………………………….. 22
1.4.3 Ionic 2…………………………………………………………………………………………………….. 23
1.5 Serviciu Android …………………………………………………………………………………………….. 24
1.5.1 Implementarea notificărilor folosind Firebase Google Cloud Messaging …………25
Capitolul 2: Dezvoltarea serverului …………………………………………………………………………….. 31
2.1 Server TCP…………………………………………………………………………………………………….. 33
2.2 REST API………………………………………………………………………………………………………. 33
2.3 Stocarea datelor ………………………………………………………………………………………………. 35
Capitolul 3: Serverul Ejabberd ……………………………………………………………………………………. 38
3.1 XMPP……………………………………………………………………………………………………………. 39
3.2 Extensii XMPP ……………………………………………………………………………………………….. 40
Concluzii…………………………………………………………………………………………………………………. 42
Referințe………………………………………………………………………………………………………………….. 43
4

Introducere
Context
Mesageria instantă este un tip de comunicare online, ce oferă o transmisie în timp real cu
ajutorul internetului. Mesajele sunt transmise de obicei bidirec ional între două păr i. Unele ț ț
aplica ii folosesc tehnologia ț push pentru a oferi un schimb de mesaje în timp real, trimi ând ț
mesajele caracter cu caracter în timp ce ele sunt compuse. Unele aplica ii mai avansate pot oferi ț
i schimb de fi iere, apeluri peste internet (VOIP), sau apeluri video.ș ș
Ideea de mesagerie are rădăcini încă din anii '90, cu primul mesaj de tip SMS trimis prin
re eaua de telefonie Vodafone, având textul “Merry Christmas”, mesaj trimis în Decembrie ț
1992. După scurt timp, aproximativ 4 ani, firma Mirabilis a lansat prima aplica ie de mesagerie ț
online numind-o ICQ (“”I Seek You”). Aceste două tipuri de mesagerie sunt folosite i astăzi în ș
paralel, cu men iunea că numărul de mesaje trimise folosind aplica ii de mesagerie online ț ț
surclasează în fiecare an numărul de mesaje trimise prin furnizorii de servicii telefonice.
Pâna în anul 2009, când aplica ia WhatsApp a fost lansată, serviciul de mesagerie prin ț
intermediul furnizorilor de servicii telefonice avea monopol. Odată cu avansarea tehnologiei,
cre terea vitezei de internet, acoperirea tot mai largă Wi-Fi, utilizatorii au început tot mai mult ș
să folosească op iunea de a trimite mesaje online, în detrimentul SMS-urilor. Această schimbare ț
a fost datorată i aspectului costisitor în unele ări al serviciului de mesagerie. ș ț
Apogeul serviciului de mesaje a fost în 2012, urmând ca în anul 2013 să fie surclasat de
aplica iile ce trimiteau mesaje prin intermediul internetului, având un pre mai scăzut sau fiind ț ț
chiar gratis. Această diferen ă este redată în numărul de mesaje trimise zilnic. Până în Ianuarie ț
2015 WhatsApp gestiona 30 miliarde de mesaje pe zi în compara ie cu 20 miliarde mesaje ț
trimise prin SMS.
Motivație
Prin dezvoltarea acestei aplica ii am vrut să aduc la cuno tin ă o serie de tehonologii ce ț ș ț
permit implementarea unei aplica ii de tip chat, sau tehnologii ce au o mare influen ă în cadrul ț ț
dezvoltării aplica iilor web sau server. ț
5

Contribuții
Lucrarea este împăr ită în trei capitole, fiecare capitol fiind destinat unei aplica ii ț ț
(server sau client), unde voi face o descriere a procesului de dezvoltare, i voi men iona, unde ș ț
este cazul resursele necesare pentru dezvoltarea acesteia. Capitolele se situează în următoarea
ordine :
●Capitolul 1: Dezvoltarea aplica iei client ț
●Capitolul 2: Dezvoltarea serverului
●Capitolul 3: Serverul Ejabberd1
În capitolele men ionate vor fi prezentate i compara ii între diferite modalită i de a ț ș ț ț
implementa anumite func ionalită i. ț ț
Contribu ia mea în dezvoltarea acestui proiect este implementarea aplica iei de client ț ț
compatibilă atât pe platformele mobile cât i în browser, dezvoltarea aplica iei server, i ș ț ș
configurarea serverului Ejabberd. A fost nevoie de o aprofundare a protocolului XMPP,
protocol ce stă la baza aplica iilor de tip chat. Folosind acest protocol împreună cu extensiile ț
sale am reu it să implementez o aplica ie care oferă informa ii ce îl in pe utilizator antrenat ș ț ț ț
în aplica ie. Următoarele implementări sunt realizate folosind XMPP i extensiile acestuia: ț ș
•Actualizare în timp real al statusul unui prieten, online sau offline.
•Ultimele conversa ii ț
•Informarea utilizatorului asupra stării conversa iei. Atunci când utilizatorul ț
este angajat într-o convorbire, acesta prime te informa ii ce îl semnalează că ș ț
persoana cu care este angajat în convorbire compune un mesaj, sau s-a oprit
din scrierea acestuia.
•Ultima oară când un utilizator a fost activ în aplica ie ț
•Setare avatar i alte informa ii precum numele complet, adresa. ș ț
Pe lângă func ionalită ile men ionate mai sus, aplica ia client dispune i de o interfa ă ț ț ț ț ș ț
intuitivă i placută din punct de vedere vizual. Interfa a este realizată ș ț folosind componente ce
respectă ultimele specifica ii țMaterial Design. Datorită acestei abordări am reu it sa creez o ș
interfa ă compatibilă cu orice dimensiune a ecranului. ț
1https://github.com/processone/ejabberd
6

Capitolul 1: Dezvoltarea aplica iei client ț
Aplica ia are scopul de a da posibilitatea utilizatorilor să trimită mesaje text altor ț
ultilizatori. Interfa a este foarte intuitivă, i va fi descrisă în următoarele subcapitole. ț ș
Deasemenea, în următoarele subcapitole voi descrie arhitectura aplica iei, mediul de dezvoltare ț
i tehnologiile folosite, cu o scurtă compara ie pentru fiecare tehnologie în parte, acolo unde esteș ț
cazul.
1.1 Arhitectura aplicației
Pentru dezvoltarea aplica iei client s-au folosit o serie de tehnologii web ce permit ț
utilizatorului să folosească aplica ia atât pe o platformă mobilă cât i în browser. Aceste ț ș
tehnologii vor fi men ionate pe parcursul lucrării i detaliate în capitolul Tehnologii folosite. ț ș
Structura aplica iei este una simplă, în care fiecare fereastră de navigare este o ț
componentă. Această structură are ca rezultat o modularizare a aplica iei, unde fiecare fereastră ț
are propria sa logică, interfa ă i foaie de stilizare. Mai mult, structurând aplica ia pe ț ș ț
componente este posibilă refolosirea acestora oriunde în aplica ie, lucru ce duce la o dezvoltare ț
rapidă, i satisface principiul dezvoltării software (DRY). ș
Aplica ia dispune i de două servicii Angular, ce vor fi injectate în componentele ce au ț ș
nevoie de ele. Aceste servicii sunt :
•Messages Manager
Serviciu folosit pentru a realiza conexiunea cu serverul Ejabberd, trimitere mesaje,
procesare mesaje primite.
•Chat Storage
Serviciu folosit pentru a executa opera ii cu baza de date (preluare istoric, inserare ț
conversa ii i mesaje). ț ș
Aplica ia dispune i de un serviciu Android ț ș2 pentru procesarea mesajelor primite când
utilizatorul nu are aplica ia deschisă. Serviciul va fi descris pe larg în Capitolul 1.5. ț
Voi descrie succint rolul fiecărei componente urmând ca în capitolul Interfa ă grafică să ț
fac o descriere detaliată împreună cu imagini din aplicație.
•AppComponent
Componenta principală va incapsula componentele cu con inut specific. Interfa a ț ț
componentei rădacină va con ine doar un toolbar ce va avea diferite ac iuni în func ie de ț ț ț
componenta copil afi ată. ș
2https://developer.android.com/guide/components/services.html
7

•TabsComponent
Componenta con ine două taburi : Conversations i Friends. ț ș
•ChatComponent
Fereastra în care este redată conversa ia dintre doi utilizatori. ț
•FriendRequestComponent.
În interiorul acestei componente sunt afi ate cererile de prietenie primite. ș
•ProfileComponent
În această fereastră utilizatorul î i poate schimba poza de profil i/sau alte date ș ș
legate de contul acestuia.
•SettingsComponent
Componenta redă posibilitatea de a schimba anumite setări în aplica ie. ț
În AngularJS[1], o componentă este definită ca fiind un caz special al unei directive
ce folose te o configura ie mai simplă, lucru ce se potrive te cu structura modulară a ș ț ș
aplica iei. ț
8// imports
@Component({
selector: 'app-friends',
templateUrl: './friends.component.html' ,
styleUrls: ['./friends.component.css' ]
})
export class FriendsComponent implements OnInit {
friends : Friend[] = [];
constructor(private router : Router,
public dialog: MdDialog,
private messagesManager : MessagesManager) {
this.friends = []
}
ngOnInit() {
this.friends = this.messagesManager. friends;
}
}
Cod1. Componenta Friends

Componenta FriendsComponent dată ca exemplu con ine clasa FriendsComponent ce ț
implementează interfa a OnInit pentru a putea suprascrie metoda ț ngOnInit apelată atunci când
se ini ializează componenta. Serviciul MessagesManager este injectat în clasă folosind ț
injectarea de dependin e oferită de AngularJS. Pentru ca serviciul să poată fi injectat în diferite ț
componente acesta trebuie adnotat cu @Injectable.
Structura proiectului este o structură standard a aplica iilor dezvoltate folosind Ionic 2. ț
Aceasta se poate realiza utilizând linia de comandă oferită de Ionic 2. Atât linia această de
comandă cât i altele, sau dependin ele aplica iei sunt instalate folosind ș ț ț npm.
Npm este un distribuitor de pachete ce se instalatează o dată cu Node.js. Sintaxa pentru a
instala un pachet este npm install <numele pachetului> . Deoarece o aplica ie poate avea mai ț
multe dependin e nu este comodă instalarea pachetelor unul câte unul. Pentru asta se folose te ț ș
fi ierul șpackage.json. Comanda npm install va căuta fi ierul respectiv i va citi toate pachetele ș ș
din acesta, care mai apoi vor fi instalate în folderul node_modules.
O altă linie de comandă folosită este cordova-CLI, folosită pentru a instala fi ierul apk ș
generat în urma compilării proiectului. Serverul este pornit utilizând comanda node
specificându-i ca parametru calea spre fi ierul ce serve te ca punct de intrare al aplica iei. Alte ș ș ț
comenzi folosite în procesul de dezvoltare sunt :
•ejabberdctl start
•tail -f
•ionic build android
•ionic serve
•cordova plugin install
9//imports
@Injectable()
export class MessagesManager {
// declarații
public constructor (private chatStorage : ChatStorage ,
private platform : Platform) {
this.chatStateEvent = new EventEmitter<string>();
}
}
Cod2. Serviciul Messages Manager

•node_modules este directorul unde sunt instalate bibliotecile AngularJS, Ionic,
Typescript i alte dependin e folosite în aplica ie. ș ț ț
•platforms este directorul ce con ine platformele pe care aplica ia poate fi ț ț
rulată. Momentan con ine platforma android. ț
•plugins con ine codul extensiilor native folosite în aplica ie. ț ț
•resources con ine resursele fiecărei platforme. ț
•src con ine codul sursă al aplica iei. În interiorul acestui director se află ț ț
10Fig 1: Structura aplicației

componentele, serviciile Angular i modelele. ș
•www este directorul ce con ine sursele rezultate în urma compilării aplica iei. ț ț
Are ca intrare un fi ier index.html i fi iereul build.js, fi ier rezultat în urma ș ș ș ș
compilării codului TypeScript în JavaScript.
Entită ile gestionate în aplica ie sunt prietenii, conversa iile, mesajele i cererile de ț ț ț ș
prietenie. Rela iile dintre prieteni – conversa ie i prieten – cerere prietenie sunt de unu la unu. ț ț ș
Rela ia dintre conversa ie i mesaj este de unu la mai mul i.ț ț ș ț
1.2 Implementare
Aplica ia client prezentată în lucrare folose te ț ș StropheJS pentru construirea mesajelor,
care ulterior vor fi trimise serverului Ejabberd. StropheJS este o bibliotecă JavaScript care oferă
obiecte i func ii utilitare pentru a u ura dezvoltarea aplica iilor ce folosesc protocolul de ș ț ș ț
comunicare XMPP. Acestei librării i se pot adăuga i extensii ce aduc func ionalită i noi în ș ț ț
aplica ie. Majoritatea cererilor sunt trimise către serverul Ejabberd iar cererile ce vor fi trimise ț
către serverul Node.js vor fi specificate.
11Fig 2: Diagramă clase

1.2.1 Conectarea utilizatorului
Când utilizatorul acceseaza aplica ia o nouă conexiune este realizată. Serverul ț
Ejabberd este configurat să primească doar o singură conexiune pentru fiecare utilizator, prin
urmare dacă un utilizator accesează aplica ia de pe alt dispozitiv, conexiunea precedentă ț
devine inactivă. Conexiunea se realizează apelând func ia țconnect din interiorul serviciului
MessagesManager .
Func ia țonConnect va fi apelată cu parametrul status ce va con ine statusul ț
conexiunii, i cu parametrul șerror ce va con ine o eroare în cazul în care conexiunea nu a fost ț
realizată cu succes. Dacă conexiunea este realizată cu succes, o serie de func ii vor fi ț
înregistrate pentru a gestiona evenimentele primite de la server.
12/**
* This method will try to connect to ejabberd
* @param user
*/
public connect(user : string) {
this.xmpp_user = user;
this.connection = new Strophe.Connection( this.BOSH_SERVICE);
this.connection.connect(user + '@' + this.XMPP_DOMAIN, this.xmpp_pass,
function(status, error){
this._onConnect.call(this, status, error);
}.bind(this));
}
Cod 3 : Funcția de conectare
this.connection.addHandler((stanza) => {return this. onMessage(stanza)}, null, "message",
null, null, null);
this.connection.addHandler((stanza) => {return this.subscribedStanza (stanza)}, null,
"presence", "subscribed");
this.connection.addHandler((stanza) => {return this.subscribeRequest (stanza)}, null,
"presence", "subscribe");
this.connection.addHandler((stanza) => {return this.userStatusChange (stanza)}, null,
"presence");
this.connection.addHandler(this.iqMessage, null, 'iq', null, null, null);
Cod 4 : Înregistrarea funcțiilor

1.2.2 Preluarea listei de prieteni
După ce conexiunea este realizată cu succes, lista persoanelor care sunt angajate cu
utilizatorul este preluată. Această listă nu reprezintă lista finală de prieteni, prin urmare este
aplicată o filtrare pe câmpul subscription ce va avea valoarea both.
Valoarea câmpului subscription este to atunci când utilizatorul a trimis o cerere de
prietenie care a fost acceptată în timp ce acesta era offline. Prin urmare, se autorizează automat
cererea primită i câmpul șsubscription î i schimbă valoarea în ș both.
1.2.3 Prezența
Totodată după ce conexiunea este realizată cu succes, se trimite o cerere prin care se
semnalează că utilizatorul a devenit online. După trimiterea acestei cereri, to i prietenii acestuia ț
vor fi semnala i cu privire la statusul utilizatorului. Acest mesaj va fi genstionat în func ia ț ț
înregistrată userStatusChange.
1.2.4 Trimiterea/Tratarea cererilor de prietenie
Mecanismul de cerere prietenie nu este clar definit în specifica iile XMPP, prin urmare ț
am decis ca termenul “prieten” să fie descris ca fiind legătura dintre doi utilizatori creată în
urma trimiterii unei cereri de abonare (subscription) de la un utilizator la altul i acceptarea ș
acesteia de către utilizatorul care a primit-o. Pentru a în elege mai bine mecanismul de abonare ț
voi descrie în ca iva pa i cum este realizată legătura de prietenie între doi utilizatori. ț ș
1.John îl adaugă pe Smith ca prieten. În acest moment se trimit serverului Ejabberd
următoarele date :
2.Smith prime te cererea de prietenie i o acceptă. Se trimit serverului următoarele date : ș ș

13<presence to=' John @ domain .co m' type='subscribed'/><presence to='Smith@domain.com' type='subscribe'/> source.filter((friend : any) => friend.subscription == "both")
.subscribe((item : any) => {
let friend = new Friend();
// set values from result
this.dsFriends.push(friend);
});
Cod 5 : Filtrarea listei de prieteni

Din moment ce Smith a acceptat cererea de prietenie se va trimite automat:
3.John prime te cererea de prietenie, dar din moment ce acesta a trimis o cerere, care ș
ulterior a fost acceptată, acceptarea noii cereri se va face automat, iar noul prieten este
adăugat în listă.
În acest moment cei doi utilizatori pot deschide o conversa ie i totodată sunt notifica i ț ș ț
când unul din ei î i schimbă statusul. ș
1.2.5 Trimiterea/Primirea mesajelor
Trimiterea mesajelor este realizată din fereastra Chat. Atunci când un utilizator trimite
un mesaj unui prieten, o cerere cu un mesaj de tipul message este trimisă serverului.
Pentru trimiterea mesajului se folose te extensia șreceipts care adaugă un nou element
mesajului pentru a beneficia de notificări asupra statusului mesajului trimis conform
extensiei XEP-0184 Message Delivery Receipts [2].
Mesajele primite sunt tratate de func ia înregistrată țonMessage unde este primit atât
mesajul trimis de prieten, cât i statusul ultimului mesaj trimis de utilizator. Prin acest status ș
mă refer la : “mesaj primit”. Acest lucru este semnalat prin primirea unui mesaj ce con ine ț
elementul recv împreuna cu id-ul mesajului. Primirea acestei notificări nu redă faptul că
utilizatorul a citit mesajul, ci semnalează faptul că mesajul a fost primit i procesat de către ș
aplica ie. ț
Atât la primirea mesajului cât i la trimitere, se construiesc obiectele de tip ș Message
14<presence to='John@domain.com' type='subscribe'/>
public sendMessage(messageT oSend, to, thread) : Message{
let message : any;
message = $msg({to: to+'@'+this.XMPP_DOMAIN,
from: this.xmpp_user+'@'+this.XMPP_DOMAIN,
type : 'chat',
thread : thread})
.c("body").t(messageT oSend) ;
let id = this.connection.receipts.sendMessage(message);
let sentMessage : Message = new Message();
sentMessage.id = id;
sentMessage.who = "me";
sentMessage.status = "unsent";
sentMessage.text = messageT oSend ;
return sentMessage;
}
Cod 6 : Funcția de trimitere mesaj

i se adaugă conversa iei. Următorul pas este inserarea acestor mesaje în baza de date locală a ș ț
dispozitivului. Inserarea se face doar dacă platforma pe care rulează aplica ia este una Android. ț
1.2.6 Stările conversației
În timpul unei conversa ii utilizatorul prime te notificări cu privire la statusul ț ș
conversa iei. Aceste notificări sunt : ț
•compune mesaj
•s-a oprit din compunerea mesajului
•este sau nu este activ în conversa ie ț
Stările conversa iei sunt emise componentei Chat prin instan a unui obiect de tip ț ț
EventEmitter, iar acest lucru va fi afi at corespunzător în interfa a respectivă. ș ț
1.2.7 Ultima activitate
Atunci când utilizatorul deschide istoricul conversa iei cu un anumit prieten, acesta ț
poate vedea data i ora când respectivul prieten a fost activ în aplica ie. Această func ionalitate ș ț ț
este descrisă de XEP-0012 Last Activity.
După primirea răspunsului este folosit acela i obiect (chatStateEvent) pentru a afi a data ș ș
i ora.ș
15let composing = $(stanza). find('composing');
let paused = $(stanza). find('paused');
let active = $(stanza). find('active');
let error = $(stanza). find('error');
if(!_.isUndefined(composing) && composing. length > 0){
this.chatStateEvent.emit('typing…');
}
else if(!_.isUndefined(paused) && paused. length > 0){
this.chatStateEvent.emit('');
}
else if(!_.isUndefined(active) && active. length > 0){
this.chatStateEvent.emit('online');
}
Cod 7 : Tratarea stărilor primite în chat
public lastOnline(user : string){
var iq = $iq({
type: 'get',
id: 'last1',
to: user+"@"+this.XMPP_DOMAIN })
.c('query', {xmlns: 'jabber:iq:last'});
this.connection.sendIQ(iq);
}Cod 8 : Ultima activitate

1.3 Interfața aplicației client
Pentru a crea o experien ă plăcută utilizatorului, interfa a este creată după standardele ț ț
Material Design3. De i Ionic 2 este într-o versiune beta, componentele oferite sunt mai bine ș
documentate i dezvoltate decât biblioteca Angular Material care la rândul ei este într-o ș
versiune beta.
1.3.1 Componenta părinte
După cum am men ionat anterior, App Component este componenta părinte, i ț ș
con ine componenta <ion-nav> ce are ca pagină rădăcină componenta TabsComponent.ț
▪Accesarea ferestrei Friends Requests, unde utilizatorul poate vedea cererile de
prietenie primite
▪Accesarea meniului, cu op iunile de a naviga în fereastra destinată profilului. ț
1.3.2 Fereastra Tabs
Această fereastră este structurată sub formă de taburi, oferind o navigare rapidă în
interiorul aplica iei între diferite ferestre. Utilizatorul are op iunea de a naviga între fereastra ț ț
de Conversations, pentru a vedea conversa iile i fereastra ț șFriends unde sunt afi ati ș
prietenii, împreună cu statusul online sau offline.
1.3.3 Fereastra Conversations
Fereastra Conversations redă lista conversa iilor deschise, unde utilizatorul poate ț
vedea numele prietenului, avatarul acestuia, i un fragment din ultimul mesaj primit sau ș
3https://material.io/guidelines/
16Fig 3: Caz utilizare Componenta Tabs

trimis. Utilizatorul poate deschide conversa ia din această listă. ț
1.3.4 Fereastra Friends
În interiorul acestei interfe e este afi ată lista de prieteni, fiecare intrare având un nume ț ș
i poza de avatar. Utilizatorul poate naviga în fereastra de Chat pentru fiecare prieten în parte, ș
unde poate deschide o nouă conversa ie sau pentru a continua o conversa ie deschisă cu un ț ț
anumit prieten.
Deasemeni există i op iunea de a adăuga un prieten, folosind butonul de adăugare ce va ș ț
fi vizibil în partea dreaptă jos. Butonul este de tip floating i datorită acestui aspect va fi mereu ș
vizibil deasupra listei.
Pentru adăugarea unui prieten este nevoie de numele acestuia, iar dacă utilizatorul este
înregistrat în aplica ie, va primi cererea ce poate va fi procesată din fereastra ț Friend Requests.
17Fig 4: Interfața conversațiilor
Fig 5: Caz utilizare componenta
Conversations

1.3.5 Fereastra Friend Requests
Cererile de prietenie vor fi afi ate în această interfa ă. Utilizatorul poate accepta sau ș ț
18Fig 6: Interfața listei de prieteni
Fig 7: Caz utilizare Friends Component

refuza o cerere de prietenie. Dacă acesta acceptă cererea de prietenie, prietenul este adăugat
automat în lista de prieteni, iar o nouă conversa ie poate fi deschisă. Numărul cererilor ț
neprocesate va apărea în bara de op iuni. ț
Navigând în fereastra Friend Requests, cererile vor fi afi ate într-o listă, iar pentru ș
fiecare, este posibilă una din op iunile: accept sau refuzare. ț
19Fig 8: Notificări
Fig 10: Caz utilizare componenta Friend Request
Fig 9: Interfața listei de notificări

1.3.6 Fereastra Profile
Accesând această interfa ă, utilizatorul î i poate schimba poza de profil. Poza poate fi ț ș
încărcată din galeria telefonului.
1.3.7 Fereastra Chat
Cea mai accesată fereastră din aplica ie este țFereastra Chat. Din acest motiv am
implementat cât mai multe funcționalități pentru a da utilizatorului informații cât mai
detaliate.
•Statusul conversa iei, având următoarele caracteristici: ț
◦Utilizatorul cu care suntem angaja i într-o convorbire compune un mesaj sau nu ț
◦Acela i utilizator a ie it din conversa ie sau încă este activ ș ș ț
•Statusul unui mesaj, având următoarele caracteristici:
◦Mesajul este trimis, primit sau văzut.
20Fig 11: Caz utilizare componenta Chat

Mesajele sunt primite de Roberta, iar acest lucru este afi at pe ultimul mesaj trimis de ș
Alexander. Mai mult acesta poate vedea că Roberta este angajată în convorbire, i compune un ș
mesaj. Prin această informa ie este asigurată o consisten ă a convorbirii, i se poate a tepta ț ț ș ș
mereu un răspuns la o anumită întrebare.
1.4 Tehnologii folosite
Pentru dezvoltarea aplica iei client s-au folosit o serie de tehnologii de actualitate, care ț
oferă atât avantaje dezvoltatorului cât i o experien ă plăcută utilizatorului. ș ț
1.4.1 AngularJS 2
Aplica ia în momentul prezentării folose te versiunea 2.4.1. AngularJS ț ș4 este un
framework în care po i dezvolta aplica ii web, web-mobile, mobile native i desktop native ț ț ș
folosind un singur limbaj de programare, typescript, ce va fi descris în sec iunea 1.4.2. ț
Beneficiile aduse de AngularJS 2 sunt :
4https://angular.io/
21Fig 12: Așteptare mesaj
Fig 13: Primire mesaj

•Folose te un sistem modular introdus de ECMAScript 6 ș5.
•Folose te utilitare moderne pentru a împacheta proiectul, precum ș Webpack sau
SystemJS.
De-a lungul dezvoltării framework-ului s-a folosit pe rând SystemJS, iar mai apoi
Webpack, la care s-a și rămas, cu mențiunea că opțiunea de a configura acest utilitar nu mai
este posibilă deoarece este folosit automat și configurat de AngularJS.
Un alt avantaj oferit de AngularJS este împăr irea aplica iei în componente. Asta duce ț ț
la posibilitatea de a refolosi anumite componente în diferite păr i ale aplica iei. O ț ț
componentă este alcătuită dintr-o clasă având logica componentei, un template i o foaie de ș
stilizare.
1.4.2 Typescript
Typescript[3] este un typed superset al limbajului Javascript, ce este mai apoi
compilat în Javascript pur. Poate fi compilat în orice versiune ECMAScript, începând cu
ECMAScript3, până la ECMAScript6, pentru a oferi suport pentru orice browser sau sistem
de operare. În următoarele două sec iuni de cod voi prezenta versiunea compilată in ț
Javascript a unei clase având un constructor i o metodă; ș
Unele avantaje oferite de Typescript sunt:
•Oferă type safety, asta înseamnă că vor apărea erori la compilare în cazul în care
asignezi valori diferite de tipul la care variabila este declarată. Acela i lucru se aplică i la ș ș
apelarea unor func ii cu parametri de tip diferit. ț
•API clar definit pentru librării. Acest aspect poate fi incorporat i în librăriile ș
dezvoltate in Javascript, adaugându-le fi iere de definire. ș
•Sintaxă asemănătoare cu limbajele de programare orientate obiect (Java, C#).
5http://es6-features.org/
22

Codul scris în Typescript este compilat în JavaScript (ECMAScript5) sau (ECMAScript
6), în func ie de op iunea aleasă. ț ț
1.4.3 Ionic 2
Ionic[4] este un framework utilizat pentru dezvoltarea aplica iilor hibride. Folosind Ionic ț
po i dezvolta aplica ii web care mai apoi pot fi portate pe platforme mobile. Acest lucru este ț ț
asigurat de Apache Cordova. Aplica ia rulează într-o componentă nativă a sistemului de operare, ț
23class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
alert(greeter.greet());
}
document.body.appendChild(button);
Cod 9 : Clasa Typescript
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
}());
var greeter = new Greeter("world");
var button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function () {
alert(greeter.greet());
};
document.body.appendChild(button);
Cod 10 : Codul clasei compilat

spre exemplu în Android este rulată într-un WebView. Se pot accesa în continuare resursele
hardware ale telefonului precum camera folosind extensii, lucru posibil numai implementând
func ionalitatea în limbajul nativ (Java). Unul dintre plugin-urile folosite este serviciul de ț
notificări care este responsabil de afi area mesajelor sub formă de notificări. ș
1.5 Serviciu Android
Serviciul este o componentă care realizează opera ii de lungă durată, fară a oferi o ț
interfa ă utlizatorului. Un serviciu poate fi deschis de o altă componentă, spre exemplu o ț
activitate, i rămâne deschis continuu chiar dacă utilizatorul a navigat într-o altă aplica ie. În ș ț
mod normal Android oferă două tipuri de servicii, cu un comportament diferit în func ie de ț
24Fig 14: Serviciu Android
https://www.tutorialspoint.com/android/android_services.htm

necesitatea aplica iei. Aceste două tipuri sunt : ț
•Service
Aceasta este clasa de bază pentru toate serviciile. Dacă se dore te implementarea unui ș
serviciu folosind această clasă este important ca opera iile să fie executate într-un nou fir de ț
execu ie, deoarece serviciul folose te în mod normal firul de execu ie principal al aplica iei. ț ș ț ț
•IntentService
Acest tip de serviciu este o subclasă a clasei Service ce folose te un fir de execu ie ș ț
pentru a executa opera iile. O altă caracteristică este aceea că acest tip de serviciu se închide ț
automat după ce comanda a fost executată.
În cadrul dezvoltării aplica iei s-a folosit clasa de baza ț Service deoarece este nevoie de
men inerea unei conexiuni persistente între utilizator i serverul ce gestionează mesajele. În ț ș
acest mod se pot implementa i notificări atunci când utilizatorul prime te un mesaj dar acesta ș ș
nu are aplica ia deschisă. Deoarece aplica ia nu este una nativă, este necesară implementarea ț ț
serviciului într-un plugin, care mai apoi va fi instalat în aplica ie. Comanda pentru a instala un ț
plugin într-un proiect Ionic este : ionic plugin add BlueChatServicePlugin.
25

1.5.1 Implementarea notificărilor folosind Firebase Google Cloud
Messaging
26Fig 15: Serviciul Firebase Cloud Messaging
https://firebase.google.com/docs/cloud-messaging/

Firebase Cloud Messaging6 este o platformă ce permite trimiterea de mesaje sau
notificări dispozitivelor. Dacă este folosit cu scopul de a trimite mesaje instant, mărimea unui
mesaj trimis nu poate depă i 4KB. șFirebase Cloud Messaging este folosit pentru a trimite
mesaje utilizatorilor care nu au aplica ia deschisă. Când un mesaj este primit acest lucru va fi ț
semnalizat printr-o notificare, care va con ine numele celui care a trimis mesajul, avatarul i un ț ș
fragment de text.
Pentru a vedea mesajul întreg, sau implicit pentru a naviga în fereastra conversa iei, ț
utilizatorul poate deschide aplica ia apasând pe notificare sau o poate anula. ț
Acest modul folose te două servicii, unul pentru gestionarea notificărilor primite, i unul ș ș
pentru genstionarea cheii primite de la serviciul Firebase.
6https://firebase.google.com/docs/cloud-messaging/
27Fig 16: Notificări mesaje
<service android:name="notification.MessagingService" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="notification.FirebaseInstanceIDService" >
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Fig 17: Înregistrarea serviciilor în AndroidManifest

Serviciul MessagingService extinde FirebaseMessagingServer i suprascrie metoda ș
onMessageReceived pentru a prelua mesajele i ulterior pentru a construi notificarea. ș
Conform documenta iei, o notificare ț7 este un mesaj care poate fi afi at în afară ș
interfe ei grafice a aplica iei. Când i se comunică sistemului Android să construiască o ț ț
notificare, prima dată notificarea apare ca o iconi ă în zona notificărilor. Pentru a vedea ț
detaliile, utilizatorul poate deschide interfa a unde sunt afi ate toate notificările. Aceste două ț ș
zone sunt controlate de sistem i pot fi văzute de către utilizator în orice moment. ș
Notificările implementate folosind acest serviciu au un comportament ce depinde de
starea aplica iei i tipul mesajului trimis de către server. Prin starea aplica iei mă refer la ț ș ț
foreground/background . Prin urmare, dacă aplica ia este în țbackground, asta însemnând că
utilizatorul a ie it din aplica ie sau aplica ia nu mai este vizibilă utilizatorului, notificările vor ș ț ț
fi construite automat de sistemul Android pe baza proprietă ilor mesajului de tip ț notification
primit de la server. Atunci când aplica ia este în țforeground, este vizibilă utilizatorului,
notificările vor fi procesate în metoda suprascrisă onMessageReceived . Aplica ia prezentată ț
în lucrare prime te de la server mesaje de tip ș data ce vor fi procesate în metoda men ionată ț
indiferent de starea aplica iei. Mesajele trimise sunt prezentate în Capitoul 2 : Dezvoltarea ț
serverului. S-a dorit această abordare deoarece notificările sunt personalizate în func ie de ț
numărul mesajelor primite. Pentru a deschide aplica ia apăsând pe notificare un obiect de ț
tipul PendingIntent8 este folosit. PendingIntent con ine descrierea unui Intent ț9 i ac iunile ș ț
acestuia.
Un Intent este o descriere abstractă a unei opera ii ce poate fi executată. Cel mai des ț
este folosit atunci când utilizatorul navighează între activită i, când se dore te pornirea unui ț ș
servciu sau când o componentă se ata ează serviciul respectiv pentru a comunica cu acesta. ș
În Intent este specificată activitatea ce va fi deschisă.
La deschiderea aplica iei, nu se vor prelua mesajele din Intent-ul folosit de notificare ț
deoarece acestea vor fi trimise de serverul Ejabberd în mod automat după conectare. Acest
lucru este datorat faptului că mesajele trimise utilizatorilor offline sunt salvate în baza de date
proprie a serverului. Mesajele primite vor fi procesate în acela i fel ca atunci când utilizatorul ș
este angajat într-o conversa ie. ț
7https://developer.android.com/guide/topics/ui/notifiers/notifications.html
8https://developer.android.com/reference/android/app/PendingIntent.html
9https://developer.android.com/reference/android/content/Intent.html
28

Serviciul FirebaseInstanceIDService extinde serviciul FirebaseInstanceIdService i are ș
ca scop procesarea id-ului trimis de platforma Firebase. Acest identificator este unic pentru
fiecare instan ă a aplica iei, i este folosit ca un mecanism de autentificare i autorizare a unor ț ț ș ș
ac iuni, în cazul aplica iei prezentate trimiterea de notificări. Este nevoie de implementarea ț ț
acestui serviciu deoarece în unele cazuri acest identificator poate fi regenerat.
29private void buildNotification(String message){
NotificationCompat.Builder builder = new NotificationCompat.Builder( this);
ArrayList<String> messages = MessagesContainer. getInstance().getMessages();
messages.add(0, message);
NotificationCompat.InboxStyle notStyle = new NotificationCompat.InboxStyle() ;
if(messages.size() > 1){
notStyle.addLine(messages.get(messages.size() – 1));
notStyle.addLine(messages.get(messages.size() – 2));
}
else if(messages.size() == 1){
notStyle.addLine(messages.get( 0));
}
int moreMessage = messages.size() – 2;
if(moreMessage > 0){
notStyle.setSummaryT ext( "+"+moreMessage+ " more");
}
notStyle.setBigContentTitle( "BlueChat");
String title = "BlueChat";
String contentT ext = "You have "+messages.size()+ " new ";
contentT ext += messages.size() == 1 ? "message" : "messages";
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT );
builder.setContentTitle(title)
.setContentT ext(contentT ext)
.setStyle(notStyle)
.setContentIntent(resultPendingIntent)
.setSmallIcon(R.drawable. icon)
.setGroupSummary( true)
.setAutoCancel(true)
.setGroup("group");
Notification notification = builder.build() ;
NotificationManagerCompat mNotifyManager =
NotificationManagerCompat. from(this.getApplicationContext()) ;
mNotifyManager.notify( 123456, notification);
}
Fig 18: Construirea notificării

Cazurile în care identificatorul este regenerat de platforma Firebase sunt:
•Aplica ia terge ID-ul ț ș
•Utilizatorul dezinstalează/reinstalează aplica ia ț
•Utilizatorul terge manual datele aplica iei. ș ț
Deoarece acest ID se poate schimba în urma unui scenariu prezentat este nevoie ca
acesta să fie salvat în baza de date a serverului Node.js. Pentru trimitea cererilor este folosită
biblioteca Volley sugerată de documenta ia Android. Conform acesteia, Volley este o ț
biblioteca HTTP cu sursă deschisă ce face comunicarea cu serverul mai u oară i mai rapidă. ș ș
Biblioteca se adaugă proiectului prin definirea dependin ei în interiorul fi ierului gradle ț ș
astfel:
30dependencies {

compile 'com.android.volley:volley:1.0.0'
}

Capitolul 2: Dezvoltarea serverului
Din moment ce serverul nu are de făcut opera ii intensive s-a decis alegerea unui server ț
Node.js10, implementat în framework-ul Express. Unul din avantajele acestui server este acela că
suportă un număr mare de conexiuni simultane, lucru crucial într-o aplica ie de tip chat. ț
Rezultatele unor teste arată că un server Node.js poate procesa mai multe cereri fa ă de un server ț
scris în PHP say Python. Acest tip de server este u or de configurat, i poate fi rulat pe orice ș ș
sistem. Serverul are următoarele func ionalită i: ț ț
•Notificarea utilizatorilor cu privire la statusul mesajului. În acest caz mă refer la
un mesaj care a fost citit.
•Înregistrarea utilizatorilor.
•Salvarea mesajelor trimise.
•Procesarea mesajelor trimise unui utilizator offline.
Pentru a realiza aceste functionalită i este necesar ca serverul să poată accepta conexiuni ț
TCP din partea utilizatorilor, dar i de a oferi un API REST, folosit de aplica ia client i serverul ș ț ș
Ejabberd. Serverul ejabberd împreună cu configurările necesare vor fi descrise detaliat în
Capitolul 3.
Express11 este framework-ul standard pentru dezvoltarea aplica iilor web sau a ț
interfe elor aplica iilor, sursa acestuia fiind deschisă. Comportamentul serverului, cererile pe ț ț
care acesta le poate procesa sunt definite în Express sub formă de rute (routes).
Pe lângă caracteristicile men ionate, serverul Node.js este folosit i ca un server proxy. ț ș
Conform paginei Wikipedia, un server proxy este un server ce se comportă ca un intermediar
pentru cererile de la un anumit client, cautând resurse în alte servere. Acest ablon de proiectare ș
este folosit atunci când utilizatorul dore te să se înregistreze la serverul Ejabberd. În procesul de ș
înregistrare aplica ia nu va trimite o cerere direct serverului Ejabberd, ci mai întai va trimite o ț
cerere serverului Node.js urmând ca acesta să trimită cererea de înregistrare după ce verificările
au fost terminate cu succes.
10https://nodejs.org/en/
11http://expressjs.com/
31

Serverul Ejabberd este configurat ca atunci când se dore te trimiterea unui mesaj către ș
un utilizator care are statusul offline(nu este connectat în aplica ie), mesajul trimis să fie ț
redirec ionat către serverul Node.js. Acest lucru este asigurat de compilarea i instalarea ț ș
modulului mod_offline_post. Compilarea modulului se realizează rulând comanda
următoare:
Asupra acestui modul scris în limbajul Erlang am venit cu modificări în apelul
func iilor ce parsează mesajele XML deoarece generau erori, motivul fiind folosirea unor ț
func ii ce nu mai erau suportate în noua versiune a serverului.ț
32Fig 19: Trimitere mesaj unui utilizator offline
erlc -I /lib/ejabberd-0.0/include/ -pa [path_to_ejabberd_src]/ejabberd-master/deps/lager/ebin/
[path_to_module]/mod_offline_post.erl

Acest mecanism face posibilă trimiterea mesajelor prin intermediul platformei Firebase Cloud
Messaging.
2.1 Server TCP
Protocolul de control al transmisiei este un protocol folosit de obicei de aplicații care au
nevoie de confirmare de primire a datelor. Efectuează o conectare virtuală full duplex între două
puncte terminale, fiecare punct fiind definit de către o adresa IP și de către un port TCP.
În acest scop am folosit librăria socket.io care permite conectarea unui client la un server
pentru a primi pachete în timp real.
2.2 REST API
Folosind Express, putem defini foarte simplu modul în care aplica ie server răspunde ț
cererilor trimise de clien i, prin folosirea țrutelor.
Rutele serverului sunt apelate atât de aplica ia client cât i de serverul Ejabberd pentru a ț ș
trimite mesaje.
33Fig 20: Înștiințare mesaj
app.METHOD(PATH, HANDLER)
•app – instanța extensie Express
•METHOD – una din metodele HTTP
•PATH – cale server
•HANDLER – funcția ce va fi executată atunci
când ruta este potrivită

Înregistrarea utilizatorului este realizată atunci când serverul prime te o cerere de la ș
client. Această cerere va fi validată i procesată, iar mai apoi serverul va returna un răspuns ș
după ce va face o cerere de înregistrare a utilizatorului la serverul Ejabberd. Este nevoie de
instalarea i configurarea modulului ș mod_rest pentru a face posibilă trimiterea mesajelor sau
a unor comenzi folosind cereri HTTP [5]. Pentru a trimite cererea se folose te modulul node ș
request12, i un obiect Promise va fi returnat.ș
Pentru a implementa func ionalitatea de notificare a utilizatorilor când ace tia sunt ț ș
offline modulul mod_offline_post este instalat i configurat pe serverul Ejabberd. În acest fel ș
mesajul este redirec ionat i o cerere către serverul Node.js este făcută. După primirea ț ș
mesajului se caută id-ul aplica iei pentru utilizatorul respectiv. Dacă a fost găsit id-ul o cerere ț
ce con ine următoarele date va fi fâcută serverului Firebase. Tipul mesajului trimis este de tip ț
data deoarece nu se dore te ca sistemul să genereze automat notificarea. Acest lucru se poate ș
face schimbând tipul mesajului din data în notification13.
12https://github.com/request/request
13https://firebase.google.com/docs/cloud-messaging/concept-options
34router.post('/register', function(req, res){

});
Cod 19 : Ruta Express
function registerUser(user){
var dfd = P.defer();
var command = "register "+user+" localhost pass";
var commandLength = _. size(command);
var httpOptions = {} ;
httpOptions.url = cfg.jabberdCredentials .urlEjabberdRest;
httpOptions.method = "POST";
httpOptions.headers = {
"Content-Length" : commandLength ,
"Content-T ype" : 'text/html; charset=utf-8'
};
httpOptions.body = command;
makeRequest(httpOptions).done(dfd.resolve, dfd.reject);
return dfd.promise;
}
Code 20 : Funcția de înregistrare

2.3 Stocarea datelor
Pentru stocarea datelor s-a folosit baza de date SQLITE14 oferită de Android. Interogările
se fac folosind extensia cordova-sqlite-storage 2.0.1. SQLite este o bază de date SQL cu sursă
deschisă, ce salvează datele în fi iere text. Spre deosebire de alte baze de date SQL, aceasta nu ș
are un proces server separat, ci este rulată pe orice dispozitiv.
În baza de date sunt salvate conversa iile i istoricul acestora, pentru a fi afi ate imediat ț ș ș
14https://www.sqlite.org/
35var data = {
body : body.body,
title : body.from,
tag : 'bluechat'
};
var fcmOptions = {
url: 'https://fcm.googleapis.com/fcm/send' ,
method: 'POST',
body : JSON.stringify({
data : data,
to : firebaseId,
collapse_key : "chat"
}),
headers: {}
};
var headers = {
'authorization': 'key='+SERVER_KEY ,
'content-type': 'application/json'
};
fcmOptions.headers = headers;
Cod 21 : Datele trimise în notificare
Fig 21: Entitățile salvate în baza de date

la deschiderea aplica iei. Logica comunicării cu baza de date este incapsulată în serviciul ț
Angular : storage, care la rândul lui folose te extensia io.sqlc, ce rulează cod nativ Android, ș
i este injectat oriunde este nevoie de el.ș
“Obiectul Promise15 este folosit pentru opera iile asincrone. Un Promise reprezintă o ț
valoare ce va putea fi folosită la momentul curent, în viitor sau niciodată”. Un Promise are
trei stări :
•pending – starea ini ială ț
•fulfilled – opera ia s-a terminat cu succes ț
•rejected – opera ia nu a fost reu ită ț ș
Apelarea func iei țexecuteSql va întoarce un Promise ce va fi folosit ulterior pentru
preluarea rezultatului.
15https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
36this.chatStorage.getConversations ()
.then((result) => {
if(result.rows.length > 0){
for(let i = 0; i < result.rows.length; i++){
let conversation : Conversation = new Conversation();
conversation.thread = result.rows.item(i).threadId;
let friend : Friend = new Friend();
// Get messages for conversations
friend.name = result.rows.item(i).friend;
conversation.friend = friend;
self.chatStorage.getMessages(conversation.thread)
.then(result => {
if(result.rows.length > 0){

// Construire mesaje
}
self.dsConversations.push(conversation);
});
}
}
})
Cod 23 : Prelucrarea conversațiilorpublic getConversations () : Promise<any>{
if(this.db == undefined) return;
return this.db.executeSql("SELECT * FROM conversations" , {});
}
public getMessages(threadId : string) : Promise<any>{
return this.db.executeSql("SELECT * FROM messages WHERE threadId = '" +threadId+"'", {});
}
Cod 22 : Preluare lista conversații

Pe serverul node sunt salvate id-urile aplica iei generate de Firebase Cloud Messaging ț
împreuna cu utilizatorul înregistrat pe serverul Ejabberd. Aceste date sunt salvate într-un fi ier ș
JSON. Datele sunt preluate atunci când se trimit notificări utilizatorilor cu statusul offline.
Aceste entită i sunt citite din fi ier folosind modulul ț ș npm, File System16
16https://nodejs.org/api/fs.html#fs_file_system
37{
user : "user înregistrat în serverul Ejabberd" ,
firebaseID : "id-ul aplicației instalate generat de Firebase"
}
Cod 24 : Entitate utilizator pe server

Capitolul 3: Serverul Ejabberd
Ejabberd este un server destinat dezvoltării aplicațiilor de tip chating. Protocolul de
comunicare este bazat pe XMPP(Extensible Messaging and Presence Protocol). XMPP este
cel mai securizat protocol de mesagerie. Este folosit de multe aplica ii cunoscute, precum ț
Messenger (Facebook), WhatsApp, acestea având versiuni personalizate de server jabberd.
O alta alternativă de a integra un server bazat pe acest protocol este Moongoseim.
Diferen a care a adus la alegerea serverului Ejabberd a fost documenta ia detaliată i ț ț ș
sumedenia de surse disponibile pentru a duce la sfâr it proiectul. Deasemeni comunitatea ș
mare ajută la optimizarea codului i implementarea noilor protocoale care apar în urma ș
descoperirii unor noi func ionalită i sau îmbunătă irea uneia deja existente. În continuare voi ț ț ț
face o scurtă compara ie între cele două. ț
Ejabberd:
•Avantaje
◦Comunitate mare i documenta ie detaliată ce con ine exemple de configuare sau ș ț ț
modificare server
◦Administrare web. Ejabberd oferă o pagină de administrare web, unde po i realiza ț
opera ii CRUD asupra conturilor, domeniilor, po i vizualiza statusul fiecărui ț ț
utilizator.
◦CLI. Ejabberd oferă i o interfa ă linie de comandă pentru a rula comenzi ce ș ț
reproduc opera iile men ionate în modulul de administrare web. ț ț
• Dezavantaje
◦Versiunea gratuită a acestui server nu este optimizată pentru proiecte mari.
Mongooseim:
•Avantaje
◦Este optimizat pentru proiecte mari
◦Cod mai clar pentru cei ce vor sa facă ajustări sau modificări personalizate, sau
chiar dezvoltări ulterioare.
•Dezavantaje
◦Nu are interfa ă web pentru administrare ț
◦Comunitatea nu este a a mare iar sursele de documenta ie nu sunt accesibile. ș ț
38

Ejabberd are o structură modulară, lucru ce face ca integrarea unor noi module să fie cât
mai simplă. Pentru a vedea întreaga listă de module disponibile pentru instan a de Ejabberd se ț
executa comanda ejabberdctl modules_available. Pentru dezvoltarea aplica iei au fost nevoie de ț
trei module:
•mod_offline_post – interceptarea mesajelor către utilizatorii offline.
•mod_post_log – loghează mesajele la un API HTTP.
•mod_rest – folosit pentru înregistrarea unui utilizator.
Configurarea modulelor se face în fi ierul de configurare ș ejabberd.yml. În interiorul
acestui fi ier se poate modifica i lista de acces, pentru fiecare domeniu în parte, sau setarea ș ș
userului administrator.
3.1 XMPP
Protocolul de comunicare dintre aplica ia client i serverul Ejabberd este XMPP ț ș [6].
XMPP este un protocol cu sursă deschisă bazat pe standardul XML i fost dezvoltat original în ș
comunitatea Jabber, iar prima tehnologie Jabber/XMPP a fost dezvoltată in anul 1998 de
Jeremie Miller. Acest protocol are i o serie de extensii denumite XEP, dezvoltate după ș
standardul XMPP (XSF).
Următoarele extensii sunt folosite în aplica ia client : ț
•XEP-0012 : Last Activity
•XEP-0085 : Chat State Notifications
•XEP-0184 : Message Delivery Receipts
•XEP-0206 : XMPP Over BOSH [7]
39modules :
mod_post_log:
url: "http://localhost:3000/notification/history"
mod_offline_post:
auth_token: "offline_post_auth_token"
post_url: "http://localhost:3000/notification/offline"

3.2 Extensii XMPP
XMPP Standards Foundation (XSF) [8] publică o serie de documente adiționale
cunoscute ca XMPP Enhancement Proposals (XEPs) [9] ce descriu o activitate și oferă un
format standard pentru folosirea respectivei activități.
Extensia Chat State Notification [10] oferă informa ii cu privire la stare unei ț
conversa ii. ț
         
 o (start)    
               |
               |
INACTIVE <­­> ACTIVE <­­> COMPOSING <­­> PAUSED
   |                                        |
   |                                       |
+­­­<­­­<­­­<­­­<­­­<­­­<­­­<­­­<­­­<­­­+
Când un utilizator începe sa compună un mesaj, acesta va trimite:
<message>
   from='romeo@montague.net/orchard'             
to='juliet@capulet.com/balcony'
type='chat'>
  <thread>act2scene2chat1 </thread>
  <composing xmlns='http://jabber.org/protocol/chatstates' />
</message>
Când acela i utilizator nu mai compune, se va trimite notificarea ș paused.
<message 
 from='romeo@montague.net/orchard'  
 to='juliet@capulet.com/balcony'
 type='chat'>
 <thread>act2scene2chat1 </thread>
 <paused xmlns='http://jabber.org/protocol/chatstates' />
</message>
Extensia Last Activity[11] este folosită pentru a oferi utilizatorul informa ii cu privire ț
la momentul în care un alt utilizator a fost online. Această informa ie poate fi redată sub tipul ț
dată, sau un număr de minute.
Pentru a ob ine această informa ie se va trimite: ț ț
40

<iq from='romeo@montague.net/orchard'
id='last1'
to='juliet@capulet.com'
type='get'>
<query xmlns='jabber:iq:last' />
</iq>
La primirea acestei cereri serverul va răspunde cu numărul de secunde sau o eroare dacă
este cazul.
<iq from='juliet@capulet.com'  
id='last1'
to='romeo@montague.net/orchard'
type='result'>
<query xmlns='jabber:iq:last'  seconds='903'/>
</iq>
Extensia Message Delivery Receipts oferă func ionalitatea de a primi statusul mesajului ț
trimis. După cum am men ionat, extensia bibliotectii ț StropheJs (receipts) este folosită pentru a
adăuga un element nou mesajului.
<message
from='northumberland@shakespeare.lit/westminster'
id='richard2­4.1.247'
to='kingrichard@royalty.england.lit/throne' >
<body>My lord, dispatch; read o'er these articles. </body>
<request xmlns='urn:xmpp:receipts' />
</message>
Elementul <request> este adăugat mesajului pentru a semnala clientul cu care
comunicăm că se dore te primirea statusului când acesta a fost primit. Atunci când este primit ș
un mesaj de acest gen clientul care a primit mesajul va răspunde cu :
<message
from='kingrichard@royalty.england.lit/throne'
id='bi29sg183b4v'
to='northumberland@shakespeare.lit/westminster' >
<received xmlns='urn:xmpp:receipts'  id='richard2­4.1.247' />
</message>
41

Concluzii
În această lucrare au fost prezentate atât tehnologiile necesare implementării unei
aplica ii de tip chat cât i arhitectura din spatele aplica iei. ț ș ț
Pe parcursul dezvoltării aplica iei client nu au fost întâmpinate probleme, motivul ț
fiind documenta ia elaborată cu privire la framework-urile i librăriile folosite. Testarea este ț ș
rapidă pentru că aplica ia poate fi rulată i într-un browser, iar modificările aduse acesteia ț ș
sunt redate imediat. În tot acest timp s-au folosit i alte aplica ii de mesagerie precum Pidgin ș ț
sau Psi, pentru a testa func ionalită ile de trimitere mesaje, trimiterea statusului utilizatorului ț ț
i statusul conversa iei, func ionalită ile de trimitere cerere prietenie i acceptarea acestora.ș ț ț ț ș
În lucrare a fost prezentat i protocolul ce stă la baza unei aplica ii de tip chat i ș ț ș
extensiile sale ce oferă o sumedenie de op iuni pentru a reda utilizatorului informa ii rapide i ț ț ș
precise.
În momentul de fa ă aplica ia poate fi folosită pentru a schimba mesaje cu al i ț ț ț
utilizatori i următoarele îmbunătă iri pot fi aduse: ș ț
•Implementarea unui server Asterisk pentru func ionalitatea de apeluri. ț
•Implementarea unui server jabberd customizat pentru performan ă sau utilizarea ț
serverului Ejabberd în varianta comercială.
•Implementarea serviciului de notificări i pe alte platforme mobile. ș
42

Referințe
1: AngularJS,
https://angular.io/docs/ts/latest/
2: Peter Saint-Andre, Joe Hildebrand, XEP-0184: Message Delivery Receipts, 2011
3: Typescript
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md,
4: Ionic 2,
http://ionicframework.com/docs/v2/intro/installation/,
5: R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee ,
Hypertext Transfer Protocol, 1999
6: P. Saint-Andre, Internet Engineering Task Force (IETF), 2011
7: Ian Paterson, Peter Saint-Andre, Lance Stout, Winfried Tilanus, XEP-0206: XMPP Over
BOSH, 2014-04-09
8: XMPP Standards Foundation, https://xmpp.org/about/xmpp-standards-foundation.html,
9: XMPP Extensions, https://xmpp.org/extensions,
10: Peter Saint-Andre, Dave Smith, XEP-0085: Chat State Notifications, 2009
11: Jeremie Miller, Thomas Muldowney, Peter Saint-Andre, XEP-0012: Last Activity, 2008
43

Similar Posts