rss feed articles all_comments

indeedgeek.de

Florian Eitel

2. Advent: Projektstart und Schnittstellen

So, die erste Woche ist vorbei. Zeit ein kleines Resumé zu ziehen. Letzten Advent sind wir auf die Features und Schnittstellen eingegangen. Nun haben wir uns dran gemacht und sind in die Implementierung gestartet.

Oh, schön. Wo kann ich es ausprobieren? — Dazu ist es noch etwas früh. Wir haben uns erst einmal zur grundsätzlichen Struktur der Applikation Gedanken gemacht. Wir wollten die Applikation so offen wie möglich halten um auch später noch Änderungen einzubauen. Dies schließt aber nicht nur das Protokoll sondern auch für jegliche Benutzerinteraktion. Unser Ziel war es das UI komplett von der Logik zu trennen. Das mag sich erst einmal selbstverständlich anhören aber ich kenne kaum Anwendungen in denen das konsequent umgesetzt wird. Jeder Programmierer wird mir bestätigen können, dass es Sinn macht das UI zu trennen und werden mit Begriffen wie MVC um sich werfen. Aber reicht diese Trennung schon?

Auf der einen Seite haben wir das Protokoll zwischen zwei Rechnern wie wir es letzte Woche schon beschrieben haben. Aber nun haben wir noch einmal die Logik vom UI getrennt und benötigen daher auch dazwischen ein Protokoll.

Wird also nun jeder Klick über ein eigenes Protokoll zur Logik übertragen? — Nein wir haben die wichtigen Funktionen wie das Empfangen und Versenden von Dateien in einen eigenen Prozess ausgelagert. Dieser Spricht zum einen über das Netzwerk mit anderen Rechnern und versendet bzw. empfängt Dateien. Ein Client kann sich nun bei diesem Prozess anmelden und bekommt Benachrichtigen wenn zum Beispiel eine neue Datei eintrifft. Zudem kann er auch selbst Methoden aufrufen um zum Beispiel eine Datei zu versenden.

Ihr habt also das Protokoll durch ein weiteres Protokoll gekapselt? Warum? — Die Idee dahinter ist das verwenden unterschiedlicher UIs. Manche mögen bunte Fenster. Andere sind von der Programmierung über die Kommandozeile überzeugt. Eventuell möchte man einen Webclient haben oder ein Applet in der Statusleiste. Manche möchten auch einfach das Beste aus allem. Wir unterstützen aktuell, dass sich beliebig viele Client zu unserem Server verbinden und dort Benachrichtigt werden oder diesen Steuern können.

Habt ihr nun erneut ein Protokoll definiert? — Diesmal nicht. Unter Linux zumindest ist DBus seit längerem schon ein Quasi-Standard. Dabei handelt es sich um eine so genannte Desktop-Middleware. Man kann sich das als ein Bus vorstellen auf dem sich verschiedene Programme einklinken können. Manche übernehmen hierbei die Rolle eines Services der verschiedene Methoden anbietet. Andere Programme können über DBus mit diesen Services kommunizieren.

In der KDE3 Zeit gab es unter KDE ein ähnlicher Mechanismus namens DCOP. Hiermit konnte man über Interprozess-Kommunikation (IPC) mit anderen Programmen kommunizieren. Gnome hatte wohl auch so etwas ähnliches ist aber recht früh auf DBus umgestiegen. Seit KDE4 wird Dbus auch im Qt/KDE Bereich genutzt. Und ist auf allen Postfix-Systemen vertreten. Selbst für Windows gibt es mittlerweile einen Port. Definiert man nun Schnittstellen wie Passwortverwaltung oder Notifications kann jedes Programm einfach darauf zugreifen. Der Service lässt sich so einfach ersetzen ohne, dass an den einzelnen Programmen etwas geändert werden muss. In sehr vielen Programmiersprachen existieren Libraries um komfortabel auf DBus zuzugreifen.

DBus hat im Gegensatz zu vielen ähnlichen Ansätzen eine recht objektorientierte Struktur. Zum einen hat man verschiedene Services die wie bereits erwähnt Passwörter oder Notifications verwalten. In unserem Beispiel soll der Service Dateiaustausch ermöglichen. Darunter kann man für jeden Service verschiedene Objekte definieren. Bei einfachen Anwendungen reicht es aus, ein einziges Objekt zu haben. Neben einem Objekt welches die grundlegende Schnittstelle bildet, instantiieren wir zum Beispiel bei einer einkommenden Datei ein neues Objekt und geben dem User nur eine Referenz auf das neue Objekt zurück. Dieser kann dann auf dem Objekt verschiedene Methoden aufrufen. Alle Filetransfer-Objekte implementieren das selbe Interface welches auch im Kontext von DBus definiert ist. Somit bleibt die Schnittstelle schön übersichtlich.

Damit ein neuer Programmierer in Erfahrung bringen kann, wie er die Schnittstelle anspricht gibt es in DBus den Mechanismus Introspection. Dadurch bekommt bekommt man ein XML-File in dem alle Daten zu dem Daemon stehen. Also welche Methoden aufgerufen werden können, welche Objekte es gibt, welche Interfaces diese implementieren und welche Signale versendet werden. Ein Schickes Tool um dieses zu visualisieren ist d-feet:

Image 1. Introspection in unseren filer Service mit d-feet.

Ok, ich sehe schon DBus ist eine großere Geschichte. Wie weit seit ihr aber nun? — Ja stimmt ich könnte noch Ewigkeiten über DBus schreiben und hoffe demnächst auch mal einen erschöpfenden Beitrag fertig zu bekommen. Wir haben nun Avahi, welches ebenfalls über DBus angebunden wird integriert und können uns schon im Netzwerk kundtun. Auch die Gegenseite kann sich schon alle Empfänger anzeigen lassen und bekommt Benachrichtigungen wenn sich etwas ändert. Das eigentliche Versenden und Empfangen haben wir erst einmal ausgespart.

Die meisten Probleme machte wohl das Avahi-Interface. Es gibt nur sehr wenig Dokumentation darüber und die Interfaces sind komplett undurchsichtig. Sucht man beispielsweise nach einem Service wird immer ein Event ausgelöst sobald dieser gefunden wurde. Mann kann dann ein discovery machen um festzustellen auf welchem Rechner der Service läuft. Verlässt der Service das Netzwerk weiß, man nicht welcher Rechner betroffen ist da ich ja kein discovery mehr machen kann. Somit muss man sich alle Rechner die man discovered hat merken, damit man nachvollziehen kann welcher jetzt verschwunden sein könnte. Der einzige brauchbare Weg zu verstehen wie das Interface gemeint ist, war sich Python Code durchzulesen und zu schauen was die so treiben.

Unser Daemon ist nun in drei Teile aufgeteilt: Einmal der Discovery, der herausfindet an welche Rechner gesendet werden kann und sich auch selbst publiziert. Und der DBus-Teil, der die Kommunikation zum User übernimmt. Der dritte Teil verbindet die beiden Komponenten miteinander. Der Code ist so ausgelegt, dass man alle drei Teile beliebig zusammenstecken kann um zum Beispiel andere Interfaces zu verwenden.

Den Code gibts wohl erst nächste Woche. Er ist leider noch nicht ganz so weit, als dass man etwas sehen könnte. Deswegen haben wir beschlossen ihn noch etwas zurück zu halten.

Comments:

(howto comment?)