Leopold–Franzens–Universität Innsbruck Improvement of XMPP

Transcription

Leopold–Franzens–Universität Innsbruck Improvement of XMPP
Leopold–Franzens–Universität
Innsbruck
Institut für Informatik
Forschungsgruppe DPS
(Distributed and Parallel Systems)
Improvement
of XMPP support in ECF
Bachelorarbeit
Betreuer: Max Berger
Roland Matha’ (0615172)
[email protected]
Innsbruck
28. Jänner 2010
Zusammenfassung
In dieser Arbeit wird das Einbinden neuer Funktionalitäten in ein bereits bestehendes Projekt (ECF) beschrieben. Einerseits werden die Begriffe XMPP,
SmackAPI ,ECF und Link-Local-Messaging(XEP-0174) erklärt und deren Funktionsweise beschrieben. Andererseits wird die Implementierung eines Link-Lokal-Clients beschrieben. Dabei wird auf Probleme bei der Einbindung, sowie auf
weiterführende Erweiterungen eingegangen.
Inhaltsverzeichnis
1. Einleitung
1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2. Ziel der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3. Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
2
2
2
2. XMPP
2.1. Was ist XMPP? . . . . . . . . . . . . . .
2.2. Kommunikation über XMPP . . . . . .
2.2.1. Jabber-ID . . . . . . . . . . . . .
2.2.2. XML-Stream und XML-Stanzas
2.3. Bestehende Ansätze . . . . . . . . . . .
2.3.1. SmackAPI . . . . . . . . . . . . .
2.4. Zusammenfassung . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
4
5
5
7
7
8
3. SmackAPI 2.2 im ECF updaten
3.1. Was ist ECF? . . . . . . . . . .
3.2. Problemstellung . . . . . . . . .
3.3. Neuerungen von SmackAPI 3.1
3.4. Integration ins ECF . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
. 9
. 9
. 9
. 10
4. Link-Local Messaging (XEP-174)
4.1. Was ist Link-Local Messaging?
4.1.1. DNS Reords . . . . . . .
4.1.2. TXT Record . . . . . .
4.1.3. Nachrichtenaustausch .
4.2. Bestehende Ansätze . . . . . .
4.3. Problemstellung . . . . . . . . .
4.4. Verwendete Ansätze bzw. APIs
4.4.1. DNS-SD . . . . . . . . .
4.4.2. Eclipse-Plugin . . . . .
4.4.3. SAXParser . . . . . . .
4.5. Implementierung . . . . . . . .
4.5.1. BonjourRosterView . .
4.5.2. Chat . . . . . . . . . . .
4.5.3. ChatManager . . . . . .
4.6. Zusammenfassung . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
11
12
13
13
13
14
14
15
16
16
16
17
18
19
5. Zusammenfassung und Ausblick
20
5.1. Vorschläge zur Erweiterung . . . . . . . . . . . . . . . . . . . . . 20
iv
Literaturverzeichnis
22
A. Anhang
23
A.1. Aufbau des Eclipse Workbench . . . . . . . . . . . . . . . . . . . 23
Abbildungsverzeichnis
2.1. Jabber-Netzwerk mit Transport zu ICQ/AIM . . . . . . . . . . .
4
A.1. Aufbau des Eclipse Workbench [4] . . . . . . . . . . . . . . . . . 23
1
1. Einleitung
Das Chatten über ICQ erfreut sich bereits seit einigen Jahren großer Beliebtheit. Die Entwicklung und Verbesserung solcher Chatprotokolle ist aber noch
lange nicht am Ende und so gibt es ständig Neuerungen.
Eines der aktuellsten Protokolle für Instant Messaging(IM) ist sicherlich XMPP.
Es ist einfach zu handhaben und es ermöglicht das Chatten mit proprietären
Netzwerkprotokollen, wie etwa ICQ, ohne zusätzlichen Aufwand für den Chatclient. Dafür sorgen so genannte Transports am Server, d.h. der Client muss
”nur” XMPP-fähig sein und der Jabber-Server verarbeitet bzw. übersetzt die
Nachrichten und leitet sie richtig weiter.
1.1. Motivation
XMPP ist mithilfe einer API (SmackAPI) bereits im Eclipse Communication Framework (ECF) integriert und voll funktionsfähig. Das ECF ermöglicht
ebenfalls das Chatten mit anderen bekannten Chatprotokollen, wie MSN, IRC,
... allerdings fehlt noch eine aktuelle Erweiterung, das so genannte Link-LocalMessaging.
Link-Local-Messaging vereint die Stärken beider Techniken Zeroconf (Apples
Name: Bonjour, ehemals Rendezvous), für die Service Discovery, und XMPP,
für den eigentlichen Nachrichtenaustausch, in sich. Link-Local-Messaging hat
deshalb den großen Vorteil, dass es serverlos arbeitet und nur ein Benutzernamen ausgewählt werden muss, um bereits mit jedem anderen Client, der im
lokalen Netz als Chatclient sichtbar ist, kommunizieren zu können.
1.2. Ziel der Arbeit
Ziel dieser Arbeit ist einerseits der Austausch der alten SmackAPI 2.2 durch
die neue SmackAPI 3.1 im ECF. Andererseits besteht der Hauptteil der Arbeit
darin einen Link-Local-Client zu schreiben und diesen, unter Verwendung der
bereitgestellten Komponenten des ECF, ins ECF zu integrieren.
1.3. Gliederung
Die Arbeit ist in folgende Kapitel gegliedert:
Kapitel 2 erläutert den Begriff XMPP, beschreibt die Kommunikation über
XMPP und gibt einen Überblick über bereits bestehende Ansätze
2
1.3 Gliederung
Kapitel 3 beschreibt den Begriff ECF, die Neuerungen in SmackAPI 3.1 gegenüber der alten Version und geht auf den Austausch der SmackAPI im
ECF ein.
Kapitel 4 demystifiziert den Begriff ”Link-Local-Messaging”, beschreibt dessen
Funtionsweise, geht kurz auf bereits bestehende Ansätze ein und erläutert
die eigentliche Implementierung. Die für die Implementierung benötigten
APIs, wie beispielsweise DNS-SD werden ebenfalls angeschnitten. Am Ende werden noch zusätzliche Vorschläge zur Erweiterung der Applikation
gegeben.
3
2. XMPP
Mit der steigenden Zahl an verschiedenen Chatprotokollen werden serverübergreifende
Protokolle immer wichtiger. Eines, der aktuellsten serverübergreifenden Protokollen ist XMPP.
Im folgenden wird XMPP, dessen Verwendung und Funktionsweise genauer beschrieben. Es werden Begriffe, wie Jabber-ID, XML-Stream und XML-Stanza
erklärt und bereits bestehende Ansätze aufgezeigt. Bei den bereits bestehenden
Ansätzen wird das Augenmerk auf der SmackAPI gerichtet.
2.1. Was ist XMPP?
XMPP (Extensible Messaging and Presence Protocol) ist ein, auf XML basiertes, Nachrichten- und Anwesenheitsprotokoll und wurde 2004 von der IETF1
als RFC 3920-3923 veröffentlicht [10].
Es wird vor allem für Instant Messaging, Mehrbenutzerchat, Zertifikatversendung und Dateiübertragungen zwischen verschiedenen Plattformen verwendet
[10].
2.2. Kommunikation über XMPP
XMPP verwendet zur Kommunikation, ähnlich wie das World Wide Web, ein
Netzwerk aus unzähligen Servern, die eine Vielzahl an Diensten anbieten.
Abbildung 2.1.: Jabber-Netzwerk mit Transport zu ICQ/AIM
Damit XMPP funktioniert muss ein Server einen Jabber-Dienst, wie Ejabbered oder Openfire, anbieten.
1
4
http://www.ietf.org/
2.2 Kommunikation über XMPP
Ein so genannter Jabber-Server(z.B. ”example.org”) kann auch zusätzliche Dienste, wie etwa ICQ oder AIM anbieten. Hierbei wird ein wesentlicher Vorteil
von XMPP ersichtlich, denn ein XMPP-Client (z.B. ”alice”) kann, mithilfe
so genannter Transports (siehe Abb.2.1), mit proprietären NetzwerkprotokollClients (z.B. ICQ) kommunizieren. Die einzige Voraussetzung hierfür ist, dass
der gewählte Server den notwendigen Transport unterstützt.
Der Client selbst verwendet XMPP-fähige Instantmessanger, wie Pidgin oder
Psi, um mit dem Server zu kommunizieren [5, S. 11].
Für die Kommunikation gibt es drei grundlegende Begriffe:
• Jabber-ID: identifiziert den Client eindeutig
• XML-Stream: Datenstrom zwischen Client und Server oder Server und
Server
• XML-Stanzas: gesendete Informationen über einen XML-Stream Im folgenden wird auf die drei Begriffe genauer eingegangen.
2.2.1. Jabber-ID
Damit ein Client sich an einem XMPP-Server registrieren bzw. anmelden kann
und innerhalb des XMPP-Netzwerkes somit eindeutig identifizierbar ist, wurde
ein so genannter Jabber Identifier eingeführt.
Der Aufbau einer Jabber-ID erinnert an den einer E-Mail-Adresse und ist hier
als ABNF (Argumented Backus-Naur Form) aufgeführt [7]:
jid = [ node ”@” ] domain [ ”/” resource ]
domain = fqdn / address-literal
fqdn = (sub-domain 1*(”.” sub-domain))
sub-domain = (internationalized domain label)
address-literal = IPv4address / IPv6address
Hierbei ist ”node” der Node Identifier und steht für den Accountnamen des
registrierten Benutzers. Der Domainname ”domain”, des XMPP-Servers, wird
durch ein ”@” vom Node Identifier getrennt angegeben.
Eine Ressource ”resource” ist optional und kann vom Benutzer frei gewählt
werden. Dadurch ist es möglich ein und den selben Accountnamen von mehreren
Rechnern aus, gleichzeitig zu verwenden, weil der Server nun die verschiedenen
Anmeldestandorte eindeutig unterscheiden kann [7].
2.2.2. XML-Stream und XML-Stanzas
Bisher wurde die Kommunikation in XMPP nur oberflächlich betrachtet. Die
eigentliche Kommunikation funktioniert mit so genannten XML-Streams und
den darin gesendeten bzw. empfangenen XML-Stanzas [7].
5
2 XMPP
XML-Stream ist ein Datenstrom bzw. Socket welches mit dem Start-Tag <stream>
gestartet und mit dem dazugehörigen End-Tag </stream> geschlossen
wird. Innerhalb dieser Tags erfolgt die eigentliche Kommunikation mithilfe so genannter XML-Stanzas [7].
XML-Stanza ist die eigentliche Information, formuliert in XML, die in einem XML-Stream gesendet bzw. empfangen wird. In XMPP gibt es drei
zulässige XML-Stanzas [7]:
• iq: ist eine Info/Query-Stanza und dient für Request/Respons-Anfragen
(z.B. für Rosteranfragen)
• presence: dient dazu den Status (online,away,...) von Chatclients
zu erfragen, sowie den eigenen zu versenden
• message: ist die eigentliche Chatnachricht, welche von den Clients
gesendet und empfangen wird
Listing 2.1: Beispiel eines XML-Streams und der gesendeten Stanzas
<stream>
...
<p r e s e n c e>
<show>xa</show>
<s t a t u s>b i n g e r a d e n i c h t h i e r</ s t a t u s>
</ p r e s e n c e>
...
<message from=” a l i c e @ e x a m p l e . o r g /home”
t o=” a l i c e @ e x a m p l e . o r g / work ”
type=” c h a t ”>
<body>H a l l o</ body>
</ message>
...
<i q type=” g e t ”>
<query xmlns=” j a b b e r : i q : r o s t e r ”>
</ i q>
...
</ stream>
< !−−a−−>
< !−−b−−>
<!−−c−−>
< !−−d−−>
Im obigen Beispiel wird die Kommunikation eines Clients mit dem Server aufgezeigt. Das Beispiel ist nicht vollständig und dient nur zum besseren Verständnis
der eben erklärten Begriffe und der somit verbundenen Arbeitsweise von XMPP.
Bei Position a (siehe Listing 2.1) wird der XML-Stream mit dem entsprechenden Start-Tag gestartet.
Bei Position b sendet der Client seinen eigenen Status mit der XML-Stanza
presence. In diesem Fall wird der Status auf xa, d.h. extended away gesetzt,
wodurch zusätzlich noch eine Textmeldung gesendet werden kann, die den aktuellen Status beschreibt [7].
Bei Position c wird mithilfe der XML-Stanza message eine Nachricht gesendet.
Die eigentliche Nachricht befindet sich dabei im Body-Tag. Damit der Server
die Nachricht richtig weiterleiten kann, müssen die Eigenschaften ”from”, ”to”
und ”type” gesetzt sein, wobei ”from” die JID des Nachrichtensender, ”to”
6
2.3 Bestehende Ansätze
die JID des Nachrichtenempfänger und ”type” den Typ der Nachricht angibt.
Die gebräuchlichsten Message-Typen sind ”groupchat” (Multiuserchat), ”chat”
(Standard-Chat) und ”error” (Fehlernachricht) [7].
Bei Position c stellt der Client eine Anfrage an den Server für den Erhalt seines
Rosters. Der Typ der XML-Stanza ist dabei auf ”get”. Der Client erhält vom
Server daraufhin entweder eine iq vom Typ ”result”, mit den Rostereinträgen
des Clients, oder eine iq vom Typ ”error”, falls ein Fehler aufgetreten ist [7].
In diesem Abschnitt wurden die Begriffe Jabber-ID, XML-Stream und XMLStanza eingeführt und anhand eines Beispiels beschrieben.
2.3. Bestehende Ansätze
Für die Implementierung eines XMPP-Clients gibt es eine Vielzahl an bereits
vorhandenen APIs für die gebräuchlichsten Programmiersprachen. Eine genaue
Auflistung aller bereitgestellten Libraries befindet sich auf der Homepage von
XMPP2 .
Explizit für Java sind bisher folgende APIs verfügbar [1]:
• emite3
• Echomine Feridian
• IP*Works Internet Toolkit4
• Jabber Stream Objects (JSO)5
• Tinder6
• Smack
In dieser Arbeit wird nur auf die SmackAPI eingegangen, weil diese unter der
ASL-Lizenz verfügbar ist und daher im Eclipse bzw. ECF verwendbar ist.
2.3.1. SmackAPI
Die SmackAPI ist eine Open Source XMPP-Client Library von Jive Software,
geschrieben in Java, für Instant Messaging und Presence [8]. Die aktuelle Version ist 3.1.
Smack erleichtert das Senden von Nachrichten über XMPP ungemein. Das folgende Code-Beispiel enthält alle notwendigen Codezeilen um eine Nachricht von
”[email protected]” an ”[email protected]” zu schicken.
2
http://xmpp.org/software/libraries.shtml
http://code.google.com/p/emite/
4
http://www.nsoftware.com/ipworks/
5
https://jso.dev.java.net/
6
http://www.igniterealtime.org/projects/tinder/
3
7
2 XMPP
Listing 2.2: Alice sendet eine Nachricht an Heidi
XMPPConnection c o n n e c t i o n = new XMPPConnection ( ” example . o r g ” ) ;
connection . connect ( ) ;
c o n n e c t i o n . l o g i n ( ” a l i c e ” , ” password ” ) ;
Chat c h a t = c o n n e c t i o n . getChatManager ( ) . c r e a t e C h a t ( ”
heidi@example . o r g ” , new M e s s a g e L i s t e n e r ( ) {
public void p r o c e s s M e s s a g e ( Chat chat , Message message ) {
System . out . p r i n t l n ( ” R e c e i v e d message : ” + message ) ;
}
}) ;
c h a t . sendMessage ( ” H a l l o H e i d i ! LG A l i c e ” ) ;
2.4. Zusammenfassung
In diesem Kapitel wurde der Begriff XMPP erklärt, dessen Funktionsweise beschrieben und bereits bestehende Ansätze analysiert.
Die Kommunikation wurde anhand einer Abbildung und dem Vergleich zum
World Wide Web erklärt. Weiters wurden die, für die Kommunikation grundlegenden, Begriffe Jabber-ID, XML-Stream und XML-Stanza eingeführt und
anhand von Beispielen anschaulich erklärt.
Bei den bereits bestehenden Ansätzen wurde vor allem auf die, in Java verfügbaren,
SmackAPI eingegangen, die auch im folgenden Kapitel (siehe Kapitel 2.4) verwendet wird.
8
3. SmackAPI 2.2 im ECF updaten
Eine Software bzw. API ist nie vollständig fehlerfrei. Obwohl die Hauptfunktionalitäten gewährleistet werden, können trotzdem Bugs im Code enthalten
sein. Diese Bugs werden erst nach der Veröffentlichung, nach und nach, durch
Patches und neue Versionen der Software behoben. Ein Programmierer sollte
deshalb stets darauf bedacht sein die aktuellste Version einer API zu verwenden.
3.1. Was ist ECF?
Das ECF ist ein Opensource Framework, um die Entwicklung von verteilten
Tools und Anwendungen für Eclipse zu erleichtern. Die Verwendung ist Vielseitig und reicht von der Entwicklung anderer Plugins bzw. Tools bis hin zu
vollständigen Eclipse RCP (Rich-Client-Plugin) Anwendungen. Für diese Arbeit ist vor allem wichtig dass ECF einen Chat, auf der Basis von Smack, bietet.
3.2. Problemstellung
Das ECF verwendet eine veraltete Version der SmackAPI für die Kommunikation über XMPP. Die unterstützte Version ist 2.2 und soll auf die Version 3.1
gepatcht werden, weil verschiedene Neuerungen getroffen und Bugs behoben
wurden.
3.3. Neuerungen von SmackAPI 3.1
SmackAPI stellt mit der aktuellen Version 3.1 verschiedene Neuerungen zur
Verfügung. Die gesamten Neuerungen sind im Smack Changelog1 aufgelistet.
In dieser Arbeit wird nur auf eine Auswahl an Updates eingegangen:
• Wichtige Veränderungen:
– Java 5 ist notwendig
– mehrere Updates sind nicht rückwärts kompatibel (z.B. Connection
handling und Klasse Chat)
• Neue Features
– Support für JEP-502 (Ad-hoc commands).
– Das Laden des Rosters während des Logins ist optional
– Mime Typen werden auch für den Avatar verwendet
1
2
http://www.igniterealtime.org/builds/smack/docs/3.1.0.beta1/changelog.html
http://xmpp.org/extensions/xep-0050.html
9
3 SmackAPI 2.2 im ECF updaten
– Mehrere Nachrichten Bodys und Body Sprachen werden unterstützt
– Ein User mit dem Status ”offline” kann einen Statustext hinterlassen.
– Erweiterter Support von Stream Errors: Smack benutzte bis dahin
den, in Jabber-Netzwerken üblichen, Error Format. Mit Version 3.1
die unter http://www.xmpp.org/specs/rfc3920.html#stanzas-error
definierten.
• Bug Fixes
– Entfernen des Status ”unsichtbar”: Der unsichtbare Presence Mode
verletzt die XMPP RFC
– Die Verbindungsgeschwindigkeit wurde erhöht
– DNS Lookups arbeiten nun mit allen DNS Servern: In Version 2.2
wurde noch nach Records vom Typ (type) ”ANY” und der Klasse
(class) ”ANY” gesucht. Ab Version 3.0 wird nach Records vom Typ
”SRV” und der Klasse ”IN” gesucht
– Die Methode ”getPresence” arbeitete nicht korrekt beim Status ”offline”.
3.4. Integration ins ECF
Die Integration der neuen SmackAPI ins ECF erfolgte in mehreren Schritten,
wobei zwischen den Schritten verschiedene Zeitspannen lagen. Damit das Erstellen eines Patchs erst möglich wurde, musste die aktuelle Version des ECF
Projekts über CVS bezogen und die SmackAPI 3.1 in Eclipse importiert werden.
Nach geraumer Einarbeitung wurde der Patch erstellt und, über den Bugtracker von Eclipse und über die Mailing-List des ECF, veröffentlicht.
Die Antwort, dass der Patch durchaus nützlich sei, folgte prompt, jedoch mussten die Lizenzvereinbarungen der SmackAPI erst geklärt werden. Ein halbes Jahr lang passierte nichts, bis einer der Committer die neue Version der
SmackAPI benötigte und den Patch entdeckte. Der Patch wurde schließlich
angewandt und wird vorraussichtlich in der neuen ECF Version verfügbar sein.
10
4. Link-Local Messaging (XEP-174)
Das in RFC 3920 definierte XMPP unterstützt keine serverlose Kommunikation
zwischen den Clients. Erst nach einer Authentifizierung am Server erhält der
Client Zugang zum Jabber-Netzwerk [6].
Für die Kommunikation über ein lokales Netz, ist ein Server in der Regel
überflüssig, weswegen ein neues Protokoll eingeführt wurde.
4.1. Was ist Link-Local Messaging?
Link-Local Messaging vereint die Vorteile des Zeroconfiguration-networking1
mit den Prinzipien von XMPP. Vom Zeroconfiguration-networking wird vor allem die Service Discovery verwendet.
In den folgenden Abschnitten werden die, für die Service Discovery benötigten,
DNS Records beschrieben, wobei auf den TXTRecord genauer eingegangen
wird, und der Nachrichtenaustausch erklärt.
4.1.1. DNS Reords
Ein neuer Client muss sich nicht erst an einem Server anmelden und authentifizieren, sondern muss lediglich vier verschiedene DNS-Records im lokalen Netz
veröffentlichen [6]:
A Record oder Adress Record: IPv4-Adresse des Hosts, der Form:
computer-name.local. A ip-address
SRV Record oder Service Record: angebotener Dienst (Service), der Form:
presence. tcp <ttl> IN SRV <priority> <weight> port-number
[email protected].
PTR Record oder Pointer Record: Domain Name Pointer,um IP-Adressen Namen zuzuweisen, der Form:
presence. tcp.local. port-number IN PTR
username@computer-name. presence. tcp.local.
TXT Record: Freidefinierbarer Text, der Form:
<owner> IN <ttl> TXT ”jid=user-jabber-id”
Der Service Typ ist für Link-Local Messaging ” presence. tcp”. Der Zusatz ”.local.” beschreibt dabei die Beschränkung aufs lokale Netz.
1
http://www.zeroconf.org/
11
4 Link-Local Messaging (XEP-174)
4.1.2. TXT Record
Für einen TXT Record gibt es, zusätzlich zum oben verwendeten Schlüsselwort
”jid”, noch eine Vielzahl anderer nützlicher Attribute. Hier eine Auflistung und
Beschreibung der wichtigsten TXT Records [6]:
1st beschreibt den ersten (first) Namen des Clients
email die E-Mail-Adresse des Benutzers
jid die Jabber-ID des Clients
last der letzte Name des Benutzers
msg eine Textnachricht, welche den aktuellen Status des Users beschreibt
port.p2pj Port des Users. Der Port des Users sollte jedoch nur vom SRV Record
verwendet werden und nicht vom TXT Record.
status kann die Werte ”avail” (online), ”away” (abwesend) und dnd (do not
disturb) annehmen und beschreibt den aktuellen Status des Benutzers
vc dieses Flag beschreibt die Fähigkeiten eines Users zu Audio- und Videokonferenzen. ”A” steht hierbei für Audio, ”V” für Video und ”C” für
Konferenzen mit mehr als einem Teilnehmer. Sollte der User keine der
eben genannten Möglichkeiten bieten wird vc auf ”!” gesetzt.
Listing 4.1: Beispiel aller verwendeten Records [6]
meinpc . l o c a l . A 1 3 8 . 2 3 2 . 9 4 . 9 9
roland@meinpc . p r e s e n c e . t c p . l o c a l . SRV 5598 meinpc . l o c a l .
p r e s e n c e . t c p . l o c a l . PTR roland@meinpc . p r e s e n c e . t c p . l o c a l .
roland@meinpc . p r e s e n c e . t c p . l o c a l . IN TXT
” t x t v e r s =1”
” 1 s t=r o l a n d ”
” e m a i l=r o l a n d . matha@student . uibk . ac . a t ”
” j i d=r o l a n d @ j a b b e r . o r g ”
” l a s t= r o l i ”
”msg=s c h r e i b e g e r a d e ”
” n i c k=r o l i 8 7 ”
” p o r t . p2pj =5677”
” s t a t u s=a v a i l ”
” vc =!”
Das oben gezeigte Beispiel (siehe Listing 4.1) veranschaulicht die verschiedenen
Recordtypen nochmals anhand von Beispielwerten. Dabei beschreibt ”meinpc”
den Rechnernamen und ”roland” den gewählten Chatnamen. Aus diesem Beispiel ist ersichtlich, warum der Port des Users stets vom SRV-Record (5598) genommen werden sollte und nicht vom TXTRecord (5677), weil der im TXTRecord enthaltene Port gefälscht sein kann.
12
4.2 Bestehende Ansätze
4.1.3. Nachrichtenaustausch
Der Nachrichtenaustausch ist stark an den von XMPP angelehnt. Damit eine
Nachricht gesendet bzw. empfangen werden kann, muss zwischen beiden Chatclients eine TCP-Verbindung bestehen. Die dazu notwendigen Informationen,
wie Hostname und Port, werden dabei durch einen Service-Lookup vom Typ
” presence. tcp” erhalten.
Besteht eine TCP-Verbindung muss der XML-Stream vom Aufrufer der Verbindung gestartet werden. Der Aufrufer startet einen neuen Stream mit folgenden
Stream-Header:
<s t r e a m : s t r e a m xmlns= ’ j a b b e r : c l i e n t ’ x m l n s : s t r e a m= ’ h t t p : //
e t h e r x . j a b b e r . o r g / s t r e a m s ’>
Der Empfänger antwortet daraufhin mit einem Respons der Form:
<s t r e a m : s t r e a m xmlns= ’ j a b b e r : c l i e n t ’ x m l n s : s t r e a m= ’ h t t p : //
e t h e r x . j a b b e r . o r g / s t r e a m s ’>
Somit wurde der Stream erfolgreich geöffnet und es können Nachrichten übermittelt
werden. Die Nachrichten besitzen, ähnlich zu XMPP, ein ”to”-Attribut (Empfänger)
und ein ”from”-Attribut (Sender). Ein Beispiel einer solchen Nachricht ist:
<message t o= ’ a l i c e @ e x a m p l e ’ from= ’ heidi@example ’>
<body>H i e r s t e h t d i e N a c h r i c h t</ body>
</ message>
Soll die TCP-Verbindung bzw. der Stream geschlossen und somit der Chat
beendet werden, muss ein Stream-End-Tag übermittelt werden mit folgender
Form:
</ s t r e a m : s t r e a m>
4.2. Bestehende Ansätze
In der SmackAPI existiert bereits eine Link-Local-Messaging Unterstützung.
Allerdings befindet sich diese noch in der Entwicklung und wird frühestens in
der nächsten SmackAPI Version zum Einsatz kommen. Die Klassenhierarchie
innerhalb der SmackAPI ändert sich nicht, weil die Unterstützung durch Modifiezierung bereits bestehender Klassen implementiert wurde [9].
4.3. Problemstellung
Es soll eine Link-Local-Messaging Unterstützung als Eclipse-Plugin geschrieben
werden, die ins ECF integriert werden kann. Die Implementierung soll dabei
möglichst ECF-konform sein, d.h. bereits bestehende Interfaces bzw. Komponenten sollen verwendet werden, um die Integration ins ECF zu erleichtern.
13
4 Link-Local Messaging (XEP-174)
4.4. Verwendete Ansätze bzw. APIs
Für die Implementierung wurden drei bereits bestehende Ansätze verwendet:
• DNS-SD: Damit der Client im Netz sichtbar ist und Kontakte im lokalen
Netz gefunden werden, wird DNS-SD von Apple verwendet
• Eclipse Plugin: Für die Implementierung wurden verschiedene Eclipse
Plugins, vor allem vom ECF, benötigt und das fertige Projekt wird als
Plugin veröffentlicht
• SAXParser: Der Nachrichtenaustausch basiert auf XMPP und somit auf
XML-Streams. Damit Nachrichten richtig geparst werden wird ein SAXParser verwendet.
In den folgenden Abschnitten wird auf die verwendeten Ansätze genauer eingegangen.
4.4.1. DNS-SD
Um das Problem, Namen und IP-Adressen ohne DNS-Server zu übersetzen,
gibt es zwei Lösungsmöglichkeiten für ein Zeroconf-Netzwerk:
• JmDNS (Java Multicast DNS)
• DNS-SD (DNS Service Discovery)
In dieser Arbeit wird nur DNS-SD genauer betrachtet. JmDNS funktioniert
analog.
DNS-SD wurde von Apple entwickelt und ist im Package ”com.apple.dnssd”
enthalten. Eine ausführliche Dokumentation des Packages befindet sich auf der
Entwicklerhomepage von Apple2 . Die Verwendung von DNS-SD ist durch Implementierung der notwendigen Interfaces relativ einfach und übersichtlich gehalten.
Ein Bespiel für die Verwendung von DNS-SD ist die, für die Arbeit geschriebene Klasse LLPresenceDiscover. Diese Klasse dient dazu den Service des Clients
zu registrieren und andere Services im lokalen Netz zu suchen.
Damit ein eigener Service registriert werden kann, reicht der Aufruf der statischen Methode:
public s t a t i c DNSSDRegistration r e g i s t e r ( int f l a g s ,
int i f I n d e x , S t r i n g serviceName , S t r i n g regType ,
S t r i n g domain , S t r i n g host , int port ,
TXTRecord txtRecord , R e g i s t e r L i s t e n e r l i s t e n e r )
throws DNSSDException
Der Wert des Parameters ”flags” wird zur Zeit noch ignoriert und soll erst in
Zukunft unterstützt werden. ”ifIndex” beschreibt das Interface auf welchem der
Service registriert werden soll. Ist ”ifIndex” gleich Null, wird der Service auf
2
http://developer.apple.com/mac/library/documentation/Java/Reference/
DNSServiceDiscovery_JavaRef/com/apple/dnssd/package-summary.html
14
4.4 Verwendete Ansätze bzw. APIs
allen möglichen Interfaces registriert. Der ”serviceName” beschreibt im Falle
von Link-Local-Messaging den Usernamen. ”regType” ist der Registrierungstyp, in diesem Fall immer ” presence. tcp.”. Die anderen Parameter sind selbsterklärend.
Es ist weiters möglich andere Services, vom Typ ”regType”, im Netz zu suchen bzw. nach einem Service zu ”browsen”. Hierfür wird die Methode browse
verwendet:
public s t a t i c DNSSDService browse ( int f l a g s , int i f I n d e x , S t r i n g
regType , S t r i n g domain , B r o w s e L i s t e n e r l i s t e n e r )
throws DNSSDException
Da die Ausführung dieser Methode viel Netzwerk-Bandbreite benötigt sollte
stets nach erfolgreicher Suche die Methode DNSSDService.stop() aufgerufen
werden um das Browsen zu beenden.
Damit Aktualisierungen der Services im Netz erkannt werden, muss die Klasse
LLPresenceDiscover folgende drei Interfaces implementieren:
RegisterListener3 Listener für die Registrierung des eigenen Services durch die
Methode DNSSD.register(...)
BrowseListener4 Listener für die Methode DNSSD.browse(...). Der Listener
reagiert, wenn ein Service, in diesem Fall vom Typ ” presence. tcp.”, gefunden bzw. verloren wurde und kann dementsprechend reagieren.
ResolveListener5 Listener für die Methode DNSSD.resolve(...). Der Listener
reagiert, wenn der gesuchte Servicename aufgelöst wurde.
4.4.2. Eclipse-Plugin
Plugins6 ermöglichen die einfache Erweiterung der Eclipse Entwicklunsumgebung (IDE) um weitere Funktionalitäten bzw. Komponenten. Ein Eclipse-Plugin
besteht aus zwei Teilen:
plugin.xml ist eine Plugin Manifest Datei und enthält die eindeutige ID, den
Namen, die Version, eine Liste der notwendigen Packages und die Extension Points des Plugins, damit Eclipse das Plugin in die Registry eintragen
kann und die IDE dementsprechend konfiguriert werden kann.
Ein Extension Point ist eine Erweiterungsschnittstelle bereits bestehender
Plugins. Es ist außerdem möglich verschiedene Eclipse-Plugins miteinander zu koppeln[2].
Quellcode die eigentliche Implementierung des Plugins.
6
http://www.eclipse.org/articles/Article-Your%20First%20Plug-in/
YourFirstPlugin.html
15
4 Link-Local Messaging (XEP-174)
4.4.3. SAXParser
Ein ”Simple API for XML”-Parser, kurz SAXParser genannt, ermöglicht es
XML-Daten als sequentiellen Datenstrom einzulesen und zu parsen. Der SAXParser ist ereignisorientiert und reagiert somit auf vordefinierte Ereignisse durch
den Aufruf von Callback-Funktionen [3].
Ein Beispiel für einen SAXParser ist die, für diese Arbeit geschriebene Klasse
SAXStreamHandler (siehe Abschnitt 4.5.2).
In diesem Abschnitt wurden die verwendeten APIs aufgezählt und kurz beschrieben. Bei DNS-SD wurden, die für diese Arbeit relevanten Methoden und
Interfaces genauer erläutert. Bei Eclipse-Plugin wurde vor allem auf die Bestandteile eines Plugins eingegangen. Der SAXParser wurde nur spärlich erklärt
und wird im Abschnitt 4.5.2 genauer betrachtet.
4.5. Implementierung
Für dieses Projekt waren eine Vielzahl an verschiedenen Klassen notwendig,
damit die spätere Kompatibilität zum ECF gegeben ist. Die wichtigsten Klassen
lassen sich allerdings auf drei beschränken:
• BonjourRosterView
• Chat
• ChatManager
Im folgenden werden diese drei Klassen im Detail untersucht.
4.5.1. BonjourRosterView
Diese Klasse ist eine angepasste Version der bereits bestehenden Klasse RosterView (org.eclipse.ecf.ui.views.RosterView). Die Hauptaufgabe der BonjourRosterView ist es einen neuen Client im Netz zu registrieren und einen Roster
bzw. eine Kontaktliste zu verwalten.
Ein neuer Client wird mit der Methode
public void c o n n e c t ( S t r i n g connectID ) ;
registriert. Als Paramter reicht der Benutzername. Der Hostname wird automatisch gelesen und dem Benutzernamen, durch ein ”@” getrennt, angehängt
um eine eindeutige ChatID zu bilden.
LLPresenceDiscover
Damit BonjourRosterView stets auf dem aktuellen Stand ist, ist ein Listener
notwendig. Dafür wurde die innere Klasse LLPresenceDiscover eingeführt. LLPresenceDiscover implementiert, wie bereits in Abschnitt über DNS-SD erwähnt,
drei Interfaces des DNS-SD (siehe Abschnitt 4.4.1).
16
4.5 Implementierung
BonjourRosterGroup und BonjourRosterEntry
Der Inhalt des Rosters ist in Gruppen vom Typ BonjourRosterGroup eingeteilt.
Eine BonjourRosterGroup hat in sich eine Liste von Rostereinträgen des Typs
BonjourRosterEntry. Diese Liste ist als ”private” deklariert und kann durch
Funktionen bearbeitet werden. Die vier wichtigsten Funktionen sind:
// Fuegt e i n e n neuen R o s t e r e i n t r a g i n d i e L i s t e e i n
public void add ( Bonjou rRosterE ntry e n t r y ) ;
// Holt e i n e n R o s t e r e i n t r a g aus d e r L i s t e
public Bonjo urRoste rEntry g e t B o n j o u r R o s t e r E n t r y ( BonjourID i d ) ;
// Löscht e i n e n R o s t e r e i n t r a g aus d e r L i s t e
public void remove ( BonjourID i d ) ;
// Holt e i n e n R o s t e r e i n t r a g aus d e r L i s t e mit dem
Benutzernamen username . Wird vor a l l e m b e i d e r D o p p e l k l i c k −
Funktion i n d e r BonjourRosterView verwendet .
Bonjo urRoste rEntry getEntryFor ( S t r i n g username ) ;
4.5.2. Chat
Die Klasse Chat verwaltet den XML-Stream über den der Chat läuft. Die Aufgabe von Chat ist es einen Stream zu starten bzw. zu schließen und Nachrichten
zu senden bzw. zu empfangen.
Interface IChat
Die Klasse Chat implementiert das, vom ECF verwendete, Interface IChat7 .Das
Interface IChat befindet sich im Package ”org.eclipse.ecf.presence.im” und definiert Funktionen zum Senden von Nachrichten. Die für diese Arbeit interessanten Funktionen sind:
// L i e f e r t d i e ID d e s N a c h r i c h t e n e m p f ä n g e r s z u r u e c k
ID g e t R e c e i v e r I D ( ) ;
// Sendet e i n e N a c h r i c h t mit dem Body messageBody an den
Nachrichtenempfaenger
void sendChatMessage ( S t r i n g messageBody ) throws ECFException ;
SAXStreamHandler
Als Listener für den Inputstream und als SAXParser wurde die innere Klasse
SAXStreamHandler eingeführt. Die Aufgabe von SAXStreamHandler ist es die
empfangenen XML-Daten des Chatstreams auszulesen und Nachrichten heraus
zu filtern. Für die Auswertung wurde die Klasse SAXStreamHandler von der
7
http://www.eclipse.org/ecf/org.eclipse.ecf.docs/api/org/eclipse/ecf/presence/
im/IChat.html
17
4 Link-Local Messaging (XEP-174)
Klasse DefaultHandler8 abgeleitet und es wurden folgende Callback-Funktionen
überladen:
// Das Ende d e s Dokuments wurde e r r e i c h t
public void endDocument ( ) throws SAXException ;
// Ein XML−S t a r t −Tag wurde e r r e i c h t . Die Bezeichnung d e s Tags
s t e h t d a b e i i n qName , A t t r i b u t e i n a t t r i b u t e s
public void s t a r t E l e m e n t ( S t r i n g u r i , S t r i n g localName , S t r i n g
qName , A t t r i b u t e s a t t r i b u t e s ) throws SAXException ;
// Ein XML−End−Tag wurde e r r e i c h t . Die Bezeichnung d e s Tags
s t e h t d a b e i i n qName
public void endElement ( S t r i n g u r i , S t r i n g localName , S t r i n g
qName) throws SAXException ;
// Eine Z e i c h e n k e t t e wurde e r r e i c h t . Vor a l l e m zum A u s l e s e n
d e r Chatmessage verwendet
public void c h a r a c t e r s ( char ch [ ] , int s t a r t , int l e n g t h )
throws SAXException ;
Bei der Methode ”startElement” wurden ”STREAM:STREAM”-, ”BODY”und ”HTML”-Start-Tags berücksigt. Bei einem ”STREAM:STREAM”-Tag wird
ein neuer Chat gestartet. Nach einem ”Body”-Tag kommt die Textnachricht.
Um eine doppelte Ausgabe der Textnachricht zu vermeiden muss das Vorhandensein des ”HTML”-Tags geprüft werden, denn im ”HTML”-Tag können Eigenschaften, wie etwa Schriftgröße oder Schriftfarbe, angegeben werden und
enthält nochmals ein ”Body”-Tag mit der Chatnachricht.
Bei der Methode ”endElement” wurde das ”STREAM:STREAM”-End-Tag berücksigt,
damit auf eine Beendigung des Streams, von der Gegenseite ausgehend, reagiert
werden kann.
4.5.3. ChatManager
Die Klasse ChatManager verwaltet Objekte vom Typ Chat. Die Aufgabe von
Chatmanager ist es, Nachrichten an den richtigen Chat weiter zu senden und
bei einem eingehenden Stream einen neuen Chat zu starten.
Interface IChatMessageSender
Damit die Klasse ChatManager Nachrichten ECF-kompatibel sendet, wird das
interface IChatMessageSender9 implementiert. Das Interface IChatMessageSender befindet sich im Package ”org.eclipse.ecf.presence.im” und definiert zwei
Funktionen zum Senden von Nachrichten:
// Für d i e Implementierung i s t d i e s e Methode n i c h t r e l e v a n t
void sendChatMessage ( ID toID , ID threadID ,
8
http://www.aip.de/~granzer/javadoc/jaxp/org/xml/sax/helpers/DefaultHandler.
html
9
http://www.eclipse.org/ecf/org.eclipse.ecf.docs/api/org/eclipse/ecf/presence/
im/IChatMessageSender.html
18
4.6 Zusammenfassung
IChatMessage . Type type , S t r i n g s u b j e c t ,
S t r i n g body , Map p r o p e r t i e s )
throws ECFException
// Nur d i e s e Methode i s t a u s i m p l e m e n t i e r t
// toID − d e r Empfänger d e r N a c h r i c h t
// body − d i e N a c h r i c h t
void sendChatMessage ( ID toID , S t r i n g body )
throws ECFException
Für das Senden von Nachrichten durch die Klasse ChatManager, ist nur die
zweite Methode brauchbar. Durch den Parameter ”toID” kann ChatManager
den richtigen Chat in der internen Chat-Liste finden und die Nachricht ”body”
senden.
SockConListener
Die Klasse ChatManager ist, neben der Aufgabe einen Chat zu starten und
Nachrichten zu senden, weiters in der Lage auf eingehende Chatverbindungen
zu reagieren. Dazu wird die innere Klasse SockConListener verwendet. SockConListener ist von der Klasse Thread abgeleitet und erfüllt die Aufgabe eines
Servers, der auf einem bestimmten Port lauscht. Der Port ist standardmäßig
auf den Wert ”DEFAULT SERVER PORT”(=5299) gesetzt. Bei einem eingehenden Socket öffnet SockConListener einen neuen Chat und fügt diesen in die
Chat-Liste des ChatManagers ein.
In diesem Abschnitt wurden die drei wichtigsten Klassen des Projekts aufgezählt und beschrieben. Es wird jeweils auf die Verwendung der Klasse und
deren Aufbau (innere Klassen) eingegangen. Bei der Verwendung der Klasse
werden vor allem die bereitgestellten Methoden genauer erläutert.
4.6. Zusammenfassung
In diesem Kapitel wurde der Begriff Link-Local-Messaging erklärt, dessen Funktionweise beschrieben und bereits bestehende Ansätze analysiert. Weiters wurde
eine neue Link-Local-Messaging Implementation vorgestellt.
Die hier vorgestellte Implementation wurde bereits veröffentlicht und an das
ECF Projekt zur Integration übergeben. Wahrscheinlich ist die Implementation bereits in der nächsten ECF Version verfügbar.
19
5. Zusammenfassung und Ausblick
Das Thema XMPP zieht sich als roter Faden durch die Arbeit. Zu Beginn
wurde eine Begriffdefinition für XMPP angegeben und die grundlegende Kommunikation erklärt. Es wurden die, für die Kommunikation wichitgen, Begriffe
Jabber-ID, XML-Stream und XML-Stanza eingeführt und anhand von Beispielen anschaulich erklärt. Zusätzlich wurden bereits bestehende Ansätze für Java
aufgezählt, wobei das Augenmerk auf die SmackAPI gerichtet wurde, weil diese
im ECF verwendet wird.
Im dritten Kapitel wurde auf das ECF Projekt, die SmackAPI und vor allem
auf die Integration der neuen SmackAPI (3.1) ins ECF eingegangen. Es wurden die wichtigsten Neuerungen der SmackAPI Version 3.1 aufgelistet und die
verschiedenen Schritte der Integration ins ECF beschrieben. Dabei wurden Probleme, wie etwa Lizenzprobleme ersichtlich.
Das in Kapitel 4 beschriebene Link-Local Messaging baut auf XMPP und Zeroconf auf. Link-Local verwendet dabei für die Service Discovery die Zeroconf
Technik. Für den eigentlichen Nachrichtenaustausch wird eine stark vereinfachte Abwandlung von XMPP benützt. Weiters wurden bereits bestehende bzw.
verwendete Ansätze aufgezeigt und beschrieben, sowie eine neue Link-Local
Messaging Implementation vorgestellt.
Die neue Implementation wurde bereits veröffentlicht und an das ECF Projekt
zur Integration übergeben. Wahrscheinlich ist die Implementation bereits in der
nächsten ECF Version verfügbar.
Im folgenden werden drei Erweiterungsvorschläge für die Implementation und
je eine kurze Anleitung für deren Umsetzung gegeben.
5.1. Vorschläge zur Erweiterung
Für die Implementation der Link-Local Messaging Unterstützung gibt es drei
Erweiterungsvorschläge:
• FileTransfer: Der Nachrichtenaustausch unter den Clients kann durch den
Dateienaustausch erweitert werden. Dazu muss die Klasse Chat für den
ausgehenden Transfer und die Klasse SAXStreamHandler für den eingehenden Filetransfer modifiziert werden.
• Statusanzeige: Bisher wird der, im TXTRecord angegebene Status nicht
berücksigt, d.h. ”unsichtbare” Clients werden trotzdem in der BonjourRosterView angezeigt. Des weiteren könnte im TXTRecord, wie vorgesehen, eine Statusnachricht bei Abwesendheit in der BonjourRosterView
aufscheinen.
20
5.1 Vorschläge zur Erweiterung
• Messagetypingnotification: Die im Interface IChat definierte Methode sendTypingMessage(...) könnte in der Klasse Chat ausimplementiert werden,
damit der Client sieht, ob der Gesprächspartner gerade eine Nachricht
schreibt.
21
Literaturverzeichnis
[1] Xmpp software: Libraries. Website, 1999-2009. Available online at http:
//xmpp.org/software/libraries.shtml; visited on December 29th 2009.
[2] Heiko Seeberger Manfred Hennig.
Einfà 14 hrung in den extension point-mechanismus von eclipse.
Website, 2008.
Available online at http://www.sigs.de/publications/js/2008/01/hennig_
seeberger_JS_01_08.pdf; visited on January 09th 2010.
[3] David Megginson. Sax. Website, 2001. Available online at http://www.
saxproject.org/; visited on January 10th 2010.
[4] Jin Li Nick Edgar, Kevin Haaland and Kimberley Peter. Eclipse user interface guidelines. Website, 2004. Available online at http://www.eclipse.
org/articles/Article-UI-Guidelines/Contents.html; visited on December 31th 2009.
[5] Remko Troncon Peter Saint-Andre, Kevin Smith. XMPP: The Definitive
Guide: Building Real-Time Applications with Jabber Technologies. O’Reilly
Media, 2009.
[6] Peter Saint-Andre. Xep-0174: Serverless messaging. Website, 1999-2009.
Available online at http://xmpp.org/extensions/xep-0174.html; visited on December 31th 2009.
[7] Peter Saint-Andre. Extensible messaging and presence protocol (xmpp):
Core. Website, 2004. Available online at http://xmpp.org/rfcs/
rfc3920.html; visited on December 29th 2009.
[8] Jive Software. Smackapi. Website. Available online at http://www.
igniterealtime.org/projects/smack/; visited on January 01th 2010.
[9] Jive Software. Xep-0174 (link-local) support in smack. Website, 2009.
Available online at http://www.igniterealtime.org/issues/browse/
SMACK-262; visited on January 09th 2010.
[10] Wikipedia. Extensible messaging and presence protocol. Website,
2009. Available online at http://de.wikipedia.org/wiki/Extensible_
Messaging_and_Presence_Protocol; visited on December 26th 2009.
22
A. Anhang
A.1. Aufbau des Eclipse Workbench
Abbildung A.1.: Aufbau des Eclipse Workbench [4]
23

Documents pareils