| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |

06-05-2010, 07:07
|
|
ShadoX
Registrierter Benutzer
|
|
Registriert seit: May 2010
Beiträge: 5
|
|
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ß
|

06-05-2010, 11:40
|
TobiaZ
 Moderator
|
|
Registriert seit: Jan 2001
Ort: MUC und MGL, Germany
Beiträge: 34.188
|
|
Zitat:
|
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.
Zitat:
|
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?
|

06-05-2010, 11:49
|
|
rossixx
Registrierter Benutzer
|
|
Registriert seit: Jul 2003
Ort: Berlin
Beiträge: 461
|
|
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.
|

06-05-2010, 12:02
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Zitat:
Zitat von ShadoX
Allerdings, wenn ein Aufruf exakt zur selben Zeit kommt, wird es 2x ausgeführt.
|
Mit einem Semaphore/Lock kannst du das verhindern.
Zitat:
Zitat von ShadoX
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.
|

06-05-2010, 13:37
|
|
ShadoX
Registrierter Benutzer
|
|
Registriert seit: May 2010
Beiträge: 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:
Zitat von onemorenerd
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:
Zitat von rossixx
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'] == 0 && !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)); }
Geändert von ShadoX (06-05-2010 um 14:00 Uhr)
Grund: Zeilenumbrüche eingefügt.
|

06-05-2010, 14:07
|
|
rossixx
Registrierter Benutzer
|
|
Registriert seit: Jul 2003
Ort: Berlin
Beiträge: 461
|
|
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 ?!?!
|

06-05-2010, 14:32
|
|
ShadoX
Registrierter Benutzer
|
|
Registriert seit: May 2010
Beiträge: 5
|
|
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...
|

06-05-2010, 15:00
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
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.
|

06-05-2010, 17:34
|
|
ShadoX
Registrierter Benutzer
|
|
Registriert seit: May 2010
Beiträge: 5
|
|
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.
|

06-05-2010, 17:59
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
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.
|

06-05-2010, 19:57
|
|
ShadoX
Registrierter Benutzer
|
|
Registriert seit: May 2010
Beiträge: 5
|
|
Zitat:
Zitat von onemorenerd
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.....
|

06-05-2010, 20:06
|
wahsaga
 Moderator
|
|
Registriert seit: Sep 2001
Beiträge: 24.486
|
|
Zitat:
Zitat von ShadoX
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.
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|