Steuerung mittels CORBA

Zurück |  | Nach vorne

# 4. Steuerung mittels CORBA

SandUhr besitzt eine umfangreiche CORBA-Schnittstelle. Damit kann man auch in eigenen Skripten und Programmen neue Uhren erzeugen oder auf bestehende Uhren zugreifen. Die Schnittstelle erlaubt es sogar, eigene Alarmmechanismen an das Programm anzuschließen. Unten findet sich als Beispiel eine Methode, um die Alarmmeldung per Email zuzustellen.

## 4.1. CORBA-Einführung

CORBA ist ein komplexes Gefüge, das dazu dient unterschiedliche Programmteile auch dann miteinander verbinden zu können, wenn sie möglicherweise in unterschiedlichen Programmiersprachen geschrieben sind, oder auf unterschiedlichen Rechnern eines Netzwerkes laufen. Die volle Dosis an Schlagworten findet sich auf der offiziellen CORBA-Webseite unter www.corba.org.

CORBA ist objektorientiert. Ein CORBA-Server implementiert Objekte und Kunden können (vom Server vorgegebene) Anforderungen an den Server senden, um bestimme Aufgaben zu erledigen. SandUhr implementiert zwei Klassen von CORBA-Objekten:

- `SandUhr::Timer`-Objekte. Diese entsprechen den sanduhrförmigen Fenstern auf dem Bildschirm. Sie stellen Anfragen zur Verfügung, um die Einträge aus dem Eigenschaftendialog der Uhr zu setzen oder abzufragen.

- `SandUhr::TimerFactory`-Objekte. Jede Kopie des SandUhr-Programms implementiert genau ein `TimerFactory`-Objekt. Das entspricht im wesentlichen dem Kontrollfenster, das man in dem Menü der Uhren öffnen kann. Die Hauptaufgabe dieses Objektes ist es, neue Uhren zu erzeugen.

Die CORBA-Unterstützung von SandUhr ist mittels ORBit realisiert. Dies ist der Standard-CORBA-ORB des GNOME-Projekts. Informationen über ORBit gibt es auf der ORBit homepage. Die Kommunikation zwischen unterschiedlichen ORB-Implementationen ist standardisiert, so dass (zumindest in der Theorie) jede ORB-Implementation geeignet sein sollte, um mit SandUhr zusammenzuarbeiten. Wenn Sie mehr über CORBA lernen wollen, dann sollten Sie den Artikel CORBA Applications In GNOME von Elliot Lee lesen. Dieser ist auf der GNOME development site veröffentlicht.

In den folgenden Beispielen werde ich die Python-Schnittstelle für ORBit verwenden. Diese gibt es auf der Seite orbit-python.sault.org. Außerdem wird die OAF-Bibliothek für GNOME benötigt. Hier verwende ich die Python-Anbindung, die im bonobo-python Paket unter bonobo-python.lajnux.nu enthalten ist.

## 4.2. Einfache CORBA-Skripte

Mittels CORBA eine neue Uhr zu erzeugen, ist leicht. Das einzige Problem besteht darin, Zugriff auf ein `SandUhr::TimerFactory`-Objekt zu bekommen. Wir können dann dieses Objekt einfach anweisen, für uns eine neue Uhr zu erzeugen. Das Problem wird durch die OAF-Bibliothek von GNOME (dem „Object Activation Framework“) gelöst. Wir können bei OAF einfach ein CORBA-Objekt anfordern, das die `SandUhr::TimerFactory`-Klasse implementiert. Diese Technik wird durch Beispiel 3 illustriert.

Beispiel 3. Erzeugen einer neuen Uhr mittels CORBA

Das folgende Python-Skript erzeugt eine neue Uhr, die nach 30 Sekunden abläuft. Wenn man das Skript startet sollte es ein neues Sanduhrfenster öffnen und sich dann sofort beenden, ohne auf das Ablaufen der Uhr zu warten. Falls Sie nicht die ORBit-Python-Schnittstelle verwenden, müssen sie eventuell erst mit dem IDL-Compiler das SandUhr-Modul erzeugen.

Natürlich kann man diese Methode auch für jede andere Programmiersprache, sofern sie nur Schnittstellen zu CORBA und der OAF-Bibliothek besitzt, übertragen. Das resultierende Programm wird ähnlich aufgebaut sein.

    import CORBA, oaf, SandUhr

    oaf.init()
    factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
    factory.CreateTimer ("+30s", "Uhr abgelaufen")

Wenn Sie erst einmal dieses Beispiel bewältigt haben, dann ist es kein Problem mehr, die Uhr weiter anzupassen. Beispiel 4 demonstriert, wie man einen pinkfarbenen Timer erzeugt, der fünfmal piept.

Beispiel 4. Konfigurieren der Uhren mittels CORBA

Das folgende Python-Skript erzeugt einen pinkfarbenen Timer, der fünfmal piepst wenn der Alarm ausgelöst wird.

    import CORBA, oaf, SandUhr

    oaf.init()
    factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
    timer = factory.CreateTimer ("+20s", "Pinkfarbener Timer abgelaufen")

    timer.SandColor=SandUhr.Timer.Color(Red=212,Green=78,Blue=222)

    alarm = factory.CreateAlarmBeep (5)
    timer.Alarm = alarm

