Praktikum Client/Server-Systeme im WS 1999/2000


Aufgabe 1 - CORBA


Inhalt dieser Seite:

Was ist CORBA?
Das Vorgehen bei der Entwicklung mit CORBA
Die vom IDL-Compiler erzeugten Dateien
Unsere Beispiel-Anwendung
Ihre Aufgabe



Was ist CORBA?

Die Common Object Request Broker Architecture (CORBA) ist ein Standard zum Verteilen von Objekten über ein Netzwerk.
Er wurde von der Object Management Group (OMG), einem nicht profitorientierten Standardisierungsgremium mit mehr als 700 Mitgliedern (Softwareentwickler, Netzwerkbetreiber, Hardwareproduzenten und kommerzielle Anwender von Computersystemen, unter anderem SUN, IBM, ...) 1991 in der ersten Version definiert.
Ziel war, eine Middleware zu schaffen, welche eine orts-, plattform- und implementierungsunabhängige Kommunikation zwischen Applikationen erlaubt.
Ein Vermittlungsdienst (Object Request Broker = ORB) gewährleistet dabei das Zusammenarbeiten von Objekten über Rechnergrenzen hinweg.
Wirklich interessant geworden ist CORBA seit der Verabschiedung der Version 2.0 im Dezember 1994. Diese Version brachte das Kommunikationsprotokoll IIOP, welches die Kommunikation zwischen Object Request Brokern (ORB) verschiedener Hersteller und vor allem auch über das Internet ermöglicht.

CORBA zeichnet sich durch folgende Eigenschaften aus:
CORBA stellt also zum einen eine beachtliche Menge technologischen Know-hows und zum anderen einen selten erreichten Konsens innerhalb der Computerindustrie dar.

Begriffe und Abkürzungen:


Das Vorgehen bei der Entwicklung mit CORBA

Prinzipiell erfolgt die Entwicklung einer CORBA-Anwendung stets in den gleichen drei Schritten:
  1. IDL-Datei schreiben, d.h. die Schnittstelle der (Server-)Objekte spezifizieren, und mit dem IDL-Compiler kompilieren
  2. Server implementieren
  3. Client implementieren
Das von uns im Praktikum verwendete Produkt ist der VisiBroker for Java 3.0 von Visigenic.
Dieses Paket enthält unter anderem die CORBA-Klassen, den IDL-Compiler, sowie weitere für die Entwicklung und den Betrieb von CORBA-Anwendungen nötige Werkzeuge und Programme.
Die Online-Produktdokumentation (zwei Teile: "Programmers´s Guide" und "Reference") dazu finden Sie unter der URL
http://www.borland.com/techpubs/visibroker/visibroker30/.
Sie bekommen unter dieser Adresse die Dokumentation wahlweise entweder als HTML-Dokument oder im PDF-Format.
Die folgende Kurz-Einleitung kann nicht die Beschäftigung mit dieser Dokumention (z.B.: "Programmers´s Guide", Kap. 1: "VisiBroker Basics", Kap. 2: "Getting started") ersetzen und soll Ihnen lediglich einen einfachen Einstieg verschaffen.

