PHP Events steuern

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • PHP Events steuern

    Hallo,
    ich entwickle selbst an einem kleinem OpenSource Browergame. Momentan bin ich an ein Problem gekommen, wo ich Hilfe benötige, die Events.
    Event sollen klar sein, User A greif User B an, ein Beispiel.
    Bei jedem Seitenaufruf(außer Login und ACP) wird geschaut ob es ein Event auszuführen gibt, per SQL. Natürlich wird noch geprüft, ob der "Handler" nicht grad von jmd. anderes ausgeführt wird. Allerdings, wenn ein Aufruf exakt zur selben Zeit kommt, wird es 2x ausgeführt.
    Meine Lösung war die, dass beim Starten des Auftrages, via shell_exec ein einmaliger Cronjob ausgeführt werden kann, vom Server aus. Das PHP-Script selbst ist nicht via HTTP ausrufbar, also lytx funktioniert nicht.

    Bitte um Ratschläge
    Gruß

  • #2
    Bei jedem Seitenaufruf(außer Login und ACP) wird geschaut ob es ein Event auszuführen gibt
    Gewöhnlich wird das durch Cronjobs erledigt, die ein entsprechendes Script anstoßen.

    Meine Lösung war die, dass beim Starten des Auftrages, via shell_exec ein einmaliger Cronjob ausgeführt werden kann, vom Server aus. Das PHP-Script selbst ist nicht via HTTP ausrufbar, also lytx funktioniert nicht.
    Verstehe ich nicht.

    Und wo ist jetzt eigentlich dein Problem?

    Kommentar


    • #3
      soweit ich online-games verstehe, dann werden dort angriffe zeitlich gesteuert.

      das heisst, wenn user x sagt angreifen, dann wird für diesen angriff eine zeit festgelegt (angriff_table)

      und du brauchst nur ein cron_job der regelmäßig die angriff_table checkt.

      wenn du das bei jedem seiten aufruf bei einigen 100 oder 1000 usern machst - wird früher oder später dein server kein bock mehr haben.

      is aber nur so ne vermutung von mir.
      fotos :

      http://www.flickr.com/photos/rassloff/collections/

      Kommentar


      • #4
        Zitat von ShadoX Beitrag anzeigen
        Allerdings, wenn ein Aufruf exakt zur selben Zeit kommt, wird es 2x ausgeführt.
        Mit einem Semaphore/Lock kannst du das verhindern.
        Zitat von ShadoX Beitrag anzeigen
        via shell_exec ein einmaliger Cronjob ausgeführt werden kann
        Das wäre dann ein At-Job.
        Aber wenn für jeden Event ein At- oder Cronjob angelegt wird, könntest du an an Grenzen stossen. Ich weiß nicht wie viele Jobs dein Betriebssystem so handeln kann, aber sicherlich ist die Zahl begrenzt.

        Ich rate dir zu einem Cronjob, der jede Minute die Datenbank befragt, ob für diese Minute Jobs vorliegen und ggf. für die Abarbeitung dieser separate Prozesse startet.

        Kommentar


        • #5
          Das Problem ist, wenn 2 Seitenaufrufe zur gleichen Zeit sind kann es passieren dass das Event doppelt ausgeführt wird. Theoretisch müsste dann, wenn Das "Checkscript" von vorne anfangen, wenn z.B.: Die Spyflüge nach 5 Sekunden beim Ziel sind.
          Zitat von onemorenerd Beitrag anzeigen
          Mit einem Semaphore/Lock kannst du das verhindern.
          Was ist das? - Eine Art Lock ist eingebaut, entspricht aber glaube ich nicht ganz so, was es soll.
          Edit.: http://www.php.net/manual/de/ref.sem.php ?


          Eigentlich gehört an diese Stelle ein Eventhandler in C++ dahin, leider sehe ich dort im warsten Sinne des Wortes schwarz.

          Zitat von rossixx Beitrag anzeigen
          wenn du das bei jedem seiten aufruf bei einigen 100 oder 1000 usern machst - wird früher oder später dein server kein bock mehr haben.

          is aber nur so ne vermutung von mir.
          Yep. Wird er.
          Deshalb such ich nach Alternativen....

          Momentan siehst so aus(Kotztüten bereit halten^^):

          PHP-Code:
                  if($game_config['stats_fly_lock'] == && !defined('IN_ADMIN')){    
                      
          $config->update(array('stats_fly_lock' => TIMESTAMP));
                      
          $db->query("LOCK TABLE ".AKS." WRITE, ".RW." WRITE, ".MESSAGES." WRITE, ".FLEETS." WRITE, ".PLANETS." WRITE, ".TOPKB." WRITE, ".USERS." WRITE, ".STATPOINTS." WRITE;");
                          
                      
          $fleetquery $db->query("SELECT * FROM ".FLEETS." WHERE (`fleet_start_time` <= '".TIMESTAMP."' AND `fleet_mess` = '0') 
                                                          OR (`fleet_end_time` <= '"
          .TIMESTAMP."' AND `fleet_mess` = '1') 
                                                          OR (`fleet_end_stay` <= '"
          .TIMESTAMP."' AND `fleet_mess` = '2') 
                                                          ORDER BY `fleet_start_time` ASC;"
          );
                      if(
          $db->num_rows($fleetquery) > 0)
                          
          $this->FleetHandler($fleetquery);

                      
          $db->free_result($fleetquery);
                      
          $db->query("UNLOCK TABLES;");  
                      
          $config->update(array('stats_fly_lock' => 0));
                  }
                  elseif(
          TIMESTAMP >= ($config->stats_fly_lock 300)){
                      
          $config->update(array('stats_fly_lock' => 0));
                  } 
          Zuletzt geändert von ShadoX; 06.05.2010, 14:00. Grund: Zeilenumbrüche eingefügt.

          Kommentar


          • #6
            wenn du die events in einer db ablegst, und die db über ein cronjob checkst, ob neue aktionen ausgeführt werden müssen. dann sollte doch nichts doppelt stattfinden ?!?!


            - user legt ein event an z.b. angriff -> wird in db gespeichert wann dieser stattfindet

            - cronjob checkt die db und startet die entsprechenden aktions

            oder hab ich was falsch verstanden ?!?!
            fotos :

            http://www.flickr.com/photos/rassloff/collections/

            Kommentar


            • #7
              Der oben gepostet Code wird bei jedem Seitenaufruf ausgeführt. Eine Art Cronjob existiert momentan nicht.

              Den Cronjob alle 10 Sekunden auf Events zu checken, wär auf Dauer zu lastig für den Datenbank-Server(?).

              Un den Cron jede Minuten zu starten wär für ungedulige User zu wenig...

              Kommentar


              • #8
                Vorab: Die Bezeichnung Event ist total daneben. Du meinst Job oder Task.
                Da u.a. auch von Cronjobs gesprochen wird, verwenden ich mal Task statt Event.

                (Vixie-)Crons kann man nur minutengenau festlegen. Das kürzeste Intervall ist also 1 Minute. Was nicht bedeutet, dass dann bis zur nächsten Minute keine Tasks ausgeführt werden. Der Cronjob holt sich ja alle Tasks aus der DB, die in dieser Minute ausgeführt werden sollen, sortiert nach der sekundengenauen Startzeit.
                Nun vergleicht der Cronjob in einer Schleife die aktuelle Zeit mit der Startzeit des ersten Task. Stimmen sie überein, wird für den Task ein Prozess gestartet und er wird aus der Liste gestrichen. Stimmen weitere Zeitstempel überein, dasselbe.

                Kommentar


                • #9
                  Dann bleiben wir als noch 3 Möglichkeiten:
                  1. Damit leben.
                  2. Eigenden Event/TaskHandler in C schreiben, der Permanet im Hintergrund läuft.
                  3. Die Tasks von der Usern ausführen lassen.
                  Nur noch den "Lock" dann optimieren.

                  Kommentar


                  • #10
                    Wieso denn? Du kannst das sehr wohl alles in PHP programmieren. Du musst dir nur mal klar machen wie es laufen soll. Ich habe versucht dir einen Weg zu zeigen.

                    Kommentar


                    • #11
                      Zitat von onemorenerd Beitrag anzeigen
                      Wieso denn? Du kannst das sehr wohl alles in PHP programmieren. Du musst dir nur mal klar machen wie es laufen soll. Ich habe versucht dir einen Weg zu zeigen.
                      Nur die Lösungen mit dem Minütigen Cronjob ist keine Lösung. Wenn hinterher die User mit hochem Speed spielen und dann die Einheit bis zu 57 Sekunden verspätung hat, würde ich Support Tickets ohne ende bekommen. Bekomme schon geung, wenn die Flotte selbst mal 30 Sekunden zu spät ist.

                      Ich glaube mit das größe Problem, dass sie nach Möglichkeit Sekunden genau gestartet werden müssen.

                      Aber ca. 500 At-Jobs zu erstellen ist ja nicht die Lösung.....

                      Kommentar


                      • #12
                        Zitat von ShadoX Beitrag anzeigen
                        Ich glaube mit das größe Problem, dass sie nach Möglichkeit Sekunden genau gestartet werden müssen.
                        Dass du glaubst, dass das nötig wäre, bzw. dass dein bisheriges Konzept es notwendig erscheinen lässt, ist das eigentliche Problem.

                        Ständig sekundengenau Berechnungen durchzuführen, ist im Umfeld eines Browsergames mit PHP Unfug. Selbst wenn das als theoretisches Konstrukt und meinetwegen sogar in einer hübschen kleinen Testumgebung funktionieren mag, bricht es dir in der Praxis garantiert irgendwann zusammen, und das schneller, als du bspw. bei der Hardware aufstocken kannst.

                        Überdenke also zunächst mal dein Konzept. Vor allem in Bezug darauf, wie man termingebundene Abläufe so abbilden kann, dass es beim Betrachten des Ergebnisses zum Zeitpunkt X nicht darauf ankommt, ob vorher hunderte von Rechenoperationen zu einem exakt spezifizierten Zeitpunkt ausgeführt werden konnten oder nicht.
                        I don't believe in rebirth. Actually, I never did in my whole lives.

                        Kommentar

                        Lädt...
                        X