Surfer: Perl + Statusanzeige

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

  1. 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.

  2. 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

  3. 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

    • vorausgesetzt, auf dem Server passiert etwas, das es überhaupt
      lohnenswert macht, einen solchen Status zu berechnen.
      Ich habe das in ein Produkt unserer Firma eingebaut - im oberen
      Frame "passiert" etwas, im unteren werden via refresh Statusmel-
      dungen eingeblendet. Am Ende stehen im oberen Frame die Ergebnisse
      und im unteren nichts mehr.

    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

    • und _das_ dauert Minuten, da lohnt sich das "Zusehen".)

    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