VRML (Virtual Reality Modelling Language, gesprochen
Vörmel) ist ein Dateiformat zur Beschreibung von interaktiven, dreidimensionalen
Multimediaobjekten im Internet. Eine VRML-Datei enthält die plattformunabhängige
Beschreibung von 3D-Objekten und ihrem Verhalten. Eine solche Beschreibung
wird auch Welt genannt.
Entwickelt wurde VRML 1994 von Mark Pesce und Tony
Parisi, die eine erste Spezifikation des Formates (VRML 1.0) auf der ersten
World Wide Web-Konferenz in Genf vorstellten. Inzwischen ist VRML von der
ISO unter dem Akronym VRML 97 standardisiert
[VRML97].
Die weitere Entwicklung und Pflege der Sprache wird jetzt vom VRML Konsortium
überwacht und koordiniert. Während VRML97 alle Mechanismen für
die Darstellung einfacher Animationen zur Verfügung stellt, verfügt
es nicht (und das war auch nie beabsichtigt) über die volle Funktionalität
einer Programmiersprache. Für anspruchsvolle Animationen, die Statusinformationen
speichern müssen oder von nichtlinearer Interpolation Gebrauch machen,
reicht die Funktionalität von VRML alleine nicht aus. Deshalb ist
es möglich sich die Funktionalität existierender Programmiersprachen
in VRML über sogenannte
Script Nodes zunutze zu machen. Eine
Programmiersprache die sich in diesem Zusammenhang hervorragend eignet
ist Java. VRML in Verbindung mit der Programmiersprache Java ermöglicht
es plattformunabhängig komplette, interaktive dreidimensionale Welten
im Internet zu gestalten
[Bru98].
Diese Möglichkeiten nutzten Stephen White und
Jeff Sonstein aus und entwickelten das VRML- Network (VNet). Das VNet ist
ein VRML- Mehrbenutzersystem, das es mehreren Benutzern ermöglicht,
sowohl untereinander, als auch mit ihrer Umwelt interagieren zu können.
Die Interaktion der Benutzer untereinander erfolgt über sogenannte
Avatare, das sind frei wählbare 3D-Grafik Repräsentationen der
Benutzer, die nicht notwendigerweise eine humanoide Gestalt aufweisen müssen.
Mit Hilfe seines Avatars kann sich der Benutzer im VR-System unbeschränkt
bewegen und über Interaktionen die Welt buchstäblich erfahren.
Das VNet wird zur Zeit ausschließlich als eine Art Chat room
(Mehrbenutzersystemm, indem die Teilnehmer miteinander Textnachrichten
austauschen können) genutzt allerdings sind die Möglichkeiten
hier gegenüber einem normalen Chat room wesentlich erweitert.
Man kann zum Beispiel die anderen Benutzer über ihre Avatare sehen.
Wenn in einem normalen" Chat room viele Benutzer
simultan reden, ist es mitunter wegen der vielen unterschiedlichen Meldungen
schwer dem Gesprächsfluß zu folgen. Im VNet ist das Problem
dadurch gelöst, daß der Text, den ein Benutzer eingibt nur den
Mitbenutzern angezeigt wird, deren Avatare sich in einem Radius von 30
Metern um diesen Benutzer befinden. Dadurch ist es auch sehr leicht möglich
eine separate Gruppe zu bilden, indem man einfach mit seinen Gesprächspartnern
einen anderen Ort in der Welt aufsucht.
Dieses kurze Beispiel zeigt schon sehr deutlich,
welche enormen Möglichkeiten in dieser neuen Technologie in Verbindung
mit dem Internet stecken. Man kann sich leicht auch Anwendungen in anderen
Gebieten vorstellen, wie Telekooperation von CAD Konstrukteuren, begehbare
Baupläne von Gebäuden, Spiele und virtuelle Trainingsgelände
für militärische Anwendungen. Was über all diese Möglichkeiten
hinaus das VNet so interessant macht, ist die freie Verfügbarkeit
des Quellkodes im Internet, so daß ein interessierter Leser die Möglichkeit
hat, entweder mit einem VRML-fähigen Browser (Bsp.: Win95,
Netscape
4.0 und
CosmoPlayer-Plug-in)
direkt in eine der Welten des VNet zu gehen oder durch die Installation
des Server- und Clientcodes auf einem Webserver seine eigene Welt kreieren
kann.
Die Intention dieses Beitrags ist es, die Implementation
des VNet anhand des Quellkodes zu untersuchen und darzustellen. Deshalb
soll als erstes mit der Beschreibung der Architektur des VNet begonnen
werden.
[Zurück zum Inhaltsverzeichnis]
2 Die Architektur des VNet
Das VNet beruht auf einer typischen Client/Server-Architektur
(siehe
Abb. 1). Zunächst soll dieses Prinzip kurz
erläutert werden und anschließend dessen Relevanz für das
VNet aufgezeigt werden.
Unter Client/Server-Architektur versteht man üblicherweise
die Aufteilung einer Softwarekomponente, die einen bestimmten Dienst erbringt,
in zwei Teilkomponenten, die um diesen Dienst zu erbringen beispielsweise
über ein Rechnernetz miteinander Nachrichten austauschen.
Eine dieser beiden Komponenten, der Server, ist ein
Programm, das ständig auf einem Rechner läuft und auf eine Verbindungsaufforderung
durch einen Client wartet, um diesem seine Dienste anzubieten. Hat sich
ein entsprechender Client beim Server mit einem Verbindungswunsch angemeldet,
und dieser die Verbindung akzeptiert, so führt der Server seinen Dienst
aus und sendet das Ergebnis zum Client zurück.
Analog dazu versteht man unter einem Client eine
Softwarekomponente, die eine Anforderung für einen Dienst an einen
bestimmten Server schickt und nach Erfüllung des Dienstes auf die
entsprechende Rückantwort wartet.
Auch das VNet ist auf diese Weise implementiert (siehe
Abb. 2). In den folgenden Abschnitten wird die Client/Server-Architektur
exemplarisch am Beispiel des Verbindungsaufbaus zwischen VNet-Client und
VNet-Server beschrieben. Es wird dabei auch, falls nötig, auf Implementationsdetails
eingegangen. Die entprechenden Quellen dazu findet man unter
[VNet-Source-Code].
2.1 Verbindungsaufbau des VNet-Client
zum VNet-Server
Wenn ein Benutzer eine der Multi-Userwelten des VNet
besuchen möchte dann muß er auf der VNet-Homepage einen der
Links zu den verschiedenen VRML-Welten anklicken. Dadurch wird eine Anfrage
an den entsprechenden Webserver geschickt, eine bestimmte HTML-Seite (
EAIVNet.html ) auf den lokalen Rechner zu laden. Auf dieser Seite befindet
sich ein Applet ( EAISceneInterface ) dieses Applet stellt den gesammten
VNet-Client dar. Nachdem der lokale Browser festgestellt hat, daß
sich ein Applet auf der HTML-Seite befindet, wird Java gestartet und der
Java Classloader lädt das Applet einschließlich aller referenzierten
Klassen auf den lokalen Rechner und startet es.
Damit läuft der VNet-Client auf dem lokalen
Rechner und holt sich als nächstes mittels getWorldURL() die URL,
an der der VRML-Code für die angewählte Welt liegt. Danach werden
Objekte erzeugt, die die Benutzerschnittstelle aufbauen ( TalkerPanel
). Hier kann der Benutzer seinen Namen eingeben und einen Avatar wählen.
Nachdem dies geschehen ist, kann er den Verbindungsaufbau zum VNet-Server
starten.
Dies führt dazu, daß ein Objekt der Klasse
Dispatcher erzeugt wird. Das Dispatcherobjekt dient dazu die Kommunikation
mit dem VNet-Server über das VRML-Interchange-Protocol (VIP) abzuwickeln.
Zu diesem Zweck wird ein eigener Thread ( ClientThread ) erzeugt,
der die Verbindung zum VNet-Server aufbaut. Unter einem Thread versteht
man den Träger einer Aktivität, mit eigenem Kontrollfluß,
die Unabhängig innerhalb eines Programms ausgeführt werden kann.
Innerhalb von ClientThread wird ein Socket erzeugt, der den Kommunikationsendpunkt
zum VNet-Server darstellt. An diesen Socket werden dann noch Datenein-
und ausgabeströme gebunden, die zum Lesen und Schreiben auf das Übertragungsmedium
benötigt werden.
Schließlich wird noch ein weiterer Thread erzeugt,
der in den Ausgabestrom schreibt und für die abzusendenden Nachrichten
ein Warteschlange verwaltet. Damit ist die Verbindung zum VNet-Server hergestellt
und die Kommunikation kann beginnen.
2.2 Verbindungsaufbau des VNet-Server
zum VNet-Client
Auf der Serverseite stellt sich der Verbindungsaufbau
folgendermaßen dar:
Zunächst muß der Server bereits gestartet
sein bevor ein Client eine Verbindung zu ihm aufbauen kann. Beim starten
des Servers mittels
java VSystem(port);
wird im Hauptthread des Programms zunächst ein
serverSocket erzeugt und an den angegebenen port gebunden.
Danach ist der VNet-Server bereit, eingehende Verbindungsanforderungen
von VNet-Clients entgegenzunehmen.
Trifft nun eine Verbindungsanforderung eines VNet-Clients
ein so wird durch die Methode accept() , der serverSocketklasse
eine Verbindung zu diesem aufgebaut. Danach wird ein neuer Thread erzeugt,
der diese Verbindung bedient, so daß der Hauptthread wieder für
neue Verbindungsanforderungen frei ist. Innerhalb dieses threads wird anschließend
ein VUserobjekt erzeugt, das von VObject abgeleitet ist und
Benutzerdaten vorhält (Bsp: Eine eindeutige Kennung für den Client,
Benutzername usw.) sowie die Kommunikation mit dem verbundenen VNet-Client
abwickelt.
Weiterhin werden auch hier Ein- und Ausgabedatenströme
für die Kommunikation angebunden und ein Objekt der Klasse writerThread
gestartet, das wartende Nachrichten verwaltet und in den Ausgabestrom schreibt.
Damit ist auch für den Server der Verbindungsaufbau abgeschlossen
und VNet-Client und VNet-Server können miteinander über das VI-Protokoll
Nachrichten austauschen.
Der VNet-Server erzeugt für jeden VNet-Client
der sich anmeldet einen eigenen Thread, der für die Kommunikation
mit dem jeweiligen VNet-Client zuständig ist. Das heißt, daß
die einzelnen VNet-Clients über den VNet-Server miteinander verbunden
sind und dadurch miteinander kommunizieren können.
Aus den bereits geschilderten Abläufen, läßt
sich deutlich die Client/Server-Architektur des VNet erkennen. Jeder VNet-Client
lädt sich nach dem Starten eine lokale Kopie der Multiuser-VRML-Welt.
Alle Interaktionen (Bewegungen, Skalierungen, usw.) zwischen Benutzer und
Welt werden auf dem lokalen Rechner berechnet, gerendert und schließlich
dargestellt. Falls andere Benutzer (Clients) von einem solchen Ereignis
informiert werden müssen, so schickt der VNet-Client eine entsprechende
Nachricht an den VNet-Server, der sie dann an die anderen VNet-Clients
weiterleitet. Damit ist gewährleistet, daß alle Benutzer in
ihrer Welt das gleiche sehen und den Eindruck haben sie seien in einer
gemeinsamen Welt. Ein Vorteil bei diesem Vorgehen ist, daß die Netzbelastung
relativ gering bleibt, da z.B. dreidimensionale Objekte nur anhand ihrer
geometrischen Beschreibung übertragen werden. Allerdings muß
dies mit einer erhöhten Rechenleistung auf dem lokalen Rechner erkauft
werden, da dort die Berechnung und Darstellung der Daten erfolgt. Der eigentliche
Dienst des VNet-Servers hierbei ist, daß er als Verteiler für
sämtliche Ereignisse dient, die die Benutzer in der VRML-Welt auslösen.
[Zurück zum Inhaltsverzeichnis]
3 Das VRML Interchange Protokoll
Das VRML Interchange Protocol (VIP) ist der Teil
der VNet-Implementierung der die Kommunikation von VNet-Client und VNet-Server
über das zugrundeliegende Netzwerk übernimmt. VIP ist ein einfaches
und kompaktes Protokoll, das den Austausch von VRML Feldern (VRML-Fields)
über das Netzwerk abwickelt, und explizit mehreren Benutzern die Teilnahme
an einer VRML-Welt ermöglicht. Das VI-Protokoll ist zum Beispiel dafür
verantwortlich Benutzernachrichten, Bewegungsänderungen, Interaktionen,
usw. eines Benutzers an die Clients der anderen Benutzer zu propagieren.
Die vorliegende Implementierung ist vollständig in Java geschrieben
und setzt auf TCP/IP auf. Ein wichtiger Designaspekt bei der Entwicklung
des VI-Protokoll war Effizienz, so daß viele Benutzer auch über
langsame Modemverbindungen kommunizieren können. Aus diesem Grund
hat man sich bei der Kodierung für ein Binärformat statt eines
ASCII-Formates entschieden. Im Folgenden soll die Kodierung und das Nachrichtenformat
des VI-Protokolls beschrieben werden.
3.1 Kodierung der Basistypen
Alle Basisdatentypen (integer, boolean, float, double,
string) werden vom VI-Protokoll im selben Format kodiert, das auch bei
der Kodierung der java.io.DataInputStream- und DataOutputstreamklassen
Verwendung findet. Das heißt zum Beispiel, daß ein 32-Bit Integerwert
mit 4 Bytes und führendem MSB und ein String mit 2 Bytes für
seine Länge, gefolgt von einer UTF-Kodierung für den Inhalt abgespeichert
wird.
3.2 Kodierung des VRML Feld-Typs
Das VI-Protokoll spezifiziert für jeden der
19 Feldtypen von VRML eine Kodierung. Das erste Byte ist ein sogenanntes
"tag-Byte", das Auskunft darüber gibt um welchen der 19 Feldtypen
es sich handelt. Die folgenden Bytes repräsentieren den Wert des VRML-Feldes,
wobei die Anzahl der Bytes vom Feld-Typ abhängig ist und somit variiert.
Die einzelnen Feld-Typen und ihre Kodierung ist aus der nachstehenden Tabelle
(
Tabelle 1) zu entnehmen.
Kodierung des VRML Feld-Typs
Tag
|
Typ
|
Kodierung
|
Beschreibung
|
1
|
(none)
|
-
|
Keine Daten
|
0
|
SFBool
|
byte
|
Null == FALSE, ugleich Null == TRUE
|
1
|
SFColor
|
float float float
|
r, g, b
|
2
|
SFFloat
|
float
|
|
3
|
SFImage
|
int int int [ int int int ]
|
Breite, Höhe, Tiefe, [ pixel ]
|
4
|
SFInt32
|
int
|
|
5
|
SFNode
|
int
|
Objekt Id des root node.
|
6
|
SFRotation
|
float float float float
|
3-vector von Achse und Winkel
|
7
|
SFString
|
utf8
|
|
8
|
SFTime
|
double
|
Sekunden seit (1. 1. 1970 GMT)
|
9
|
SFVec2f
|
float float
|
x, y
|
10
|
SFVec3f
|
float, float, float
|
x, y, z
|
11
|
MFColor
|
int [ float float float ... ]
|
n, gefolgt von n (r, g, b) 3-tupeln
|
12
|
MFFloat
|
int [ float float float ... ]
|
n, gefolgt von n floats
|
13
|
MFInt32
|
int [ int int int ... ]
|
n, gefolgt von n ints
|
14
|
MFNode
|
int [ int int int ... ]
|
n, gefolgt von n objekt Id's
|
15
|
MFRotation
|
int [ float float float float ... ]
|
n, gefolgt von n SFRotation 4-tupeln
|
16
|
MFString
|
int [ utf8 utf8 utf8 ... ]
|
n, gefolgt von n utf8- kodierten trings
|
17
|
MFVec2f
|
int [ float float ... ]
|
n, gefolgt von n (x, y) 2-tupeln
|
18
|
MFVec3f
|
int [ float float float ... ]
|
n, gefolgt von by n (x, y, z) 3-tupeln
|
[Zurück zum Inhaltsverzeichnis]
3.3 Das Nachrichtenformat
Beim VI-Protokoll besteht jede Nachricht aus drei
Teilen. Einem Objekt, einem Feld (Field) und einem Wert (Value). Diese
3 Teile haben die folgende Bedeutung.
3.3.1 Das Objekt
Das Objekt ist ein 32-Bit Integer, der das Objekt
bezeichnet, dessen Feld geändert werden soll. Um eine eindeutige Objekt-ID
zu gewährleisten wird diese zentral vom VNet-Server bei der Erzeugung
eines Objekts vergeben und anschließend an die angeschlossen Clients
gesendet, so daß alle Clients dasselbe Objekt auch mit der identischen
Objekt-ID ansprechen.
3.3.2 Das Feld
Das Feld ist ein vorzeichenbehafteter 16-Bit Integer,
der Auskunft darüber gibt welches Feld des Zielobjektes gesetzt werden
soll. Zur Zeit sind 4 Felder mit spezifischen Werten reserviert. Wert und
Bedeutung der Felder kann man aus
Tabelle 2 ersehen.
Der Feld-Typ
Wert
|
Identifizierer
|
Typ
|
Beschreibung
|
0
|
POSITION
|
SFVec3f
|
Die Position eines Benutzers (Avatar) oder eines
Objektes in 3D Welt Koordinaten. Broadcast vom Server zu jedem Benutzer
außer dem Sender.
|
1
|
ORIENTATION
|
SFRotation
|
Die Ausrichtung eines Benutzers (Avatar) oder eines
Objektes, dargestellt als Rotationsachse und einem Winkel. Broadcast vom
Server zu jedem Benutzer außer dem Sender.
|
2
|
SCALE
|
SFVec3f
|
Eine Skalierung die auf einen Benutzer (Avatar) oder
ein Objekt angewendet wird. Broadcast vom Server zu jedem Benutzer außer
dem Sender.
|
3
|
NAME
|
MFString
|
Der Name eines Objektes. Wird im VNet für 3d
nametags verwendet.
|
3.3.3 Der Wert
Der dritte und letzte Teil aus dem sich eine Nachricht
zusammensetzt, ist ein ein einzelner VRML-Feldwert. Seine Kodierung kann
man aus
Tabelle 1 entnehmen.
3.3.4 Von VNet reservierte Pseudo-Felder
Pseudo-Felder sind Feldwerte, die außerhalb
des definierten Wertebereiches von VRML-Feldern liegen. Das heißt
sie bezeichnen keine Feldwerte von Objekten, sondern das VI-Protokoll nutzt
sie dazu Geometrieänderungen wie "füge dieses Objekt in die Szene
ein" zu propagieren oder Textnachrichten im VNet-Client-Fenster anzuzeigen.
Um dies zu erreichen wurden für die Pseudo-Felder negative Feldwerte
gewählt. Man erreicht damit zweierlei, zum einen bleibt das VI-Protokoll
dadurch "einfach", da alle Nachrichten im gleichen Format vorliegen und
zum anderen kann man so auf sehr elegante Weise, Nachrichten mit diesen
Feldern bei der Nachrichtenversendung bevorzugt behandeln (out-of-band
messaging). Die einzelnen Pseudo-Felder und ihre Bedeutung zeigt die Tabelle
(
Tab. 3)
Die Pseudofelder
ID
|
Name
|
Typ
|
C->S
|
S->C
|
Broadcast
|
Beschreibung
|
-1
|
QUIT
|
(none)
|
Ja
|
Nein
|
Nein
|
Der Benutzer möchte die Verbindung zum Server
beenden.
|
-2
|
MESSAGE
|
SFString
|
Ja
|
Ja
|
Ja
|
Die SFString nachricht soll bei allen Benutzern im
Textfenster angezeigt werden.
|
-3
|
ADD_OBJECT
|
SFString
|
Ja
|
Ja
|
Ja
|
Es soll ein neues Objekt in die Szene eingefügt
werden. Das SFString Argument bezeichnet den URL wo das Objekt zu finden
ist.
|
-4
|
REMOVE_OBJECT
|
(none)
|
Ja
|
Ja
|
Ja
|
Ein Objekt soll aus der Szene entfernt werden. Das
Ziel ist seine Objekt-Id.
|
-5
|
PRIVATE_MESSAGE
|
SFString
|
Ja
|
Ja
|
Nein
|
Eine Textnachricht soll bei einem Benutzer angezeigt
werden. Das Ziel ist seine Benutzer-Id.
|
-6
|
CREATE_OBJECT
|
(none)
|
Ja
|
Ja
|
Nein
|
Erzeugt eine neue Objekt-Id. Wird in VNet 1.0 nicht
genutzt.
|
-7
|
USER_INFO
|
SFString
|
Nein
|
Ja
|
Nein
|
Übermittelt den Benutzernamen eines neuen Benutzers.
Wird in der Benutzerliste des VNet angezeigt.
|
[Zurück zum Inhaltsverzeichnis]
3.4 Beispiel eines Nachrichtenaustausches
Beispiel eines Nachrichtenaustausches
Objekt
|
Feld
|
Wert
|
Beschreibung
|
5
|
0
|
2.5 0 100.0
|
Verschiebe Objekt 5 an die Position (2.5, 0, 100.0).
|
5
|
-2
|
"Joe:hi"
|
(Client->Server) Chat- Nachricht von Objekt
5 (Benutzer Joe).
|
5
|
-2
|
"Joe:hi"
|
(Server->Client) die gleiche Nachricht als Broadcast
vom Server.
|
5
|
-6
|
(none)
|
(Client->Server) Benutzer Joe möchte ein neues
Objekt erzeugen.
|
15
|
-6
|
(none)
|
(Server->Client) Es wurde ein Objekt mit der Objekt-Id
15 erzeugt.
|
15
|
-3
|
"http://joe.com/dog.wrl"
|
(Client->Server) Füge Objekt mit angegebenem
URL in Szene ein.
|
15
|
-3
|
"http://joe.com/dog.wrl"
|
(Server->Client) Füge Objekt mit angegebenem
URL in Szene ein.
|
15
|
3
|
"Ralph"
|
(Client->Server) Ändere den Namen von Objekt
15 zu "Ralph".
|
15
|
3
|
"Ralph"
|
(Server->Client) Ändere den Namen von Objekt
15 zu "Ralph".
|
5
|
-1
|
(none)
|
Benutzer 5 möchte die Verbindung beenden.
|
3.5 Geplante Weiterentwicklung des
VI-Protokolls
Während zur Zeit das VI-Protokoll noch dazu
benutzt wird einen "festverdrahteten" Satz an Nachrichten zu versenden,
wird dies vom Design des Protokolls in keiner Weise erzwungen, so daß
zukünftig jedes gültige VRML-Feld gesendet werden kann.
Beispielsweise könnten Avatare mit eigenem Verhalten
ausgestattet werden, indem man etwa folgenden Prototypen verwendet:
field MFString behaviours [ "smile" "blink" "scream" ]
Der Client weist dann den einzelnen Verhaltensweisen
eindeutige Feldidentifizierer zu. Um die neuen Ausdrucksmöglichkeiten
des Avatars nutzen zu können, muß das VNet-Clientfenster um
Schaltflächen erweitert werden, die der Benutzer betätigen kann
um das entsprechende Verhalten bei seinem Avatar auszulösen. Wenn
eine Schaltfläche von einem Benutzer gedrückt wird, so veranlaßt
das den Client dazu eine einfache SFBool-Nachricht an den Server zu schicken.
Daraufhin reicht der Server die Nachricht an die anderen angeschlossenen
Clients weiter, die dann das entsprechende SFBool behaviour Feld des PROTO
suchen und und das damit verknüpfte Verhalten ausführen so daß
in jedem Client-Fenster die gewählte Animation des Avatars zu sehen
ist.
Mit anderen VRML Datentypen, wie zum Beispiel dem
SFVec3f oder dem MFString können sogar noch viel komplexere Interaktionen
unterstützt werden. Die Objekte selbst können dann asynchrone
Ereignisse erzeugen indem diese Felder in ähnlicher Weise in einem
Prototypen aufgelistet werden. Das sieht dann ungefähr so aus:
field MFString eventIns [ "clicked" ]
field MFString eventOuts [ "clicked" ]
eventOut SFBool clicked
Dies bewirkt, daß eventOut wie auch
schon weiter oben automatisch ein eindeutiger Feldidentifizierer zugewiesen
wird. Wenn ein Benutzer diese Schaltfläche anklickt, wird ein clicked
Ereignis erzeugt und eine entsprechende Nachricht an den Server geschickt,
der sie dann wieder an die Clients weiterreicht, um dort eine entsprechende
Animation oder etwas anderes auszulösen.
[Zurück zum Inhaltsverzeichnis]
4 Die Ereignisverteilung im VNet
Nachdem nun die Kodierung und das Nachrichtenformat
des VI-Protokolls bekannt sind, soll hier erläutert werden wie die
Ereignisverteilung im VNet realisiert ist. Wie schon in der Architektur
des VNet beschrieben können nach dem Verbindungsaufbau zwischen VNet-Client
und VNet-Server, die beiden Prozesse durch das VI-Protokoll miteinander
kommunizieren. Hierzu müssen die Abläufe beim Verbindungsaufbau
und danach, noch etwas genauer betrachtet werden. Wenn der VNet-Server
eine Verbindung zu einem Client akzeptiert, so erzeugt er dafür unter
anderem eine Datenstruktur in der, der Name des Benutzers, ein URL auf
seinen Avatar und eine eindeutige Kennung ( vid ) abgelegt werden.
Weiterhin wird für jeden VNet-Client ein eigener Thread erzeugt, der
für die Kommunikation zuständig ist.
Wenn im VNet der Zustand erreicht ist, daß
mehrere Clients mit dem Server verbunden sind, muß jede Interaktion
zwischen VRML-Welt und Benutzer an die anderen Clients kommuniziert werden,
so daß diese die Darstellung ihrer Welten entsprechend aktualisieren
können. Diese Kommunikation erfolgt wie weiter oben beschrieben über
sogenannte VIP-Nachrichten.
Wenn ein VNet-Client ein Ereignis (Bsp.: persönliche
Nachricht, Positionsänderung des Avatars usw.) erzeugt, an dem ein
oder mehrere andere angeschlossenen VNet-Clients interessiert sind, so
schickt er es zunächst als VIP-Nachricht an den VNet-Server. Der VNet-Server
entscheidet dann auf Grund des Typs der VIP-Nachricht welche anderen VNet-Clients
über das Ereignis informiert werden müssen und gibt die VIP-Nachricht
an die entsprechenden Threads weiter, die sie dann zum Versenden in den
jeweiligen Ausgabestrom schreiben. Die Clients lesen diese Nachrichten
ein und werten sie entsprechend aus (Bsp.: Aktualisieren die Darstellung
der Welt, zeigen eine persönliche Nachricht an, usw.) Wie das im Einzelnen
geschieht wird, am Beispiel einer
Orientation -Nachricht beschrieben
(siehe auch
Abb. 3).
Eine Orientation-Nachricht wird von einem Client
an alle anderen Clients geschickt, wenn sein Avatar aufgrund einer Benutzereingabe
den Blickwinkel ändert. Das führt dazu, daß das VRML-Plugin
des Browsers ein EventOut-Ereignis generiert. Dieses Ereignis liefert einen
Vektor und einen Winkel als Wert ( SFRotation ) an die Clientschnittstelle
( EAISceneInterface ), wo es behandelt wird. Dieser Parameter wird
von der Clientschnittstelle dazu verwendet ein SFRotation -Objekt
zu erzeugen, das dann an den clientThread weitergereicht wird. Im
clientThread wird eine Methode Namens send aufgerufen, der
neben dem SFRotation -Objekt noch die vid (eindeutige Kennung
des Clients) und ein Bezeichner ( ORIENTATION ), das den Typ der
Nachricht bezeichnet als weitere Parameter mitgegeben werden. Aus den obigen
Parametern wird ein Message -Objekt erzeugt und dem writerThread
übergeben. Der writerThread ist die Instanz, in der tatsächlich
auf das Übertragungsmedium geschrieben wird. Hierzu verwaltet der
writerThread aus Effizienzgründen 2 Warteschlangen ( messages
und transientMessages ). In die messages-Warteschlange kommen
z.B. alle Nachrichten die ein Pseudofeld enthalten (Bsp.: PRIVAT-MESSAGE
, CREATE-OBJECT , usw.) und werden sobald der writerThread
bereit ist, aus der Warteschlange geholt und verschickt.
Bei der transientMessages-Warteschlange funktioniert
es etwas anders. Hier werden alle anderen Nachrichten, das sind die, die
sich ausschließlich auf Bewegungsdaten beziehen ca. 100ms zwischengespeichert
und dann erst abgeschickt. Kommt jetzt eine Nachricht dieses Typs beim
writerThread an, überprüft dieser ob schon eine Nachricht
gleichen Typs in der Warteschlange steht. Ist dies der Fall dann ist diese
automatisch veraltet, (da es sich ja um Bewegungsdaten des Avatars handelt)
und kann direkt durch die neue ersetzt werden.
Sind die Nachrichten beim VNet-Server angekommen
entscheidet dieser zunächst anhand des Nachrichtentyps ob die Nachricht
an alle außer dem Sender (Bsp.: ORIENTATION -Nachricht) oder
nur an einen einzelnen VNet-Client (Bsp.: PRIVATE_MESSAGE -Nachricht)
gesendet werden muß. Danach geht die Nachricht an die entsprechenden
Clients wo von einem Observerobjekt der Eingang einer Nachricht an die
Dispatcherklasse gemeldet wird. Diese gibt die enthaltenen Daten
entweder über die Clientschnittstelle an das VRML-Plugin zur Verarbeitung
weiter oder zeigt z.B. eine Benutzernachricht auf dem Bildschirm an.
[Zurück zum Inhaltsverzeichnis]
5 Zukünftige Weiterentwicklung des
VNet
Stephen White beschreibt seine Ziele für die
Zukunft des VNet als seine "grand vision" und teilt diese in vier Phasen
ein.
Phase I:
Diese Phase entspricht dem Status quo und erlaubt
Chat , die Benutzung von selbstprogrammierten Avataren und gemeinsames
Begehen der Welt.
Phase II:
Die nächste geplante Erweiterung des VNet,
soll es ermöglichen, daß die Benutzer selbständig die Welt
um eigene Objekte erweitern können. Dies erfordert allerdings die
Einführung einer Eigentümerschaft auf Objekte. Daneben muß
auf der Clientseite eine Client-Schnittstelle entwickelt werden, die das
Manipulieren und Einfügen von Objekten in die Welt ermöglicht.
Schließlich benötigt der Server eine Datenbankanbindung um die
neuen Objekte persistent abspeichern zu können.
Phase III:
In dieser Phase soll erweitertes Verhalten (z.B.Mimik)
von Objekten und Avataren unterstützt werden. Dies ist möglich
ohne das VI-Protokoll zu erweitern. Es ist eine Erweiterung dessen was
bereits unter 3.5 Geplante Weiterentwicklung des VI-Protokolls beschrieben
wurde.
Phase IV:
In der letzten Phase ist geplant, daß der
VNet-Server die Synchronisation von Clients unterstützt. Das heißt
wenn ein Client eine bestimmte, kritische Aktion auf einem Objekt in der
VRML-Welt durchführt, wird dieses Objekt solange für die anderen
Clients gesperrt bis die Aktion beendet ist. Als letztes soll die Möglichkeit
bestehen, daß ein Benutzer Java-Code für ein Objekt an den Server
schicken kann, wo es kompiliert wird und anschliesend zur Laufzeit in die
Datenbasis geladen wird. Dafür müsste aber der
Class loader
modifiziert werden.
[Zurück zum Inhaltsverzeichnis]
6 Anhang
6.1 Literaturverzeichnis
[Bru98] |
Don Brutzman. The Virtual Reality Modelling Language and Java. In communications
of the ACM, vol 41 no. 6, June 1998, pp. 57-64.
|
[VRML97] |
Internatinal Standard ISO/IEC 14772-1:, December 1997 |
6.2 Internet Ressourcen zu VNet und
verwandten Themen