Platz ist in der kleinsten Hütte
von Karl Banke
Webservices heißt derzeit ein neues Paradigma, dass von IBM bis Oracle,
von Microsoft bis SUN als neue "Silver Bullet" der verteilten
Softwareentwicklung gefeiert wird. Wir wollen die Probe aufs Exempel
machen und einen Webservice von einer eher esoterischen Zielplattform
aus ansprechen: Einem Linux PDA der kalifornischen Firma Agendacomputing.
Der anzusprechende Webservice stellt die Funktionalität eines einfachen
Übersetzungsdienstes mittels des SOAP Protokolls bereit.
Auf die Plätze
Den PDA haben wir direkt vom Hersteller bezogen. Für rund 600 DM gibt es
ein System mit einem MIPS R3000 Prozessor und 8MB Hauptspeicher. Auch
die PDA typischen Applikationen sind vorhanden. Im täglichen Gebrauch
fühlt sich das ganze noch etwas zäh an, hier ist sicherlich noch
Optimierungspotential vorhanden. Über ein mitgeliefertes serielles Kabel,
die Infrarotschnittstelle oder ein eingebautes Modem kann die Verbindung
zum Netzwerk hergestellt werden. Zum Zwecke der Softwareentwicklung
vernetzen wir das Gerät über das serielle Kabel und eine PPP Verbindung
mit einem als Router konfigurierten Entwicklungsrechner.
Als Programmiersprache der Wahl dient hier C++ mit dem GNU C++ Compiler.
Dieser wird als Cross Compiler für Intel Linux bereitgestellt. Andere
Programmiersprachen, wie Java, Python, Tcl u.a. sind ebenfalls erhältlich.
Diese stellen jedoch erhebliche Ressourcenanforderungen an das Gerät, so
dass ihre Verwendung derzeit noch nicht praktikabel erscheint.
Die Standardentwicklungsumgebung für den Agenda PDA ist durch das Auspacken
einiger rpm Archive auf einem Intel Linux System schnell aufgebaut.
Eine ausführliche
Anleitung liefert das Linux VR Tools Howto. Damit sind bereits einfache
Programme mit grafischer Benutzeroberfläche erstellbar. Die grafische
Oberfläche des VR3 ist mit dem Fast Light Toolkit, fltk, umgesetzt.
Um Programmme zunächst unter Intel Linux zu kompilieren und zu testen
empfiehlt es sich, dieses Toolkit herunterzuladen und zu kompilieren.
Ohne Parser geht es nicht
Da wir möglichst viele Resourcen sparen wollen, verzichten wir auf lästigen
Overhead wie Webbrowser oder Email Client. Der verfügbare Platz im
Dateisystem beträgt nämlich nur rund 3 Megabyte. Auch von der Nutzung
einer speziellen SOAP Bibliothek wollen wir absehen. Um aber halbwegs
komfortabel auf einen Webservice zugreifen zu können und die Antwort des
Servers zu analysieren, ist ein XML Parser empfehlenswert. Eine kompakte
Bibliothek mit einem geringen Footprint ist die libxml2.
Sie bietet
darüber hinaus einfache Möglichkeiten zum Aufbau des Request Dokuments
und zum Senden des Dokuments zum Server über das http Protokoll. Unter
unserem ix86 Linux System übersetzt die libxml problemlos.
Um den Parser mit dem Crosscompiler als shared library zu übersetzen, ist
ein wenig Handarbeit notwendig. Zunächst müssen einige Pfade geändert werden.
Dann ist configure mit den richtigen Parametern aufzurufen.
export PATH=/usr/mipsel-linux/bin:$PATH
export CC="mipsel-linux-gcc -msoft-float"
export LD="mipsel-linux-gcc -msoft-float"
./configure --includedir=/usr/mipsel-linux/include/
--libdir=/usr/mipsel-linux/lib/
--host=i386-linux --target=mipsel-linux
--disable-static --without-iconv
--without-debug --disable-corba
--without-ftp --without-html --without-docbook
--enable-shared --with-gnu-ld
Wenn dann mit gmake der Bauprozess gestartet wird, tritt bei der Übersetzung des HTTP Moduls zunächst ein Fehler auf. Diesen kann man durch das manuelle Einfügen eines fehlenden Define beheben.
#define SOCK_STREAM 2
Schließlich sind noch einige Anpassungen in libtool vorzunehmen, um die dynamischen Bibliotheken zu bauen. Insbesondere sind folgende Zeilen anzupassen.
# Whether or not to build shared libraries.
build_libtool_libs=yes
# List of archive names.
# First name is the real one, the rest are links.
# The last name is the one that the linker finds with -lNAME.
library_names_spec="libxml.so"
# Commands used to build and install a shared archive.
archive_cmds="$CC -shared $libobjs $deplibs $linkopts
${wl}-soname $wl$soname -o $lib"
Die Library sollte auf dem PDA im Verzeichnis /usr/local/lib installiert
werden.
SOAP Anfrage stellen
Zunächst wird das SOAP XML Anfragedokument im Hauptspeicher aufgebaut.
Im betrachteten Beispiel wird ein Dienst aufgerufen, der für einen
Begriff in einer Quellsprache eine Reihe von verwandten Originalbegriffen
mit ihren Übersetzungen in der Zielsprache liefert.
Dabei unterstützt libxml den Aufbau von XML Dokumenten als einfachen Baum
im Speicher. Da auch Namespaces und Attribute unterstützt werden kann
das benötigte XML Dokument problemlos erzeugt werden. Die Variablen
Quellsprache, Zielsprache und der zu übersetzende Begriff werden der
Funktion in Listing 1 übergeben.
Das erzeugte Dokument entspricht dann
der unter dargestellten Struktur.
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTranslations xmlns:ns1="urn:demo1:translate"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<term xsi:type="xsd:string">Hallo</term>
<srcLanguage xsi:type="xsd:string">en</srcLanguage>
<targetLanguage xsi:type="xsd:string">de</targetLanguage>
</ns1:getTranslations>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP Antwort
Das Dokument kann jetzt als Zeichenfeld in den Speicher gelegt werden
und als HTTP Request an den Endpunkt des Webservice gesendet werden.
Hierzu dienen die folgenden Befehle.
xmlDocDumpFormatMemoryEnc(doc,&doctxt,&doclen,"utf-8",1);
void* ctx = xmlNanoHTTPMethod (endPoint, "POST", (char*)doctxt,
NULL, headers);
Der Output kann nun gelesen und sofort verarbeitet werden. Hier bietet
die libxml2 eine sogenannte Push Verarbeitung. Dabei kann dem Parser das
Reply Dokument stückweise übergeben werden, eben genau so, wie es vom
Server gelesen wird. Der Parser liefert dann eine Baumstruktur zurück,
die traversiert und interpretiert werden kann. Man kommt also ganz ohne
Programierung von Parsercallbacks aus, obwohl die libxml natürlich die
Möglichkeit hierzu liefert. Listing 2
zeigt die Funktion, die das
Senden der Anfrage und das Parsen der Antwort enthält. Schließlich ist
noch eine Aufarbeitung des Dokuments notwendig, um zu einem Charakterarray
zu kommen, das dann in der grafischen Benutzeroberfläche dargestellt werden
kann.
Gut siehst Du aus
Nun muss noch die grafische Oberfläche programmiert werden. In unserem Fall
beschränkt sich dies auf ein Eingabefeld, einen Button und eine
Listenstruktur zum Darstellen der Ergebnisse. Denkbar wären noch
Radiobuttons, um die
Übersetzungsrichtung anzugeben. Ein Callback für den Button wird
benötigt um die Abfrage zu starten. Der benötigte Code ist in Listing 3
dargestellt.
Damit haben wir einen einfachen Client für den Übersetzungswebservice
geschrieben. Nach dem Compilieren können wir ihn auf den PDA kopieren
und ihn dort ausführen, im einfachsten Fall von der Kommandozeile aus.
Fazit
Zusammenfassend ist zu sagen, dass die Verwendung von Webservices auch
von eher exotischen Geräten aus ohne größere Schwierigkeiten funktioniert.
Als Hauptvoraussetzung sollte jedoch neben der obligatorischen
Netzwerkanbindung eine leistungsfähige XML Bibliothek zur Verfügung stehen.
Für allgemeinere Aufgaben kann diese dann immer in einen leichtgewichtigen
SOAP Abstraktionslayer gewrappt werden. Viele der auf dem Markt befindlichen
Geräte - z.B. Mobiltelefone und PDAs, aber auch Videospielkonsolen - erfüllen
bereits jetzt diese Anforderungen. Angesichts dieser Tatsache sind
Webservices ohne Zweifel eine Technologie mit hervorragender Zukunft.
Links und Literatur
- Simple Object Access Protocol (SOAP) 1.1
- Linux VR Tools Howto, LaRonde, Bradley
- The Fast Light Toolkit Homepage
- The XML C Library for Gnome
Karl Banke
2004-01-06