Die Verwendung von Ajax für das Mosaik

Saturday, 15. April, 2006

Der folgende Artikel erklärt wie wir Ajax benutzen, um das Mosaik auf BunteSuppe als fast Echtzeit, synchrone Server-Multi-Client Application zu implementieren. Wie Ihr Euch vorstellen könnt, ist die Sache etwas kompliziert und die Beschreibung unterhalb könnte für manche ziemlich trocken erscheinen. Wenn Ihr mit Ajax noch nicht vertraut seid, dann lest Euch noch schnell unsere kurze Einführung in Ajax durch.

Und jetzt rein ins Vergnügen…

Der Client/Server Datenaustausch, der für das Update der BunteSuppe Mosaik Spielfläche erforderlich ist, wird mittels dem Ajax Web Application Modell abgewickelt. Die Bewegungen des Spielers und seine Karma Stimmen werden dem Server über das JavaScript XmlHttpRequest Objekt mitgeteilt, und auf die gleiche Weise werden Daten über die Bewegungen und Karma Stimmen anderer Spieler zu jedem Browser über dieses XmlHttpRequest Objekt zurückgesendet.

Die Positionsdaten der Steinchen, die durch das XmlHttpRequest Objekt übergeben werden, lösen eine JavaScript Funktion aus, welche jedes bewegte Steinchen dazu bringt, zu seiner neuen Position in der Mosaik Spielfläche zu “fliegen”.

Jedes XmlHttpRequest Objekt ist völlig synchron mit dem Server, es gibt daher keinen Datenverlust, sogar wenn viele Spieler in den BunteSuppe Rooms aktiv sind.

Wie es funktioniert

BunteSuppe verwendet eine zeitabhängige Ajax Anwendung, um den Anschein einer Echtzeit Application zu bewirken. Jeder Browser Client interagiert mit dem Server planmäßig jede Sekunde, um:

  1. die neuen Positiondaten der Steinchen, die der Spieler bewegt hat, zu transferieren; und
  2. die neuen Positionsdaten der Steinchen, die andere Spieler bewegt haben, zu erhalten.

Das bedeutet, dass wir nur ein einziges XmlHttpRequest Objekt verwenden. Der Request zum Server ruft ein Server-seitiges Script auf (wir nennen es die “engine“), welches die eingehenden Daten verarbeitet und das an den Client zurücksendet, was sich in der Server Database verändert hat.

Dieser Request wird asynchron zurückgesendet. Nachdem die neuen Daten zurückgesendet worden sind, updated nun der Client seine eigenen Datenstrukturen, also die Steinchenpositionen und die Informationen über die Spieler. Dann wird ein anderer Request gesendet, der die Daten über die Bewegungen, die der Spieler in der Zwischenzeit gemacht hat, beinhaltet, usw.

Zusammenfassung der Spieler Bewegungen

Anstatt einen Request jedes Mal zum Server zu senden, wenn ein Steinchen bewegt worden ist, fassen wir die Daten von jeder Steinchenbewegung zusammen und senden dann alle neuen Positionen im selben Request.

Zwischen den periodischen Updates werden die Spieler Bewegungen zu einem Client Stapel hinzugefügt. Wenn das periodische Update stattfindet, werden die Inhalte dieses Stapels in einen Buffer geschrieben, um an den Server gesendet zu werden. Der Request wird mittels einem Timestamps und dem Spielernamen identifiziert.

Beschreibung eines Ajax Write/Read Ablaufs

Bei jedem periodischen Update werden folgende Schritte ausgeführt, indem ein XmlHttpRequest zum Server gesendet wird:

  1. Daten über die Spieler Bewegungen und neue Steinchen Positionen (falls es welche gibt) werden an den Server gesendet.
  2. Das Server-seitige Script, das durch einen Request aufgerufen wird, schaut im Output Buffer nach, ob Response Daten für diesen Request schon generiert worden sind oder ob es sich um einen neuen Request handelt.
  3. Wenn es festgestellt hat, dass es sich um einen neuen Request handelt, updated der Server die Database, um die Bewegungen des Spielers zu reflektieren.
  4. Der Server sammelt dann die Daten über das, was sich seit der letzten periodischen Interaktion geändert hat.
  5. Diese Daten werden an den Client in einem speziellen Format zurückgesendet, gemeinsam mit dem ursprünglichen Timestamp des Requests zu Identifizierungszwecken.

Request Timeouts

Wenn ein Ajax Request nicht innerhalb 5 Sekunden zurückgesendet wird, wird der ursprüngliche Request abgebrochen und ein neuer wird gesendet.

Hier ist der JavaSript Code, der einen anhängigen Request abbricht, indem die abort() Funktion aufgerufen wird und das Objekt gelöscht und ein neues initialisiert wird:

ajaxOb.abort();
delete ajaxOb;
ajaxOb=initxmlhttp();

Datenaustausch Format

Daten werden zwischen dem Client und dem Server als Delimited Strings ausgetauscht. Diese Option wurde statt XML gewählt, um Bandwith und Parsing Overheads zu sparen.

Die vom Client zum Server gesendeten Daten beinhalten folgende Informationen:

  • Room Name: der Name des Rooms von dem die Daten gesendet worden sind.
  • Timestamp: eine 13-stellige Zahl (Integer), die die Zeit in Millisekunden anzeigt.
  • Steinchendaten: Daten, die die neuen Positionen der bewegten Steinchen anbelangen. Diese Daten bestehen aus folgenden Feldern:
    • Slot Number: die Zahl der Steinchen, die bewegt worden sind.
    • X: die X Positon des bewegten Steinchens.
    • Y: die Y Position des bewegten Steinchens.

Wenn keine Steinchen bewegt worden sind, dann werden die Steinchendaten nicht inkludiert, wenn der XmlHttpRequest zum Server gesendet wird.

Was das Server-seitige Script zum Browser zurücksendet

Daten, die vom Server zum Client, als Response auf den zum Server geschickten XmlHttpRequest gesendet werden, beinhalten drei Teile:

  1. Spieler Hash
  2. Steinchendaten
  3. Spielerdaten

Der Spieler Hash wird immer gesendet, egal ob begleitende Steinchen- und Spielerdaten gesendet werden. Die Steinchendaten wiederum beinhalten welche Steinchen bewegt worden sind und ihre neuen x, y Positionen. Indem man den Spieler Hash mit einbezieht, können andere Spieler sehen, welcher Spieler als Letzter ein Steinchen bewegt hat.

Die Spielerdaten beschreiben, ob sich etwas beim Spieler – sein Room Karma oder sein Spielername – seit dem letzten Update verändert hat.