Wie Highscore in einer Serveranwendung speichern?



  • Hallo,

    ich bastel gerade mit BCB eine kleine Anwendung/ein kleines Spiel, das auf einem Windows Server 2003 laufen wird. D.h. mehrere Benutzer können das Spiel gleichzeitig spielen.

    Nun überlege ich, wie ich am besten den Highscore speichern soll. Mir schwebt eine einfache Textdatei vor. Nur könnte es aber theoretisch sein, dass von zwei Anwendungen gleichzeitig der Highscore geschrieben werden soll, was zu einem Datenchaos führen kann.

    Als Lösung schwebt mir die Verwendung einer Lock-Datei (à la OpenOffice vor): Die erste Anwendung, die schreibenden Zugriff möchte, sorgt dafür, dass während des Schreibens eine Lock-Datei angelegt wird. Und solange diese Lock-Datei existiert, müssen die anderen Benutzer warten, bis sie auf die Textdatei wieder zugreifen können.

    Hat jemand eine bessere Idee? 😉

    Danke.

    stem



  • Wenn mehrere Spieler parallel versuchen die Bestenliste zu aktualisieren bringt dir eine Lock-Datei auch nichts.

    Bei deinem Problem kann dir eigentlich nur eine Datenbank oder ein Server, der die Liste verwaltet, helfen.
    Versuchs mal mit SQLite.



  • override schrieb:

    Wenn mehrere Spieler parallel versuchen die Bestenliste zu aktualisieren bringt dir eine Lock-Datei auch nichts.
    Bei deinem Problem kann dir eigentlich nur eine Datenbank oder ein Server, der die Liste verwaltet, helfen.
    Versuchs mal mit SQLite.

    klar funktioniert die lockdatei.



  • Und was ist, wenn die Lock-Datei gerade gelöscht wurde und 2 Spieler gleichzeitig in die Datei schreiben wollen?



  • override schrieb:

    Und was ist, wenn die Lock-Datei gerade gelöscht wurde und 2 Spieler gleichzeitig in die Datei schreiben wollen?

    Beide erstellen sie mit dwDesiredAccess == GENERIC_WRITE und dwShareMode == FILE_SHARE_READ, dann schlägt der zweite Schreibzugriff fehl.

    Allerdings ist die Datenbank trotzdem besser; im Falle einer Lock-Datei müßtest du den Benachrichtigungsmechanismus selbst bauen.

    volkard schrieb:

    Ich bin ein Dokmatist.

    😃



  • audacia schrieb:

    Beide erstellen sie mit dwDesiredAccess == GENERIC_WRITE und dwShareMode == FILE_SHARE_READ, dann schlägt der zweite Schreibzugriff fehl.

    Darauf wollte ich hinaus - denn dadurch erledigt sich doch die Lock-Datei. 😃



  • der, bei dem es fehlschlägt, nämlich das lockenbzw. erstellen des lockfiles, muß einfach so lange weitermachen, bis es klappt. das lockfile wird also nicht anders als eine critical section verwendet, nur daß es nicht critsect, nichmal semaphore, sondern nur ein file ist. das funktioniert in der praxis sogar, siehe flock in perl.
    vielleicht noch besser, das highscorefile selbst geeignet zu öffnen, natürlich mit der passenden warteschleife. wollen wir mal hoffen, daß nicht ausgerechnet das schreiben der highscore irgendwie zu einem stau führen kann. im allgemeinen dürfte das gar nicht der fall sein, und die lösung ausreichend.
    ich will nicht sagen, daß das lockfile die beste lösung wäre. will nur sagen, daß es auch geht und die aussage, es ginge gar nicht, gar nicht stehen lassen mag. der fragesteller kann ja dann zwischen datenbank, lockfiles, selbergeschickten mails, ausweichfiles und noch spaßigeren wegen wählen.



  • Der Weg über eine Lock Datei ist komplizierter als die Lösungen, die Windows und die Win32 API mitbringt. Ich nehme mal an, dass nur eine Instanz deiner Server Anwendung läuft. Dann reciht es völlig aus, eine CriticalSection anzulegen und diese beim Betreten der Highscore-Schreib-Funktion zu sperren und beim Verlassen der Funktion wieder zu entsperren. Wenn mehrere Instanzen der Serversoftware laufen kannst du das gleiche über einen named Mutex erreichen, musst dir halt ein wenig die Win32 API angucken (CreateMutex/ReleaseMutex/WaitForSingleObject, TCriticalSection gibts in der VCL, ansonsten CreateCriticalSection, EnterCriticalSection und LeaveCriticalSection).



  • DocShoe schrieb:

    Ich nehme mal an, dass nur eine Instanz deiner Server Anwendung läuft.

    Gute Frage, die Anwendung wird über eine Terminal-Server-Lösung auf Thin-Clients aufgerufen.

    Wie könnte ich das programmiertechnisch in der Anwendung rausfinden, ob nur eine Instanz läuft?

    Danke!



  • Also das ist schon eine wichtige Frage. Ist es eine "echte" Client-Server Architektur, wobei es nur einen Server und einen Serverprozess gibt, oder schreiben die Clients ihre Daten selbst auf den (File-)Server?



  • So genau weiß ich das momentan gar nicht, ich werde da mal recherchieren.

    Ich habe schon eine Testanwendung geschrieben, die von einem TC auf dem Server aufgerufen wird (klappt auch von mehreren TCs gleichzeitig), und per Mausklick das aktuelle Datum+Uhrzeit sowie den Windows-Server-Anmeldenamen in einer Textdatei anfügt. Die Textdatei (mit Schreibrechten für alle) befindet sich im Programmverzeichnis auf dem Server.

    Würde helfen, wenn die Demoanwendung ihre Prozess-ID anzeigen würde?


Anmelden zum Antworten