## 4.3. Fortgeschrittene CORBA-Anwendungen

Eine aufwändigere Anwendung der CORBA-Schnittstelle besteht darin, neue Alarmmechanismen an das Programm anzuschließen. Dadurch können sie die Alarmmeldung mittels beliebiger Programme zustellen. Beispiel 5 zeigt exemplarisch, wie Sie das per Email tun.

Das Programm muss hier einen CORBA-Server bereitstellen, der die `SandUhr::AlarmAction`-Schnittstelle, wie sie in SandUhr::AlarmAction(3) beschrieben ist, implementiert: es muss das `SandUhr::AlarmAction::NeedsPopup`-Attribut und die Methoden `SandUhr::AlarmAction::Attach`, `SandUhr::AlarmAction::Detach` und `SandUhr::AlarmAction::Deliver` bereitstellen.

Für objektorientierte Programmiersprachen stellt die ORB-Implementation dazu gewöhnlich eine Klasse, die etwa `SandUhr__POA::AlarmAction` benannt ist, zur Verfügung (für Python ist der Name `SandUhr__POA.AlarmAction`). Davon müssen Sie nun eine neue Klasse ableiten, die `NeedsPopup`, `Attach`, `Detach` und `Deliver` überlädt.

SandUhr greift auf den Server zu, um die Alarmmeldung zuzustellen. Daher müssen sie Ihr Programm am Laufen halten, bis der Timer abgelaufen ist. Gewöhnlich ruft man dazu die Methode `ORB::run` des ORBs auf.

Beispiel 5. Zustellung des Alarms per Email

Das folgende Python-Skript implementiert eine Alarmmethode, die den Alarm per Email zustellt. Sie müssen die Variablen `EMAIL` und `SENDMAIL` an Ihre Situation anpassen. Nach dem Starten sollte das Skript ein Sanduhrfenster öffnen und in Schlaf verfallen. Nach 60 Sekunden schickt es dann eine Email los und beendet sich selbst.

    EMAIL = "Addressee <some@email.address>"
    SENDMAIL = "/usr/sbin/sendmail"

    import os
    import CORBA, oaf
    import SandUhr, SandUhr__POA

    orb = oaf.init()

    class SendMailAlarm(SandUhr__POA.AlarmAction):
        def __init__(self):
            self.NeedsPopup = CORBA.FALSE

        def Attach(self, timer):
            pass

        def Detach(self, timer):
            orb.shutdown(1)

        def Deliver(self, timespec, message):
            p = os.popen("%s -t" % SENDMAIL, "w")
            p.write("To: %s\n" % EMAIL)
            p.write("Subject: SandUhr: %s\n" % message)
            p.write("\n") # Eine Leerzeile trennt den Header vom Text
            p.write("Eine Sanduhr ist abgelaufen.\n")
            p.write("  Alarmmeldung: %s\n" % message)
            p.write("  Alarmzeit: %s\n" % timespec)
            sts = p.close()
            if sts:
                print "Sendmail exit status", sts

    poa = orb.resolve_initial_references("RootPOA")
    alarm = SendMailAlarm()._this()
    poa._get_the_POAManager().activate()

    factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
    timer = factory.CreateTimer ("+60s", "Der Uhr hat die Stunde geschlagen")
    timer.Alarm = alarm

    orb.run()

Es gibt noch eine weitere Methode, um CORBA-basierte Alarmmechanismen an das Programm anzuschließen: mittels `ORB::object_to_string` kann man den IOR-String des `AlarmAction`-Objektes herausfinden. Diesen String kann man in das entsprechende Feld der Seite Aktion im Eigenschaftendialog der Uhr eintragen. Die Uhr wird dann den Alarm mit Hilfe unseres Servers zustellen. Dies wird durch Beispiel 6 demonstriert.

| Diese Technik ist manchmal nützlich, da sie im Gegensatz zu den oben geschilderten Methoden nicht die OAF-Bibliothek benötigt. Man kann dieses Verfahren also auch mit Programmiersprachen verwenden, für die es noch keine OAF-Anbindung gibt.

Beispiel 6. Anschließen einer Alarmmethode mittels des IOR-Strings

Das folgende Python-Skript implementiert eine Beispielalarmmethode. Wenn man es startet, gibt es zunächst nur den IOR-String aus und wartet ab. Wenn man den String in das entsprechende Feld der Seite Aktion im Eigenschaftendialog der Uhr einträgt, dann verwendet die Uhr die Funktion `Deliver()` aus diesem Skript.

    import CORBA, SandUhr, SandUhr__POA

    class Wecker(SandUhr__POA.AlarmAction):
        def __init__(self):
            self.NeedsPopup = CORBA.FALSE

        def Attach(self, timer):
            pass

        def Detach(self, timer):
            orb.shutdown(1)

        def Deliver(self, timespec, message):
            print message

    orb = CORBA.ORB_init()
    poa = orb.resolve_initial_references("RootPOA")

    ref = Wecker()._this()
    print orb.object_to_string(ref)

    poa.the_POAManager.activate()
    orb.run()

Zurück | Zum Anfang | Nach vorne
Konfiguration des Programms |  | Autor