AGI - Variable / Pipe flüchtig bei Asterisk 1.6?

TheRaph

Neuer User
Mitglied seit
6 Jan 2009
Beiträge
7
Punkte für Reaktionen
0
Punkte
0
Hallo, ich habe ein kleines Problem.

Ich betreibe zur Zeit zwei VServer mit Asterisk. Auf einem läuft die Version 1.4.? und auf dem anderen 1.6.2.1

Aus dem Dialplan heraus wird ein PHP-AGI-Script gestartet - dies funktioniert soweit ganz gut.

Allerdings ist der STDIN bei dem Script auf dem Asterisk 1.6.2.1 flüchtig.

Hier mal der Code:
Code:
#!/usr/bin/php -q
<?php
{
 // Logfile
 $errorfile = "/var/lib/asterisk/agi-bin/script_12.log";
 $log = 0;     // soll geloggt werden? 1 = ja 0 = nein

...

 $stdin = fopen( 'php://stdin', 'r' );
 $stdout = fopen( 'php://stdout', 'w' );
 if($log) $stdlog = fopen($errorfile, 'w' );
 if($log) fputs( $stdlog, "---Start---\n" );

[COLOR="Red"]sleep(1);[/COLOR]

 while ( !feof($stdin) )
 {
  $temp = fgets( $stdin );

  if($log) fputs( $stdlog, $temp );
  // Strip off any new-line characters
  $temp = str_replace( "\n", "", $temp );
  $s = explode( ":", $temp );
  $agivar[$s[0]] = trim( $s[1] );
  if ( ( $temp == "") || ($temp == "\n") )
  {
   break;
  }
 }

...
}

Das sleep (warten für x Sekunden) ist nur zum testen. Steht da "0" drin funktioniert alles gut, wenn ich da 'ne 1 rein schreibe, fehlt die erste Hälfte der agi-vars wenn ich ne 2 rein schreibe fehlen fast alle agi-vars und wenn ich da 'ne 3 reinschreibe, dann gibt es gar keine agi-vars und das Script hängt an dem "fgets".

Das heißt, je mehr sich der Anfang des Scriptes verzögert, desto weniger habe ich von den agi-vars.

Nun könnte man ja sagen: "Warum liest du die nicht als erstes ein?" Nun, dies tue ich bereits, leider ist es so, wenn das Script nach einer Bestimmten Zeit das erste Mal aufgerufen wird, dann verzögert sich das ganze und mir fehlen die Variablen. Heißt also, wenn ich morgens das erste mal die Nummer anrufe, chrasht das Script, wenn ich dann auflege und dann gleich nochmal anrufe, läufts - auch nach einer Stunde noch - auch nach 2 - wenn ich aber 4 Stunden (besser 6) nicht angerufen habe, chrasht es wieder.

Interessant ist, auf der Anderen Maschine habe ich Asterisk 1.4 am laufen und dort besteht das Problem nicht. Das heißt, es ist egal ob ich da ein Sleep von 3 Sekunden oder von 10 Sekunden einbaue, der Inhalt der Pipe (des Streams) steht mir so lange zur Verfügung, bis ich ihn gelesen habe.

Meine Frage nun, ist der Fehler bekannt? Liegts an PHP oder Asterisk? Oder ist es eine Konfig-Einstellung?

Für sinnvolle Ratschläge bin ich dankbar.

Gruß Raph

(PS: SuFu wurde benutzt, zum Thama AGI-vars gibt es 1001 Beiträge aber irgendwie habe ich keins gefunden, was auf genau DIESES Problem passt)
 
Hallo Raph,

ich mache sehr viel (bzw. fast alles) mit PHPs als AGI und habe das von Dir beschriebene Problem noch nie festgestellt. Im Moment verwende ich PHP 5.2.0 und Asterisk 1.6.1, hatte aber auch schon andere Versionen. An den PHP Einstellungen habe ich soweit ich mit erinnern kann nichts in der Richtung verändert.

Zum Lesen benutze ich immer folgende Funktion:

PHP:
$in = fopen("php://stdin","r");

function read() {
  global $in;
  $input = str_replace("\n", "", fgets($in, 4096));
  return $input;
}

while ($env=read()) {
  $s = split(": ",$env);
  $agi[str_replace("agi_","",$s[0])] = trim($s[1]);
  if (($env == "") || ($env == "\n")) break;
}

Im Grunde nichts anderes, außer dass ich nicht nach dem EOF des Streams gehe.

Ich glaube nicht, dass das an Asterisk liegt. Der übergibt seine Daten an den Puffer von PHP, was PHP damit anstellt kann er aber meines Erachtens nicht mehr beeinflussen.

Svenja
 
Hallo Svenja

vielen Dank erstmal. Wie schon beschrieben, tritt es ja auch immer nur beim ersten Mal auf ... ich vermute das PHP wenn man es länger nicht benutzt hat ein wenig braucht um von der Platte geladen zu werden (keine Ahnung wie so ein VServer seine Ressourcen verwaltet, aber die haben bestimmt nicht immer alles im RAM).

Was halt das eigentliche Problem ist, ist dass nach dem etwas Zeit vergangen ist, keine Daten mehr am "stdin" anliegen. - Mich wundert nur, dass das bei de einen System klappt udn bei dem Anderen nicht. - Ich habe auf einem dritten System jetzt auch mal ein PHP-Script installiert, auch mit sleep() und so um die Zeitverzögerung zu testen, auch dort klappt es nicht. Hier noch einmal die Systemdaten, vielleicht kann sich da einer 'nen Reim drauf machen:

System 1:
php5-cli 5.2.0-8+etch13
Asterisk 1.4.22
- auch nach 10 sek sind noch AGI-Vars zu bekommen

System 2:
php5-cli 5.2.0+dfsg-8+etch16
Asterisk 1.6.2.1
- bereits nach wenigen Zehntelsekunden sind die ersten Variablen verschwunden

System 3:
php5-cli 5.2.0+dfsg-8+etch16
Asterisk 1.6.2.2
- auch hier sind bereits nach wenigen Zehntelsekunden sind die ersten Variablen verschwunden

Es gibt auch KEINE Fehlermeldung auf der CLI.

- edit -

Auf der Suche nach dem Problem ist mir noch etwas aufgefallen. In der "asterisk.conf" gibt es ganz unten einen Abschnitt, der vermutlich etwas mit der Kompatibilität zu tun hat:

Code:
[compat]
pbx_realtime=1.6
res_agi=1.6
app_set=1.6

Also habe ich mal kurzerhand den Eintrag "res_agi=1.6" auskommentiert.

Der Effekt ist sehr interessant, alle PHP-Scripte in denen ich die Pipe mit "STDIN" referenziere funktionieren noch wie gewohnt, die beiden anderen Scripte (die schon etwas älter sind) in denen ich das selbe über "fopen("php://stdin","r");" tue funktionieren nicht mehr und erzeugen auf der Asterisk-CLI bei Verbose 5 einen Fehler aus, ich habe leider vergessen ihn direkt aus der CLI zu kopieren ... im Log stehts so:
Code:
[Apr  6 00:13:18] ERROR[31765] utils.c: write() returned error: Broken pipe
[Apr  6 00:13:18] ERROR[31765] utils.c: write() returned error: Broken pipe
[Apr  6 00:13:18] ERROR[31765] utils.c: write() returned error: Broken pipe
[Apr  6 00:13:18] ERROR[31765] utils.c: write() returned error: Broken pipe
[Apr  6 00:13:18] ERROR[31765] utils.c: write() returned error: Broken pipe
und davon genau so viele Zeilen wie es agi-vars gibt ...

Ich bin mir also mittlerweile nicht mehr so ganz sicher ob es den Asterisk wirklich nicht interessiert, wie PHP die Pipe in Empfang nimmt ...

Nach umstellen des Scriptes von "fopen" auf "STDIN" funktioniert es wieder, der Fehler aber, bei dem die Variablen verschwinden wenn man sie nicht gleich ausliest, bleibt.

- /edit -

Gruß Raph
 
Zuletzt bearbeitet:
Ich kämpfe im Moment mit genau demselben Problem in Zusammenhang mit dem Asterisk Management Interface.

Gibt es inzwischen neue Erkenntnisse zu diesem Thema bzw. Tricks, wie man den Fehler behebt?

Danke und Gruss
amc
 
Hi,

das eigentliche Problem konnte ich auch nicht lösen.

Ich habe es aber umgangen, in dem ich zuerst alle Chan-vars in den Müll haue, da ich nicht genau wissen kann, ob's klappt oder nicht ... es wird auch gar nicht lange gewartet.

Danach ziehe ich mir die benötigten Vars (und nur die) einzeln über den "GET VARIABLE" Befehl.

Das sieht dann etwa so aus:

Code:
#!/usr/bin/php -q
<?php
{

 set_time_limit(30);
 error_reporting(0);

// Variablen
 $logfile = "/var/lib/asterisk/agi-bin/logs/blah.log";

 $log = fopen( $logfile, 'w' );
 fputs( $log, "---Start---\n" );

// STIN und STDOUT sind von PHP bereits konfiguriert ...

 stream_set_blocking(STDIN , 0); // wenn nix da ist, dann auch nicht warten

// STIN einlesen (falls vorhanden) und (als Müll) ins Log schreiben:
 while ( !feof(STDIN) )
 {
  $temp = fgets(STDIN);
  fputs( $log, $temp );
  // Strip off any new-line characters
  $temp = trim( $temp );
  if ( ( $temp == "") || ($temp == "\n") )
  {
   break;
  }
 }

 stream_set_blocking(STDIN , 1);  //ab jetzt wieder warten ...

 fputs( STDOUT, "ANSWER \n" );   // call beantworten
 fflush( STDOUT );
 $temp = fgets( STDIN );
 fputs( $log, $temp );   // Antwort ins log ... hier könnte man noch auf Erfolg testen

// Benötigte private Variablen einlesen
 fputs( STDOUT, "GET VARIABLE sowieso \n" );
 $temp = fgets( STDIN );
 fputs( $log, $temp );
 $suche = preg_match("~.*1 \((.*)\)$~", $temp, $ergebnis);

 $vars['sowieso'] = $ergebnis[1];
 fputs( $log, "Sowieso: ".$vars['sowieso']."\n" );

// Variable für die Rufnummer einlesen
 fputs( STDOUT, "GET VARIABLE CALLERID(num) \n" );
 $temp = fgets( STDIN );
 fputs( $log, $temp );
 $suche = preg_match("~.*1 \((.*)\)$~", $temp, $ergebnis);

 $vars['callerid'] = $ergebnis[1];
 fputs( $log, "Callerid: ".$vars['callerid']."\n" );

//... Restlicher Code

// letztes Auslesen und ENDE

 $temp = fgets( STDIN );
 fputs( $log, $temp );

 usleep(200000);      // warten ... zur sicherheit

 fputs( $log, "\n---ENDE---\n\n" );
 fclose( $log);

 exit;

}
?>
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.