Bei der Programmierung gehen Sie nun also wie folgt vor:
  1. IDL-Datei schreiben, d.h. die Schnittstelle der (Server-)Objekte spezifizieren, und mit dem IDL-Compiler kompilieren

    Nehmen wir an, Sie möchten eine Klasse "MeineKlasse" mit vier Methoden im Netz zur Verfügung stellen.
    Ihr IDL-Interface könnte dann in etwa so aussehen:

    module Test {
      interface MeineKlasse {
        void tunix();
        long tuwas(in float zahl);
        short tuwas2(inout long zahl);
        float tuwas3(out short zahl);
      };
    };
    

    Die Art eines jeden Parameters (in, inout, out) gibt dabei an, ob mit dem jeweiligen Parameter nur ein Wert an die Methode übergeben werden soll (in), oder ob über diesen Parameter auch ein Wert zurückgegeben wird (inout, out).

    Sie schreiben also die IDL-Datei und speichern sie z.B. unter dem Namen Test.idl ab. Anschließend compilieren Sie sie mit dem Kommando idl2java Test.idl -no_tie (die Option -no_tie bezweckt lediglich, daß der IDL-Compiler keine Dateien generiert, die wir in unserem Fall nicht benötigen).
    Nicht erschrecken: Der IDL-Compiler legt Ihnen nun ein Verzeichnis mit dem Namen Test an, in dem sich eine Unzahl von Dateien befindet, die sich von den ORB-Klassen ableiten und über weitere Vererbung die entsprechenden Methoden soweit anpassen, bis sie mit den IDL-Interfaces übereinstimmen. Für Java werden dabei sehr viele Dateien erzeugt, da Java keine Mehrfachvererbung unterstützt und außerdem nur eine Klasse pro Datei erlaubt ist.
    Je nach Compileroptionen und Art der Klasse werden so pro in der IDL-Datei definierter Klasse ca. fünf Dateien generiert, die alle zusammen das Package Test bilden.
    Wir werden weiter unten noch auf diese Dateien zurückkommen.

  2. Server (in Java) implementieren

    Hier müssen Sie zunächst die Klasse mit den Methoden, die Sie bereitstellen möchten, implementieren.

    Außerdem müssen Sie das Objekt mittels des BOAs beim ORB anmelden und für einen Mechanismus sorgen, der das Objekt aktiviert.
    Im Falle von Visigenic wird die Aktivierung entweder bei Bedarf von einem extra gestarteten Prozess, dem "Object Activation Daemon (OAD)", automatisch erledigt, oder aber sie aktivieren das Objekt mit Hilfe des BOAs selbst und warten dann auf die Anfragen der Clients. Dies können Sie entweder in der main-Methode des Objekts oder aber (wie gleich in unserem Beispiel) in einem separaten Serverprogramm tun.

    Bei der Implementierung Ihrer Klasse erweitern sie per Vererbung die vom IDL-Compiler generierte Skeleton-Klasse (in unserem Beispiel _MeineKlasseImplBase.java).
    Nehmen wir an, sie nennen Ihre Implementation MeineKlasseImpl.java.

    Nun schreiben Sie das Serverprogramm MeinServer.java. Wichtige Kommandos hierbei sind:

    Test.MeineKlasse klasse = new MeineKlasseImpl("Klassen_Name");
    Diese Zeile erzeugt ein neues MeineKlasse-Objekt klasse.
    Wichtig: Durch die Benutzung des Konstruktors mit String-Argument erzeugen Sie ein sog. persistentes Objekt, welches von den Clients später anhand seines Namens (hier: "Klassen_Name") gefunden werden kann.
    Alternativ können sie auch ein namenloses transientes Objekt mit dem argumentlosen Konstruktor erzeugen:
    Test.MeineKlasse klasse = new MeineKlasseImpl();

    boa.obj_is_ready(klasse); (Methode eines org.omg.CORBA.BOA-Objekts boa)
    Hiermit wird das Objekt klasse ins Implementation Repository aufgenommen und vom BOA aktiviert.

    boa.impl_is_ready();
    Alle Objekte sind bereitgestellt, das Serverprogramm hat seine Aufgabe erledigt. Mit diesem Kommando wird das Serverprogramm -und mit Ihm das zur Verfügung gestellte Objekt- weiter am Leben erhalten. Dieses Kommando ist das letzte im Serverprogramm, dieses befindet sich nun in einer Warteschleife, nachfolgende Befehle werden nicht mehr ausgeführt.

    Genauer erklärt finden Sie dies im "Programmers´s Guide", Kap. 5: "Activating Objects".

  3. Client (in Java) implementieren

    Die Methoden, mit denen der Client das von ihm gewünschte Objekt erhält, befinden sich in der vom IDL-Compiler generierten Klasse MeineKlasseHelper.java, und zwar im wesentlichen die Methoden narrow und bind.
    Von beiden gibt es mehrere Formen, die jeweils andere Argumente erwarten.
    Der grundlegende Unterschied zwischen narrow und bind ist, daß narrow die Objektreferenz benötigt, um das Objekt zu finden, bind hingegen findet es aufgrund seines Namens oder liefert einfach das erstbeste passende Objekt des gesuchten Typs zurück.
    In unserem Fall wäre also die richtige Wahl:
    Test.MeineKlasse klasse = Test.MeineKlasseHelper.bind(orb,"Klassen_Name");

    Genauer erklärt finden Sie dies im "Programmers´s Guide", Kap. 4: "Naming and Binding".
Sie haben nun also folgende Dateien vorliegen, die Sie mit dem Compile-Kommando javac *.java compilieren können:
MeinServer.java, MeineKlasseImpl.java und MeinClient.java, sowie das generierte Verzeichnis Test.
Auf dem Serverrechner benötigen Sie MeinServer.java, MeineKlasseImpl.java und das Verzeichnis Test, auf den Clientrechnern MeinClient.java und das Verzeichnis Test.

Die VisiBroker-Dokumentation enthält hierzu ein sehr übersichtliches Beispiel, das die Vorgehensweise verdeutlicht.



Die vom IDL-Compiler erzeugten Dateien:

Genauer erklärt finden Sie dies in "Reference", Kap. 4: "Generated Classes".



