. Anforderungen
3.1. Problemstellung
3.1.1. Spezifiche Problembeschreibung
3.1.2. Festlegung von Restriktionen
3.2. Nicht-funktionale Anforderungen
3.2.1. Systembezogene Anforderungen
3.2.2. Prozessspezifische Anforderungen
3.2.3. Qualitative Anforderungen
3.3. Funktionale Anforderungen
3.3.1. Die Spieldaten
3.3.2. Die Services/Dienst-Suche
3.3.3. Die JavaSpace-Server-Initialisierung
3.3.4. Die Benutzerschnittstellen
3.3.5. Die Funktionalität der Anwendung
3.3.6. Die Entwicklung und Integration der Spiele
4. Entwurf
4.1. Der Spieldaten Entwurf
4.2. Auffinden der Dienste
4.2.1. Die Klasse ‚ServiceFinder’
4.2.2. Die Klasse ‚ServiceFinderListener’
4.2.3. Klassendiagramm des ‚ServiceFinder’
4.3. Initialisierung des JavaSpace-Servers
4.3.1. Die Klasse ‚JSInit’
4.3.2. Anlegen der Spiel-ID
4.3.3. Anlegen der Spieltypen
4.3.4. Klassendiagramm der JS-Initialisierung
4.3.5. Ablauf der JS-Initialisierung
4.4. Entwurf der Benutzerschnittstelle
4.4.1. Die Client-Oberfläche
4.4.2. Die Oberfläche der Spielerstellung
4.5. Entwurf der Funktionalität
4.5.1. Die Spielerstellung
4.5.2. Der Spielbeitritt
4.5.3. Der Warteraum
4.5.4. Ein Spiel verlassen
4.6. Entwurf der Spielliste
4.6.1. Die Listen-Struktur
4.7. Die Spielerprüfung
4.8. Klassendiagramm des Basissystems
4.9. Entwurf der Spielintegration
4.9.1. Analyse der Spiele
4.9.2. Signaturentwurf der Status-Klasse
4.9.3. Signaturentwurf der Spiele
4.9.4. Entwurf der Spiele
4.9.5. Die Oberfläche der Spiele
4.9.6. Gesamtsystem der Spielintegration
4.9.7. Der Spielablauf
5. Implementierung
5.1. Die Implementierung der Funktionalität
5.1.1. Die Spielerstellungs-Funktion
5.1.2. Die Spielbeitritts-Funktion
5.1.3. Die Warteraum-Funktion
5.1.4. Die Spielverlassen-Funktion
5.1.5. Die Funktion der Spielliste
5.2. Besonderheiten und Probleme der Implementierung
5.2.1. Die Oberflächen
5.2.2. Die dynamische Objekt-Erzeugung
5.2.3. Abbruch von Threads
5.2.4. Funktion der Spielerüberprüfung
5.2.5. Funktion des Spielablaufs
5.3. Verwendete Werkzeuge
6. Bedienung und Installation
6.1. Installation Spieler
6.2. Installation Spielentwickler
6.2.1. Die Dateien der Spielentwickler
6.3. Integration eines neuen Spiels
6.3.1. Aspekte der Implementierung
6.3.2. Aktualisieren des JavaSpace-Servers
Inhalt
1. Einleitung
1.1. Zielbestimmung
1.1.1. Zielsetzung
1.1.2. Kriterien die der Client erfüllen muss
1.1.3. Kriterien die der Client erfüllen kann
1.1.4. Abgrenzungskriterien zu anderen Produkten
1.2. Einsatz
1.2.1. Benutzer und Zielgruppe des Produkts
1.2.2. Einsatzgebiet und Betriebsbedingungen
2. Benötigtes Vorwissen
2.1. Der Geist aus der Flasche (JINI)
2.1.1. Die drei Grundpfeiler
2.1.2. Discovery
2.1.3. Registrierung
2.1.4. Nutzung eines Services
2.2. Das Leasing Prinzip
2.2.1. Was ist Leasing?
2.2.2. Vorteile von Leasing
2.3. JavaSpaces
2.3.1. Die wichtigsten Methoden im Überblick
2.3.2. Das Entry
2.3.3. Idee der Synchronisation
2.4. Weitere wichtige Dienste
3. Anforderungen
3.1. Problemstellung
3.1.1. Spezifiche Problembeschreibung
3.1.2. Festlegung von Restriktionen
3.2. Nicht-funktionale Anforderungen
3.2.1. Systembezogene Anforderungen
3.2.2. Prozessspezifische Anforderungen
3.2.3. Qualitative Anforderungen
3.3. Funktionale Anforderungen
3.3.1. Die Spieldaten
3.3.2. Die Services/Dienst-Suche
3.3.3. Die JavaSpace-Server-Initialisierung
3.3.4. Die Benutzerschnittstellen
3.3.5. Die Funktionalität der Anwendung
3.3.6. Die Entwicklung und Integration der Spiele
4. Entwurf
4.1. Der Spieldaten Entwurf
4.2. Auffinden der Dienste
4.2.1. Die Klasse ‚ServiceFinder’
4.2.2. Die Klasse ‚ServiceFinderListener’
4.2.3. Klassendiagramm des ‚ServiceFinder’
4.3. Initialisierung des JavaSpace-Servers
4.3.1. Die Klasse ‚JSInit’
4.3.2. Anlegen der Spiel-ID
4.3.3. Anlegen der Spieltypen
4.3.4. Klassendiagramm der JS-Initialisierung
4.3.5. Ablauf der JS-Initialisierung
4.4. Entwurf der Benutzerschnittstelle
4.4.1. Die Client-Oberfläche
4.4.2. Die Oberfläche der Spielerstellung
4.5. Entwurf der Funktionalität
4.5.1. Die Spielerstellung
4.5.2. Der Spielbeitritt
4.5.3. Der Warteraum
4.5.4. Ein Spiel verlassen
4.6. Entwurf der Spielliste
4.6.1. Die Listen-Struktur
4.7. Die Spielerprüfung
4.8. Klassendiagramm des Basissystems
4.9. Entwurf der Spielintegration
4.9.1. Analyse der Spiele
4.9.2. Signaturentwurf der Status-Klasse
4.9.3. Signaturentwurf der Spiele
4.9.4. Entwurf der Spiele
4.9.5. Die Oberfläche der Spiele
4.9.6. Gesamtsystem der Spielintegration
4.9.7. Der Spielablauf
5. Implementierung
5.1. Die Implementierung der Funktionalität
5.1.1. Die Spielerstellungs-Funktion
5.1.2. Die Spielbeitritts-Funktion
5.1.3. Die Warteraum-Funktion
5.1.4. Die Spielverlassen-Funktion
5.1.5. Die Funktion der Spielliste
5.2. Besonderheiten und Probleme der Implementierung
5.2.1. Die Oberflächen
5.2.2. Die dynamische Objekt-Erzeugung
5.2.3. Abbruch von Threads
5.2.4. Funktion der Spielerüberprüfung
5.2.5. Funktion des Spielablaufs
5.3. Verwendete Werkzeuge
6. Bedienung und Installation
6.1. Installation Spieler
6.2. Installation Spielentwickler
6.2.1. Die Dateien der Spielentwickler
6.3. Integration eines neuen Spiels
6.3.1. Aspekte der Implementierung
6.3.2. Aktualisieren des JavaSpace-Servers
Zusammenfassung und Ausblick
Anhang 1
Anhang 2
1 Einleitung
1.1 Zielbestimmung
1.1.1 Zielsetzung
Im Rahmen dieser Projektarbeit soll eine verteilte Anwendung entwickelt werden, welche in der Lage ist, über ein Netzwerk Mehrpersonen-Spiele anzubieten und dynamisch zu verwalten. Hierbei soll weniger der Fokus auf die Spiele an sich, sondern auf die Kommunikation und den Datentransport der einzelnen Clients gesetzt werden. Die Hauptaufgabe besteht darin, einen Client auf Basis von Jini und JavaSpaces zu erstellen, welcher Verbindungen zu anderen Spielern aufbaut und die verschiedensten Spiele anbietet. Diese Spiele können durch ‚einfache Integration’ eingebunden werden. Unter ‚einfacher Integration’ versteht man, dass der Anwender seinen Client nicht updaten muss, wenn der Entwickler ein neues Spiel implementiert und integriert! Die Integration eines neuen Spiels soll durch ‚dynamisches Klassenladen’ über einen Webserver stattfinden. Die Abbildung 1.1-1 zeigt den verteilten Aufbau.
Abbildung in dieser Leseprobe nicht enthalten
(Abbildung 1.1 -1)
1.1.2 Kriterien, die der Client erfüllen muss
Der Client muss folgende funktionalen Kriterien nach Abschluss dieser Projektarbeit erfüllen können:
- Ein beliebig ausgewählte Spielpartie erstellen
- Einer erstellten Spielpartie beitreten
- Eine Spielpartie verlassen
- TicTacToe spielen
- Das 100er Spiel spielen
- Verbindung zu den Jini- Diensten aufbauen
- Mehrbenutzerfähigkeit
- Einfache Integration weiterer Spieltypen
- Datentransport ausschließlich über JavaSpaces
- Dynamische Objektverwaltung des JavaSpace-Servers
1.1.3 Kriterien, die der Client erfüllen kann
Weitere Ziele, die das Projekt zwar erfüllen könnte, aber auf die hier verzichtet werden kann, da sie die eigentliche Kernfunktionalität nicht beeinflussen:
- Eine laufende Spielpartie beobachten
- Authentifizierung mit einem Spielernamen
1.1.4 Abgrenzungskriterien zu anderen Produkten
In diesem Punkt möchte ich kurz auf die Abgrenzung der Funktionalität zu anderen Systemen eingehen, welche aber hier bewusst nicht zur Zielsetzung beitragen sollen. Als Gegenüberstellung habe ich den ‚Gamespy’ der Firma Arcarde (http://www.gamespy.com) getestet, welcher von der Grundidee ähnlich ist, sich aber dennoch in folgenden Punkten abgrenzt:
- Wurde in anderer Programmiersprache implementiert (C++)
- Installation nur über das Internet
- Datentransport ist in den Spielen selbst ‚hart programmiert’
- Client-Update bei neuer Spielintegration erforderlich
- GameSpy beinhaltet User Chat und Spielerliste als Feature
1.2 Einsatz
Die Analyse des Einsatzes liefert wichtige Informationen für die Benutzungsoberfläche und die Qualitätsanforderungen des zukünftigen Systems.
1.2.1 Benutzer und Zielgruppe des Produkts
Im Allgemeinen kann man sagen, dass die Anwendung von zwei Gruppen genutzt wird.
- Der ‚ Endanwender ’
- nutzt den Client zum Spielen!
- Der ‚ Spielprogrammierer ’
- Zum einfachen Integrieren neuer Spiele
1.2.2 Einsatzgebiet und Betriebsbedingungen
Der Client soll seinen Einsatz bei jedem Anwender finden, der gerne mit anderen Leuten über ein Netzwerk spielen möchte. Die physikalische Umgebung des Systems wird in den meisten Fällen der Home-PC, eventuell auf einer LAN- Party sein. Weiterhin soll die Anwendung bei Spielprogrammierern zum Einsatz kommen, die mit einfachen Mitteln Mehrpersonen-Spiele anbieten und implementieren möchten. Die Betriebszeit hängt von dem Anwender ab und kann hier nicht definiert werden.
2 Benötigtes Vorwissen
Um das Nachfolgende richtig verstehen zu können, ist es notwendig ein gutes Grundwissen von Java RMI (Remote Method Invocation) zu besitzen. Die folgenden Punkte beziehen sich nur auf die wichtigsten Eigenschaften von Jini und JavaSpaces.
2.1 Der Geist aus der Flasche (JINI)
Auf den ersten Blick erinnert das Wort Jini an den ‚guten Lampengeist’ aus
‚Aladin und die Wunderlampe’
Des Weiteren lässt sich eine nahe Verwandtschaft mit dem Wort Java erkennen.
JINI steht für ‚Java Intelligent Network Infrastructure’ und es handelt sich bei JINI um eine Art Netzwerk-‚Plug & Play’ System, das – analog zum Flaschengeist – jede Art von Diensten bereitstellen kann. Und auch die Wortverwandtschaft zu Java ist kein Trugschluss, da Jini vollständig auf Java basiert und auch dessen Standard-Klassen- Bibliothek nutzt.
2.1.1 Die drei Grundpfeiler
Prinzipiell kann man bei Jini, wie in Abbildung 2.1-1 zu sehen ist, drei Hauptkomponenten ausmachen:
Ein zentraler LookupService-Server stellt den Dreh- und Angelpunkt des gesamten Konzeptes dar. Er muss allen anderen Komponenten zugänglich sein und enthält eine Art Datenbank diverser zuvor registrierter Services, die bei Bedarf ausgeliefert werden können.
Der Service-Server ist der ‚Anbieter’ von Services. Er registriert selbige beim Lookup-Server und führt sie meistens auch aus.
Ein Client bzw. das entsprechende Programm implementiert die Schnittstelle zum Endnutzer und richtet dementsprechend formatierte Service-Wünsche an einen Lookup-Server. Er macht die Services also letztendlich nutzbar.
Alle Komponenten können auf beliebigen Rechnern laufen, die durch ein
‚beliebiges TCP/IP Netzwerk’ verbunden sind.
Abbildung in dieser Leseprobe nicht enthalten
(Abbildung 2.1-1)
2.1.2 Discovery
Sowohl Client als auch Service müssen zunächst Kontakt zu einem Lookup- Service aufnehmen. Hier unterscheidet man zwei Wege :
- Unicast-Lookup
- Multicast- Lookup
Unicast-Lookup wird verwendet, wenn die IP-Adresse des Lookup-Servers bereits bekannt ist. Hier wird also gezielt eine Verbindung hergestellt.
Beim Multicast-Lookup wird per ‚Broadcast’ im so erreichbaren Netzwerk versucht, einen Lookup-Service zu finden. Dieser wird standardmäßig auf Port 4160 ‚lauschen’. Das heißt, eigentlich ‚lauscht’ dort der RMI-Daemon
(s.h. Anhang), welcher dann den Lookup-Service aufweckt. Bei der Suche können Gruppen angegeben werden, die einen solchen Service unterstützen sollen. In jedem Fall liefert nach erfolgreicher Verbindungsaufnahme der Lookup-Service
ein so genanntes ‚Registrar-Objekt (Proxy)
P ’ an den Client bzw. Service
(s.h. Abb. 2.1-2). Dies kann dann zur weiteren Kommunikation genutzt werden. Lookup -Service wird gesucht:
Abbildung in dieser Leseprobe nicht enthalten
(Abbildung 2.1-2)
2.1.3 Registrierung
Mit Hilfe des empfangenen ‚Registrars P ’ kann sich ein Service-Server einen Service mit diversen Eigenschaften registrieren. Dabei werden u.a eine Kopie
des Services bzw. eines Service-Proxies
SP , der später Kontakt zum
eigentlichen Service aufnehmen kann, zum Lookup-Server gesendet
(s.h. Abb. 2.1-3). Der Lookup-Server vergibt bei der erstmaligen Registrierung eine eindeutige ID, welche bei erneuter Anmeldung vom Service-Server oder auch vom Client genutzt werden kann. Je nach Lookup-Service muss die Registrierung regelmäßig erneuert werden. Dies dient z.B. dem Vermeiden von
‚Service-Leichen’. Wenn ein Service registriert ist, kann mit Sicherheit davon ausgegangen werden, dass der Anbieter noch existiert.
Dienst meldet sich an:
Abbildung in dieser Leseprobe nicht enthalten
(Abbildung 2.1-3)
2.1.4 Nutzung eines Services
Ein Client kann den empfangenen ‚Registrar
P ’ benutzen, um einen Service
anzufordern. Dazu muss entweder eine eindeutige ‚Service-ID’, diverse Eigenschaften oder ein konkretes Interface angegeben werden, welches dem gewünschten Service entspreche n . (s.h. Abb. 2.1 -4)
Client nutzt Service:
Abbildung in dieser Leseprobe nicht enthalten
(Abbildung 2.1-4)
2.2 Das Leasing Prinzip
Bislang wurden mit Lookup und Discovery jene Mechanismen vorgestellt, welche für das Auffinden und Bereitstellen von Diensten verantwortlich sind.
Ein wichtiger Bestandteil von JINI ist die ‚Leasing’ Eigenschaft.
Hier wird die Fähigkeit von Selbstheilung und Bewältigung unvermeidbarer Störungen innerhalb eines Netzwerks, Systemabstürzen und Software-Fehlern gewährleistet. Der Aspekt 'Zuverlässigkeit' ist besonders wichtig, wenn Software- Systeme mit geringem oder gar keinem Wartungsaufwand langfristig existieren sollen. Jini stellt dafür einen ‚ LeaseRenewalManager ’ zur Verfügung.
2.2.1 Was ist Leasing?
Leasing basiert auf dem Prinzip, dass Zugriff auf eine Ressource nur für begrenzte Zeit gewährt wird. Die Ressource wird für eine bestimmte Zeitspanne
‚geliehen’. Jini- Leases stellt an Nutzer von Ressourcen bei langfristiger Nutzung die Anforderung regelmäßiger Bestätigung des Bedarfs. Jini- Leases können vom Anbieter des Leases abgelehnt und vom Abnehmer verlängert werden. Leases bieten eine konsistente Möglichkeit für das Entfernen ungenutzter oder nicht mehr benötigter Informationen, um mit den vorhandenen Ressourcen schonend umzugehen.
2.2.2 Vorteile von Leasing
Ein großer Vorteil liegt darin, dass die Wahrscheinlichkeit des Absturzes des gesamten Systems auf ein Minimum reduziert wird.
- Das System verhält sich ‚ vorsichtig ’
Jini vereinheitlicht die Handhabung bestimmter Programmfehler, die Leases werden bei Netzwerkfehlern und Abstürzen von einzelnen Rechnern nicht mehr verlängert.
2.3 JavaSpaces
JavaSpaces sind neben den JINI Diensten das wesentliche Element der Netzwerkkonzepte in Java.
JavaSpaces werden eingesetzt, um Teilnehmer einer JINI Gemeinschaft zu koordinieren. Man kann JavaSpaces losgelöst von JINI als Werkzeug zur Entwicklung verteilter Anwendungen betrachten. In JavaSpaces Anwendungen kommunizieren Prozesse nicht direkt miteinander, sondern sie koordinieren ihre Aktivitäten, indem sie Objekte mit Hilfe eines Spaces, eines gemeinsamen Speicherbereichs, austauschen.
Ein Prozess kann ein neues Objekt in ein Space schreiben (write()), lesen (read()) oder entfernen (take()). Die Prozesse rufen keine Methoden im Space auf. Spaces dienen nur zur Objektspeicherung. Um ein Objekt zu verändern muss ein Prozess dieses aus dem Space kopieren oder herausholen, modifizieren und wieder in den Space schreiben. Die Abbildung 2.3 zeigt die Grundfunktionen:
Abbildung in dieser Leseprobe nicht enthalten
(Abbildung 2.3)
Jeder Prozess wird hier als ‚Duke’ dargestellt. Zum Herausholen oder Lesen
eines Objekts wird ein ‚Matching-Algorithmus’ verwendet. Falls kein Objekt mit den angegebenen Suchkriterien existiert, kann der Prozess warten, bis ein gesuchtes Objekt eintrifft. Spaces sind Objektspeicher mit mehreren wichtigen Eigenschaften, welche sie zu einem mächtigen Werkzeug machen.
2.3.1 Die wichtigsten Methoden im Überblick
Ablegen von Objekten
Lease write(Entry entry, Transaction txm, long lease)
Lesen von Objekten
Entry read(Entry Template, Transaction txm, long timeout)
Entry readIfExsits(Entry Template, Transaction txm, long Timeout)
Entfernen von Objekten
Entry take(Entry Template, Transaction txm, long Timeout)
Entry takeIfExsits(Entry Template, Transaction txm, long Timeout)
2.3.2 Das Entry
Ein Objekt, welches in einem Space gespeichert werden soll, bezeichnet man als ‚ Entry’. Um ein Entry zu sein, muss das Objekt das Interface Entry implementieren.
Ein Beispiel:
import net.jini.core.entry.Entry;
public class Nachricht implements Entry
{
public String einString;
// Ein Konstruktor ohne Argumente public Nachricht()
{ }
}
Diese Klasse besitzt ein String- Attribut, welches eine Nachricht aufnehmen kann. Entry ist ein ‚ marker Interface’. Es besitzt somit keine Konstanten oder Methoden und ist daher recht einfach zu implementieren. Jedes Feld eines Entry muss ‚ public ’ sein. Man kann keine Basistypen in einem Entry abspeichern. Ein Entry kann eine beliebige Anzahl von Konstruktoren haben.
2.3.3 Idee der Synchronisation
JavaSpaces könne n sehr gut zur Kommunikation und Koordination in verteilten Java-Anwendungen eingesetzt werden.
Zum Beispiel kann man JavaSpaces zur Koordination schnell veränderlicher JINI-Umgebungen, Umgebungen in denen Entities verfügbar und nicht verfügbar sind, einsetzen. JavaSpaces garantiert Synchronisation auf Entry Ebene. Durch den geschickten Einsatz dieser Entries können also Zugriffe und Aktivitäten synchronisiert werden.
Es ergibt sich folgendes Grundmuster der Synchronisation:
- Lesen eines vorhandenen Entry ist jederzeit möglich (auch von mehreren Prozessen)
- Ändern eines Entry ist jeweils nur durch einen Prozess möglich. Dabei wird das Entry erst aus dem Space entfernt, dann verändert. Damit ist es exklusiv verfügbar. Danach wird es wieder in den Space zurück geschrieben.
‚Read(), write()’ und ‚ take()’ Operationen erzwingen einen koordinierten Zugriff auf Entries. Dieser Mechanismus muss verstanden worden sein, da er als Grundlage in der zu implementierenden Anwendung dient.
2.4 Weitere wichtige Dienste
- Ein Webserver
Jini erfordert diesen, da das Herunterladen von RMI-Code mit Hilfe des HTTP-Protokolls erfolgt.
- TransactionManager (MAHALO)
Mit Hilfe von Transaktionen kann Jini erreichen, dass Berechnungen unter Beteiligung mehrerer Dienste sicher ausgeführt werden können. Der Aufrufer wird darüber informiert, ob die Berechnung vollständig oder gar nicht verarbeitet wurde. In beiden Fällen existiert ein bekannter Zustand. Dies Modell schützt vor Tücken und teilweiser Ausfälle innerhalb verteilter Systeme.
- Den RMI-Aktivierungs-Daemon (RMID)
Der Aktivierungs-Dienst ist sehr einfach verwendbar und stellt einen sehr nützlichen Bestandteil der Java-Infrastruktur dar. Der RMID ermöglicht Objekten, die nur selten gebraucht werden, gewissermaßen ‚einzuschlafen’, um bei Bedarf automatisch geweckt zu werden. Der RMID reguliert das Wechseln zwischen den aktiven und inaktiven Zuständen solcher Objekte und wird von den anderen grundlegenden Jini-Diensten ausgiebig genutzt. Der RMID muss auf jedem Host laufen, auf dem auch der Lookup-Dienst beschrieben wird.
3 Anforderungen
3.1 Problemstellung
In diesem Teil der Dokumentation wird gezielt auf die Problemstellung und den dabei auftretenden Problemen eingegangen werden. Dabei werden keinerlei Funktionen genau definiert oder Lösungsvorschläge gegeben.
3.1.1 Spezifische Problembeschreibung
Wie bereits aus der Zielsetzung hervorgeht, ist eine verteilte Anwendung zu entwickeln, welche auf Basis von Jini und JavaSpaces einen Client repräsentieren soll, mit dem man die verschiedensten Spiele über eine TCP/IP Verbindung nutzen kann. Dazu soll eine übersichtliche Oberfläche erstellt werden, die dem Nutzer bei Programmstart die Möglichkeit gibt, eine Spielpartie zu erstellen, einer erstellten Partie beizutreten, eine laufende Partie als Beobachter zu verfolgen und den Client wieder beenden zu können. Möchte der Anwender eine neue Spielpartie erstellen, soll er sich aus einer Auswahlliste ein Spieltyp selektieren und die Spielerzahl mit angeben. Um zu sehen, welche Partien bereits erstellt wurden, wird eine Liste benötigt, über die man eine Spielpartie selektieren kann um dieser beizutreten, oder sie zu beobachten. Aus der Liste muss ersichtlich sein, um welchen Spieltyp es sich handelt, wie viele Spieler der Spieltyp erfassen kann, wie viele bereits zu dieser Spielpartie beigetreten sind und wie der momentane Spiels tatus ist. Der Status soll Information über den momentanen Zustand der Spielpartien in Form von ‚offen’,
‚läuft’ oder ‚beendet’ liefern. Diese Liste muss immer aktuell gehalten werden. Dies kann automatisch vom Programm nach interner Zeitvorgabe, oder vo m Benutzer manuell erledigt werden. Hat man eine Partie erstellt oder ist zu einer erstellten Spielpartie beigetreten, soll man in eine Art ‚Warteraum’ geführt werden, in dem man die Partie auch wieder verlassen kann. Auch im Spiel selber muss die Möglichkeit bestehen, das laufende Spiel wieder verlassenoder den Client komplett beenden zu können. Hierbei ist eine ständige Aktualisierung der erforderlichen Spieldaten und die Reinigung des JavaSpace-Servers notwendig. Die wichtigste Anforderung liegt jedoch in der dynamischen Integration bzw.
Objekt-Instanzierung eines neuen oder ausgewählten Spiels (Instanzierung bedeutet die Erzeugung von realen Instanzen (Objekten)). Hierbei ist zu beachten, dass die Datenhaltung so einfach wie möglich gehalten wird, um eine spätere problemlose Integration eines neuen Spiels zu gewährleisten. Der Nutzer des Clients soll die Integration nicht bemerken. Er muss seinen Client keinem Update unterziehen, um das neue Spiel nutzen zu können. Genau an dieser Stelle liegt der Kernpunkt dieses Projekts. Es soll gezeigt werden, wie mit Hilfe der Eigenschaften von Jini und JavaSpaces eine solch komplexe Anwendung einfach erstellt werden kann. Am Ende der Arbeit soll eine Anleitung verfasst werden, die die Integration eines neuen Spiels so einfach wie möglich beschreibt.
3.1.2 Festlegung von Restriktionen
Im Laufe der Projektarbeit mussten einige Abgrenzungen und Festlegungen getroffen werden, um den Umfang der Anwendung zu reduzieren bzw. die Funktionalität eindeutig beschreiben zu können.
Der Initiator einer neu erzeugten Spielpartie erhält immer die Spielernummer eins. Dieser Spieler soll das Spiel eröffnen und den ersten Zug tätigen.
Wird ein laufendes Spiel verlassen oder freiwillig beendet, sollen alle beteiligten Mitspieler eine Nachricht bekommen und die Verbindung wird getrennt. Hier geht keiner als Gewinner oder Verlierer aus der Partie.
Handelt es sich um Spiele wie z.B. TicTacToe oder Schach, bei denen eine feste Spielerzahl von zwei vorgegeben wird, soll die Spielerzahl als ‚fixed’ gesetzt werden. Hier darf der Anwender die Spieleranzahl nicht verändern können.
Hat das ausgewählte Spiel seine Höchstspielerzahl erreicht, soll es automatisch gestartet werden. Die Speicherung und Kommunikation der benötigten Spieldaten soll ausschließlich mit Jini und einem JavaSpace-Server geschehen. Um die einzelnen Spiele untereinander zu unterscheiden, muss dem jeweiligen Spieltyp eine eindeutige Spielnummer (ID) mitgegeben werden. Die Initialisierung dieser ID soll genau einmal erfolgen. Die ID sollte daher in einem separaten-Entry (s.h . Punkt 2.3.2) abgespeichert werden. Auch bei späterer Spielintegration muss die Information des Spieltyps wegen der Aktualisierung des Clients in einem separaten-Entry festgehalten werden. Ist der JSS nicht verfügbar bzw. ‚abgestürzt’, muss dies geschickt abgefangen werden und der Client soll eine Nachricht an den Anwender senden.
3.2 Nicht-funktionale Anforderungen
Anforderungen an das System, welche den Freiheitsgrad bei Konstruktion des Systems (also die Umsetzung der funktionalen Anforderung) einschränken.
3.2.1 Systembezogene Anforderungen
Das zu entwickelnde System soll auf allen gängigen Betriebssystemen laufen. Aus diesem Grund soll die Anwendung in Java programmiert werden. Die Benutzerschnittstelle soll mit einer Auflösung von 800 x 600 Bildpunkten noch voll darstellbar sein. Auf dem Client-Rechner müssen Java und Jini fertig konfiguriert vorhanden sein. Auf der Serverseite müssen folgende Dienste zur Datenübertragung und Kommunikation laufen:
- RMID
- Webserver
- TransactionManager (MAHALO)
- Lookup Dienst (REGGIE)
- JavaSpaces (OUTTRIGGER)
Eine genaue Anleitung zur Inbetriebnahme der einzelnen Dienste ist auf
http://wwwmath.uni-muenster.de/u/versys/courses/SoSe2001/VS/EXAMPLES/Installation.pdf
zu finden.
3.2.2 Prozessspezifische Anforderungen
Das System muss innerhalb der angegebenen Projektfrist von einem Semester einsatzbereit sein. Die Entwicklungsumgebung ist vom Programmierer der Anwendung bereit zu stellen und zu konfigurieren. Die Entwicklung des Systems soll von Zuhause aus erledigt werden. Die Testläufe können im Projektraum an der Fachhochschule Trier ausgeführt werden. Parallel sind ständige Absprachen mit dem Auftraggeber notwendig, welche wöchentlich stattfinden können. Hierbei ist dem Auftraggeber eine Ausarbeitung der letzten Woche schriftlich oder am Rechner vorzuführen. Parallel zur Entwicklung des Systems, muss ein Pflichtenheft/Dokumentation geführt werden, welches bei Fertigstellung des Projekts dem Auftraggeber ausgehändigt werden muss.
3.2.3 Qualitative Anforderungen
Die Anwendung soll eine übersichtliche Benutzerschnittstelle haben. Weiterhin soll die Software leicht änderbar und erweiterbar sein. Das System soll Vertraulichkeit und Sicherheit gewährleisten. Weitere Spiele sollen ohne Schwierigkeiten integrierbar sein. Da es sich hierbei um eine verteilte Anwendung handelt, müssen Rechnerabstürze oder Serverausfälle berücksichtigt werden. Die Performance soll im Hinblick auf eine eventuell große Benutzeranzahl ausreichend sein.
3.3 Funktionale Anforderungen
Im Gegensatz zur Spezifikation wird in diesem Abschnitt nun gezielt auf die Funktionalität eingegangen. Dazu wird anhand von Modellen der Sachverhalt der Funktion verdeutlicht. .
3.3.1 Die Spieldaten
Hier soll darauf geachtet werden, dass keine unnötigen Attribute verwendet werden und dass die Namensgebung aussagekräftig ist. Die Anwendung soll die Eigenschaft besitzen, ohne großen Aufwand erweitert werden zu können. Dies stellt eine große Herausforderung dar, weil die Daten sowohl für Schach als auch für Skat oder andere Spiele geeignet sein müssen.
Man muss spielerspezifische Daten, wie zum Beispiel die Spielernummer, ablegen können. Jeder Spieler, der dem Spiel beitritt, muss eine eindeutige Spielernummer zugeteilt bekommen.
Die maximale Anzahl der Mitspieler muss für den ausgewählten Spieltyp bei der Erstellung des Spiels abgespeichert werden. Außerdem muss eine Grenze vorhanden sein, die Auskunft darüber gibt, wann der letzte der Maximal zulässigen Mitspieler eines Spieltyps eingetroffen ist.
Wird nun die ‚Beitrittsgrenze’ erreicht, muss das Spiel als ‚Voll’ deklariert werden. Dazu reicht ein Wahrheitswert aus. Auch um das Spielende festzuhalten reicht ein Wahrheitswert, der sagt, ob das Spiel zu Ende ist oder nicht. Um auf ein bestimmtes Spieldatenobjekt zugreifen zu können, muss dies durch eine eindeutige ID gekennzeichnet sein. Man soll ein bestimmtes Spiel aus einer Liste selektieren können, um es zu spielen. Hier muss der Spielname als String angegeben werden, über den man auch später die Klasse identifizieren muss.
Daher hat der Spielname ebenso wie die ID eine wichtige Rolle und kann nicht vernachlässigt werden. Eine der wichtigsten Attribute ist der Spielstatus. Der Spielstatus gibt den aktuellen Zustand des laufenden Spiels an. An dieser Stelle muss abstrahiert werden, da es verschiedene Spiele geben kann, die man vorher nicht kennt. Dieser Sachverhalt ist unter Punkt 4.9.2 nachzuschlagen. An dieser Stelle nehmen wir an, dass wir ein Objekt des Typs ‚ SpielStatus ’ abspeichern müssen. Zur Spielkoordination muss eine Variable bereitgestellt werden, die sagt, welcher Spieler gerade am Zug ist.
Zusammenfassend werden folgende Anforderungen an die Daten gestellt:
- Eine eindeutige Spiel-ID
- Dynamisch zugeteilte Spielernummer
- Der Spielname des Spiels
- Der Spielstatus des jeweiligen Spiels
- Anzahl der maximalen Mitspieler
- Spieler, der am Zug ist
- Maximale Mitspieleranzahl einer Spielpartie ist erreicht
- Eine Spielpartie ist beendet oder nicht
3.3.2 Die Services/Dienst-Suche
Die Anwendung soll auf Basis von Jini und JavaSpaces implementiert werden. Um überhaupt zu wissen, was Jini und JavaSpaces sind wurden in Abschnitt 2 die wichtigsten Eigenschaften erläutert. Hier besteht nun die Anforderung in der Suche der Services und dem Verbindungsaufbau zu dem JavaSpace-Server.
Hierzu müssen zunächst die in Punkt 3.2.1 angegebenen Dienste/Server auf dem PC laufen. Die Anwendung muss sich nun die einzelnen Services suchen und die Verbindungen aufbauen. Dazu müssen Referenzen beschafft werden, mit denen man die einzelnen Services ansprechen kann. Es muss eine Verbindung zum
‚ JavaSpace’ -Server geschaffen werden, der ‚ TransactionManager’ soll zum Einsatz kommen und es muss eine Verbindung bzw. Referenz zum
‚ LeaseRenewalManager’ bestehen.
Die Anwendung soll sich sozusagen selbst verwalten, was durch den geschickten Einsatz der Jini- Lease-Eigenschaften und den Transaktionen erledigt werden soll.
Zusammenfassend werden folgende Anforderungen gestellt:
- Verbindungsaufbau zu dem ‚ JavaSpace ’-Server
- Verbindungsaufbau zum ‚ TransactionManager ’
- Verbindungsaufbau zum ‚ LeaseRenewalManager ’
- Koordination mittels Transaktionen
- Dynamische Objektverwaltung durch Angabe von Leases
3.3.3 Die JavaSpace-Server-Initialisierung
In diesem Teil soll der Blick auf die anfängliche JavaSpace-Server- Initialisierung gerichtet werden. Hierbei sei angemerkt, dass die Initialisierung von einem beliebigen Punkt aus der Jini- Gemeinschaft getätigt werden soll.
Der Grund dieser Initialisierung liegt darin, dass man sicherstellen muss, nur
‚genau eine ’ ID zu haben. Würde die Initialisierung hart in den Client programmiert, könnte der Fall auftreten, dass zwei Clients gleichzeitig eine neue ID schreiben und es somit ein Synchronisationsproblem geben würde. Also liegt die erste Anforderung darin, eine Art ‚Initialisierungs-Server’ zu implementieren, welcher die Aufgabe hat, die ID sicher in den JavaSpace-Raum zu schreiben. Dieser Server soll weitgehend unabhängig vom übrigen Programmcode sein. Dazu muss eine extra Entry-Klasse, welche eine Integerzahl repräsentiert, geschrieben werden. Eine weitere Aufgabe dieses Servers soll darin bestehen, auch die Initialisierung der Spieltypen zu übernehmen. Dies ist ein wichtiger Aspekt im Hinblick auf die dynamische Spiel-Integration. Diesem
‚Spieltyp-Objekt’ müssen demzufolge auch die notwendigen Attribute mitgegeben werden, welche diesen Typ repräsentieren. Eine separate-Entry- Klasse muss auch in diesem Fall geschrieben werden. Die Entry-Klasse speichert neben dem Spielnamen auch Informationen darüber, wie viele Mitspieler diesen Typ spiele n können (Schach hat genau 2 Spieler), und ob dieser Wert durch den Benutzer veränderlich ist oder nicht. Auch hier hat der Server die Aufgabe diese Objekte zu verwalten. Im Falle eines Ausfalls sollen diese Objekte verfallen.
Folgende Anforderungen lassen sich daraus ableiten:
- Initialisierungsserver implementieren
- Server soll nicht vom Client abhängig sein
- Server soll ID-Objekt erzeugen und schreiben
- ID-Entry implementieren
- Server soll Spieltypen erzeugen und schreiben
- Spieltyp-Entry implementieren
- Einsatz der Lease-Eigenschaft zwecks Überwachung
3.3.4 Die Benutzerschnittstellen
Die Benutzerschnittstelle hat einen großen Einfluss auf die weitere Vorgehensweise bei der Implementierung. Daher sollte die Schnittstelle zum Benutzer mö glichst einfach zu bedienen, übersichtlich und mit den grundlegenden Funktionalitäten ausgestattet sein. Hier ist eine Absprache mit dem Auftraggeber unumgänglich.
Die zu verwendenden Buttons sollen gut angeordnet und mit einer aussagekräftigen Beschriftung gekennzeichnet sein. Eine weitere wichtige Anforderung besteht darin, auf eine unübersichtliche Verschachtelung von Menüs und deren Untermenüs zu verzichten, da viele aufgeklappte Fenster dem Nutzer die Übersicht erschweren. Wird aus der Hauptoberfläche nun eine neue Spielpartie erstellt, sollen deren Buttons deaktiviert werden, damit der Anwender kein zweites Spiel (oder mehr) anlegen, oder zu einer bereits eröffneten Partie beitreten kann. Aus der in Punkt 3.1.1 angegebenen Spezifikation sollen folgende Elemente auf der Hauptoberfläche vorhanden sein:
- Button zum Spiel erstellen
- Button zum Spiel beitreten
- Button zum Spiel beobachten
- Button zum Client beenden
- Eine Liste der derzeitig angebotenen Spiele
- Button zur manuellen Aktualisierung dieser Liste
Möchte man nun als Initiator ein Spiel erstellen, muss man die spielspezifische n Daten angeben und natürlich den Spieltyp auswählen können. Dazu soll eine neue Oberfläche programmiert werden, welche diese Auswahlelemente beinhaltet.
- Auswahlbox für den Spieltyp
- Auswahlbox für die Spieleranzahl des Typs
- Button, um die angegebene Spielpartie zu erstellen
- Button, um wieder zurück zur Hauptoberfläche zu gelangen
Wurde das Spiel erstellt, soll man in den Warteraum geschickt werden um auf weitere Mitspieler zu warten. Hier muss die Möglichkeit bestehen, den Warteraum wieder verlassen zu können. Auch bei der Funktion ‚ beitreten ’ soll der Benutzer in den Warteraum des ausgewählten Spiels eintreten.
- Warteraum- Dialog erstellen
- Button, um Warteraum zu verlassen
3.3.5 Die Funktionalität der Anwendung
Die einzelnen Funktionen, die der Client dem Nutzer anbietet, werden in den folgenden Anforderungen dargelegt.
- Eine neue Spielpartie erstellen
Als erstes soll der Anwender die Möglichkeit haben, ein Spieltyp seiner Wahl erstellen zu können. Drückt er den zugehörigen Button ‚ Erstellen ’, muss sich die passende Oberfläche mit den angebotenen Spieltypen öffnen. Hier kann er einen Spieltyp auswählen und erstellen. Hat der Anwender ein Spiel erstellt, darf er keine zweites eröffnen.
- Einer angelegten Spielpartie beitreten
Wurde nun eine neue Spielpartie erstellt, muss den anderen Mitspielern die Möglichkeit gegeben werden, bei dieser Partie mit einzusteigen.
Die Partie muss aus der Spielliste selektierbar sein und mit Betätigung des Beitret-Buttons soll der Spieler mitspielen können. Ist das gewünschte Spiel bereits mit seiner Höchstspielerzahl belegt, soll eine dementsprechende Meldung erscheinen.
- Der Spieler Warteraum
Laut Restriktion aus Punkt 3.1.2 soll das Spiel gestartet werden, wenn der letzte Spieler sich im Warteraum eingefunden hat. Dazu muss ein Warteraum für die Spieler erstellt werden, indem alle Spieler sich sammeln. Es muss geprüft werden, wann der letzte Spieler eingetroffen ist. Wenn es soweit ist, sollen die Objekte des ausgewählten Spiels dynamisch zur Laufzeit erzeugt werden. Erst dann kann gespielt werden.
- Eine offene oder laufende Spielpartie verlassen
Eine weitere Anforderung liegt darin, ein Spiel wieder verlassen zu können. Die Hauptaufgabe besteht in der Reinigung des JavaSpace- Servers von den Spielobjekten. Wird eine laufende Spielpartie verlassen, sollen alle beteiligten Mitspieler eine Nachricht bekommen und das Spielobjekt muss entfernt werden. Hat die Partie noch nicht begonnen und ein Mitspieler verlässt den Warteraum, soll der Platz für einen anderen Spieler freigegeben werden. Sollte der Initiator den Warteraum verlassen, müssen alle bisher eingetretenen Spieler eine Nachricht bekommen und das angelegte Objekt muss entfernt werden. Hierbei darf die Anwendung nicht abstürzen oder hängen bleiben.
- Den Client beenden
Wird der Client beendet muss sichergestellt sein, das sich der Spieler nicht in einer Spielpartie oder im Warteraum befindet. Sollte dies der Fall sein, muss zuvor die Spielpartie beendet werden. Hier gilt auch die Anforderung wie bereits im Punkt ‚ eine offene oder laufende Spielpartie verlassen ’ beschrieben wurde. Befindet sic h der Spieler nicht im laufenden Spiel, oder im Warteraum, wird der Client regulär beendet.
[...]
-
-
-
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X. -
-
¡Carge sus propios textos! Gane dinero y un iPhone X.