Perl + Statusanzeige
Surfer
- cgi
Hallo,
ich hab da mal ein Problem.
Wie kann ich den mit eine Art Satatusanzeige machen im Web ?
Z.B. lade ich gerade eine Datei via Web (Perlprogramm) auf mein
Server. Nun will ich, dass während des Uploadvorganges z.B.
immer der User ein Uhrzeit wie lange es bis jetzt dauert oder
alle 10 Sekunden die Farbe der Html-Seite wechselt oder sowas halt.
Nämlich ich raff des vom Prinzip her schon nicht, wie das gehen soll.
Denn wenn ich mein Perl-Programm ausführe, dann ist doch nach dem erstenmal wenn ich an Browserwas zurück gesendet hab und den HTML-Tag schließe aus und vorbei und ich kann selbst wenn das Perl-Programm noch laufen sollte nicht mehr an den Browser schicken bzw. er reagiert nicht mehr drauf oder blick ich da was nicht ?!?
Wäre nett, wenn mir jemand helfen könnte und/oder vielleicht ein kleines simples Beispiel mit posten könnte.
Danke
Surfer
ich hab da mal ein Problem.
Wie kann ich den mit eine Art Satatusanzeige machen im Web ?
Eigentlich gar nicht, das Web funktioniert über HTTP und dort gibt es praktisch keine Verbindung, über die du den "Status" beim Client auch aktualisieren könntest.
Z.B. lade ich gerade eine Datei via Web (Perlprogramm) auf mein
Server. Nun will ich, dass während des Uploadvorganges z.B.
immer der User ein Uhrzeit wie lange es bis jetzt dauert oder
alle 10 Sekunden die Farbe der Html-Seite wechselt oder sowas halt.
Das ist noch viel schwieriger, dazu müsste der Client ja irgendwie die Information bereitstellen, wie weit der Upload denn schon von statten gegangen ist, das tut der aber nicht. Die meisten Server lassen dich ebenfalls im unklaren darüber, so dass du noch weniger eine Chance hättest, hier dem Nutzer irgend eine Rückmeldung zu geben. Dass liegt in der Verantwortung des Clients.
Ich schlage vor, du schlägst dir das aus dem Kopf, eine vernünftige Lösung kannst du eh nicht auf die Beine stellen.
Hallo.
Nämlich ich raff des vom Prinzip her schon nicht, wie das gehen soll.
Denn wenn ich mein Perl-Programm ausführe, dann ist doch nach dem erstenmal wenn ich an Browserwas zurück gesendet hab und den HTML-Tag schließe aus und vorbei und ich kann selbst wenn das Perl-Programm noch laufen sollte nicht mehr an den Browser schicken bzw. er reagiert nicht mehr drauf oder blick ich da was nicht ?!?
Wäre nett, wenn mir jemand helfen könnte und/oder vielleicht ein kleines simples Beispiel mit posten könnte.
Bei dem Upload, den du vorhast zu realisieren, da wird es denke ich nicht gehen. Ich bin mir nicht 100%ig sicher, aber ich glaube der Client schickt die Datei erst vollständig an den Webserver, bevor dieser dein Perl Programm aufruft. Also läuft dein Programm während des Uploads noch gar nicht.
Wenn du aber ansonsten eine Statusanzeige haben willst, dann geht das schon. Du musst das Buffern von STDOUT ausschalten ($| = 0; iirc). Dann kannst du z.B. folgendes machen:
#!/usr/bin/perl
$| = 0; # Hier sicherheitshalber nochmal nachgucken.
print "Content-type: text/html\n\n";
print "<html><body><h1>Los gehts</h1>";
for (1..10) {
print "<p>$_</p>";
sleep 5;
}
print "<h1>Fertig!</h1></body></html>";
__END__
Damit kommen die meisten Browser zurecht.
Gruß,
Stefan
Hi,
Wie kann ich den mit eine Art Satatusanzeige machen im Web ?
das, was Du haben willst, nennt sich im Prinzip "Server Push".
(Allerdings ist es eine Geschmacksfrage, ob man das als Vergewal-
tigung von HTTP ansieht, oder als "Anwendung". ;-)
Es gibt einen MIME-Typ, mit dem Du sagen kannst, daß Deine Ausgabe
nicht _ein_ Paket ist, sondern eine _Serie_ von Paketen, also etwa
eine Serie von HTML-Dokumenten.
Wenn der Browser das versteht (und das ist ein echtes Problem -
ich habe es noch mit keinem existierenden Browser so hinbekommen,
wie ich mir das vorstelle), dann sollte er jedes eintreffende
HTML-Dokument darstellen, aber auf weitere Dokumente warten und
mit diesen den Inhalt des Dokuments überschreiben.
Der Server sollte also einen Datenstrom liefern, den der Browser
abnimmt - ohne daß der Browser auf "client pull" zurückgreifen muß.
Das ist nämlich die zweite Möglichkeit, die Du hast: In jedes
HTML-Dokument ein Meta-Refresh rein schreiben, um nach einer Dir
genehmen Anzahl von Sekunden die nächste Seite zu laden.
Auf diese Weise könntest Du in der Tat eine Statusanzeige machen
Z.B. lade ich gerade eine Datei via Web (Perlprogramm) auf mein
Server. Nun will ich, dass während des Uploadvorganges z.B.
immer der User ein Uhrzeit wie lange es bis jetzt dauert oder
alle 10 Sekunden die Farbe der Html-Seite wechselt oder sowas halt.
Hm - mit dem Refresh-Prinzip könntest Du so etwas machen. Die
Seite, welche diese Farbe realisiert, könnte ein CGI-Skript sein,
das auf Serverseite abfragt, ob der Upload fertig ist (dazu muß
es natürlich wissen, wie es das erkennen kann), und in diesem
Falle _nicht_ mehr den Refresh-Header erzeugt, also die Selbst-
referenzierung einstellt. So habe ich das jedenfalls realisiert.
Das Problem ist allerdings, daß Du keine Zwischenzustände des
Uploads erkennen kannst. Du hast keine Chance, beispielsweise
das Wachsen der Ausgabedatei zu beobachten - weil HTTP nicht so
funktioniert, wie Du das bräuchtest. Es ist eben _nicht_ so, daß
die Datei zeilen- oder blockweise übertragen wird und Dein
Annahmeskript auf einzelne Blocks lauscht und diese auf die
Platte schreibt (_dann_ würde Dein Status-CGI jeweils die Datei-
größe abfragen und "rechnen" können), sondern zuerst geht die
gesamte Datei via HTTP an den HTTP-Server, und _danach_ leitet
dieser über die CGI-Schnittstelle den Inhalt an Dein Upload-Skript
weiter. In dem Moment, in dem Du anfängst, die Datei zu speichern,
ist sie bereits vollständig übertragen, und das Speichern dauert
nur noch Sekundenbruchteile.
Du kannst also lediglich prüfen, wann die Datei entsteht - das ist
aber nicht das, was Du erreichen möchtest. (Bei meinem Einsatzfall
ist das anders - meine Statuszeile "beobachtet" die Entstehung
einer Datei, die auf dem HTTP-Server durch Zugriff auf eine dritte
Maschine entsteht, wobei dieser Zugriff via CGI nur angestoßen wird
Denn wenn ich mein Perl-Programm ausführe, dann ist doch nach dem
erstenmal wenn ich an Browserwas zurück gesendet hab und den HTML-
Tag schließe aus und vorbei und ich kann selbst wenn das Perl-
Programm noch laufen sollte nicht mehr an den Browser schicken bzw.
er reagiert nicht mehr drauf oder blick ich da was nicht ?!?
Du blickst es durchaus. ;-)
Also mußt Du entweder einzelne HTTP-Requests mit refresh aneinander
ketten, oder bei server push das entsprechende Multipart-Paket senden.
Allerdings habe ich noch nie hingekriegt, daß bei Server Push alle
Zwischenzustände mit der gewünschten zeitlichen Verzögerung darge-
stellt werden - ich kriege immer nur den Endzustand (obwohl bei
"view-source" der HTML-Code _aller_ Zustände angezeigt wird).
Irgendwer scheint da etwas zu puffern, und das macht den Effekt kaputt.
Falls also jemand Server Push irgendwo produktiv laufen hat, würde
ich mir das gerne mal im Detail ansehen wollen ...
Wäre nett, wenn mir jemand helfen könnte und/oder vielleicht ein
kleines simples Beispiel mit posten könnte.
Server Push ist in der Literatur reichlich dokumentiert - da gibt
es in der CGI-Bibliothek von Perl explizit ein Beispiel.
<meta refresh> findest Du in SELFHTML.
Viele Grüße
Michael