Unsere Beispiel-Anwendung

Das Programm, mit dem Sie sich in den nächsten drei Aufgaben beschäftigen werden, ist ein Vier-Gewinnt-Spiel, mit dem Sie über Rechnergrenzen hinweg gegeneinander oder gegen einen Computergegner spielen können.


Prinzipieller Aufbau des "VierGewint"-Systems:

  1. Partie-Manager und Spielpartien
    Der Partiemanager hat die Aufgabe, die laufenden Spielpartien zu verwalten. Er startet bei Bedarf neue Spielpartien und weist diese den Clients zu, die spielen wollen.
    Jede Spielpartie enthält die Spiellogik und ein Spielfeld, so daß immer zwei Clients in einer Spielpartie gegeneinander spielen.

  2. Computerspieler
    Der Computerspieler liefert auf Anfrage des Clients den besten Zug für eine bestimmte Spielsituation zurück.

  3. Client
    Der Client beantragt entweder beim Partie-Manager eine neue Spielpartie und wartet auf einen Gegner, oder er steigt als Gegner in einer vorhandenen Partie ein, die er sich vom Partie-Manager holt.
    Während des Spiels übermittelt er seine Spielzüge an die Spielpartie und stellt das Spielfeld dar. Die zu übermittelnden Spielzüge nimmt er entweder über die Tastatur vom Benutzer entgegen, oder aber er fragt den Computerspieler nach dem im Moment besten Zug.


Für unsere Aufgabe vereinfachen wir diesen prinzipiellen Aufbau folgendermaßen:
Der Partie-Manager und ein Computerspieler laufen auf einem Rechner, es gibt also nur einen Server.


Die Verzeichnisstruktur unserer Anwendung

Alle Dateien, die Sie zur Praktikumsaufgabe benötigen, erhalten Sie weiter unten als Zip-Datei.
Wenn Sie diese entpacken, werden folgende Verzeichnisse mit den darin enthaltenen Dateien angelegt:
Aufgabe1
 |  VierGewinnt.idl
 |  vbroker.csh
 |
 +---ClientAufg1
 |       Client.java
 |
 +---ServerAufg1
         PartieManagerImpl.java
         Partie4GewinntImpl.java
         Meister.java
         Server.java


Die einzelnen Dateien:


Die Java-Klassen sind zusammengefaßt in den Packages ClientAufg1 und ServerAufg1. Ein drittes Package VierGewinnt wird beim Compilieren der IDL-Datei generiert.
Die Package-Dokumentationen zu allen drei Packages finden Sie
HIER.



Ihre Aufgabe:

  1. IDL-Datei vervollständigen

    Ergänzen Sie die Datei VierGewinnt.idl um die Interfaces der Objekte, die per CORBA im Netz bereitgestellt werden sollen.
    Hinweis: Bis auf einen einzigen sind alle Parameter vom Typ in. Lediglich die init-Methode des Spielpartie-Objekts hat einen out-Parameter.

    Compilieren sie anschließend die IDL-Datei mit dem Kommando idl2java VierGewinnt.idl -no_tie.

  2. Server vervollständigen

    Die Datei Server.java ist bisher lediglich ein Gerüst. Machen Sie daraus ein funktionsfähiges Programm, das die oben erläuterten Aufgaben erledigt.

  3. Client vervollständigen

    In Client.java müssen die Methoden
    private static PartieManager holeManager() und
    private static Meister holeMeister(int typ)
    vervollständigt werden.
    Diese Methoden dienen dazu, dem Client den vom Serverprogramm per CORBA bereitgestellten Partie-Manager bzw. Computerspieler zu finden.
    Aufgerufen wird holeManager zu Beginn der main-Methode, holeMeister am Anfang der spielen-Methode des Clients.

  4. Anwendung starten

    Bringen Sie die Anwendung zum Laufen!
Hinweise:



Diese HTML-Seite an sich sowie die Zusammenstellung dieser Programme und Dokumentationen sind urheberrechtlich geschützt.
© 1999 Michael Dom und Wolfgang Westje
Alle Rechte vorbehalten.



Bearbeitungszeitraum für die Aufgabe:
Erste Novemberwoche 1999.

Betreuung der Aufgabe am Donnerstag den 4.November 1999 von 9-11 Uhr im Raum 023 auf dem Sand durch Michael Dom.

Abgabe der Lösungen per E-Mail an Michael Dom:
michael.dom@student.uni-tuebingen.de

Unter dieser Mailadresse können Sie auch jederzeit Fragen zum Thema stellen.

Als Abgabe werden funktionierende Versionen der drei zu vervollständigenden Dateien erwartet.