• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[PHP] (u)sleep nur in Funktion

bosko

Member
Hoi,

ich habe vor kruzem angefangen ein PHP Demon Script zu Schreiben, was auf dem Server
Dauerhaft läuft.
Nun bin ich dabei, wenn ich in meinen Shell Clienten einen Befehl gebe, das ich eine Antwort
erhalte, alles ohne Probleme. Nun habe ich über eine Function ein "sleep" eingebaut, das ich
nach 10s eine weitere Antwort erhalte. Funktioniert auch.
Jetzt Sende ich ein Befehl bevor die 10s abgelaufen sind und das Script wartet dennoch die
10s ab, bevor ich eine Antwort bekomme, dies ist so unerwünscht. Wenn ich den Befehl sende
soll er wieder die 10* (* = kann unterschiedlich sein) Sekunden von vorne abwarten und so weiter...

Gibt es da eine Vernüftige Lösung.

Gruß
 
dies ist eine art Server Bot für ein IRC, und er soll nach einem Behl zeitversetzt Sprechen ohne das er beim neuen Befehl die Zeit abwartet sondern gar nicht den vorrigen befehl ausführen
 
Das mit dem SyncEvent::wait verstehe ich nicht 😩

Dachte es gibt vielleicht eine Art timer wie in C oder Tcl
 
ich sehe nicht, wie dir ein timer weiterhilft.
du willst mit timeout 10s darauf warten, dass ein neuer "befehl" - das löst das event aus - über was auch immer eintrift und diesen dann abarbeiten. du brauchst also 2 threads/prozesse zum empfangen und abarbeiten.
 
Hoi,
Genau andersrum, mit einem Befehl löse ich eine Ausgabe aus, ca 10-20 sec soll eine weitere kommen außer es kommt wieder ein Befehl
 
hoi,

ich bin nun fast am Ziel, hänge nur daran das ich jetzt in der class in einer Funktion eine andere Funktion aufrufen möchte, eigentlich ist das noch tiefer, hier mal mein Auszug....

PHP:
class FirstStepPlugin implements pluginInterface {

	var $lastCheck;

	function init() {
		$this->lastCheck = 0;
	}

	function loop() {
		if($this->lastCheck < time()) {

                   function check($data) {
                      if($data==true) $cmd = "hat geklappt";
                   }


			$this->lastCheck = (time()+180);
		}
	}

	function onData($data) {
           $this->loop->check($data);
        }

}

hab es jetzt so nicht getestet aber: ruft $this->loop->check($data); die Funktion in der loop auf? die loop läuft jede Sekunde durch zur Info...
Das Problem ist das loop() keine Daten ($data) übertragen kann, nur check() kann dies....
 
da loop() vom Server gesteuert wird und die eingabe vom User nicht lesen kann
onData() ist dafür verantwortlich, der bemerkt ob eine Input da ist oder nicht
 
PHP:
<?php
class CmdInput extends Thread
{
  public function __construct()
  {
    $this->cmd = NULL;
    $this->newCmd = FALSE;
  }
  
  public function run()
  {
    while(true)
    {
      $this->synchronized(function($thread)
      {
        if (!$thread->newCmd)
        {
          $thread->wait();
        }
        else
        {
          $event = new SyncEvent("CmdAvailable");
          $event->fire();
          $thread->newCmd = FALSE;
        }
      }, $this);
    }
  }
  
  public function getCmd()
  {
    return $this->synchronized(function($thread)
    {
      return $thread->cmd;
    }, $this);
  }
  
  public function setCmd($cmd)
  {
    $this->synchronized(function($thread, $cmd)
    {
      $thread->cmd = $cmd;
      $thread->newCmd = TRUE;
      $thread->notify();
    }, $this, $cmd);
  }
}

class CmdExecution extends Thread
{
  public function __construct($cmdInput)
  {
    $this->cmdInput = $cmdInput;
  }
  
  public function run()
  {
    while(true)
    {
      $this->exec();
    }
  }
  
  public function exec()
  {
    $event = new SyncEvent("CmdAvailable");
    $event->wait();
    $cmd = $this->schedule($this->cmdInput->getCmd());
    echo "cmd: " . $cmd . "\n";
  }
  
  public function schedule($cmd)
  {
    $event = new SyncEvent("CmdAvailable");
    if ($event->wait(10000))
    {
      $cmd = $this->cmdInput->getCmd();
      echo "new cmd - ";
      return $this->schedule($cmd);
    }
    else
    {
      echo "timeout - ";
      return $cmd;
    }
  }
}

$event = new SyncEvent("CmdAvailable");
$input = new CmdInput();
$input->start();
$exec = new CmdExecution($input);
$exec->start();

$input->setCmd(1);
sleep(10);
$input->setCmd(2);
sleep(5);
$input->setCmd(3);
?>
 
Danke für eure Hilfe und Antworten, eigentlich war die lösung nicht so weit:

PHP:
class FirstStepPlugin implements pluginInterface {
  var $lastCheck;
  var $check;
  
  function init() {
    $this->lastCheck = 0;
    $this->check = NULL;
  }
  
  function loop() {
    if($this->lastCheck < time()) {
      if(time() > ($this->check+400)) {
        $cmd = "hat geklappt";
        $this->check = NULL;
      }
    }
    
    $this->lastCheck = (time()+60);
  }
  
  function onData($data) {
    $this->check = $ZeitVonData;
  }

}

Wie gesagt, loop() läuft ständig und wenn in onData() was rein kommt kann loop() sein Inhalt Verarbeiten.
 
alles mit lastCheck gehört raus.
Code:
if($this->lastCheck < time()) {
}
$this->lastCheck = (time()+60);
sorgt sonst nur dafür, dass deine loop nie etwas macht, wenn loop schneller als alle 60s aufgerufen wird.
was bedeutet du rufst loop zur zeit langsammer auf als alle 60s, sonst würde es nicht gehen???

check würde ich mit 0 initialisieren, da es ein int ist.
was ist denn $ZeitVonData? damit if(time() > ($this->check+400)) true liefert, müsste ZeitVonData 400 sek in der vergangenheit liegen???
 
Kleiner Erweiterungsvorschlag: Bau Dir auch einen Interrupt-Handler in Deine Klasse ein – damit Du den "Dienst" sauber stoppen kannst, wenn er denn mal "infinity" läuft. Sowas ist nobler als der "kill pid" auf der Konsole. Ich weiß - hast bestimmt schon dran gedacht, wollte es aber dennoch nicht unerwähnt lassen.
 
Zurück
Oben