Sören: flush in perl

Hallo zusammen!

Ich versuche seit einer Ewigkeit einen Webchat auf die Beine zu stellen, doch es will nicht gelingen. Es scheitert daran, dass der Browser die Chatausgabe erst beim Beenden der Verbindung (also nach komplettem Laden der Seite) anzeigt.
Ich habe mittlerweile schon herausgefunden, dass man sich hierbei mit "flush()" Abhilfe schaffen kann. Das funktioniert bei mir aber leider auch nicht ohne weiteres. Ich bekomme zwar nun den Anfang des Chatouts mit Channelangabe und Anwesenden Usern, aber danach werden keine neuen Daten mehr angezeigt. Statt dessen wird beim Empfang weiterer Daten die Verbindung beendet.
Es scheint, als würde der zweite "flush()" Befehl das ganze zum Kippen bringen. Wenn einer ne Idee hat, wäre ich sehr dankbar.

Hier ein Auszug des Skripts:
---------------------------------------------------------------------
print $cgi->header(-type => 'text/html');

chatout abfragen (Schleife)

$req = $ua->get($chatout, ':content_cb' => &callback, ':read_size_hint' => 4096);

sub callback
{
 my($data, $response, $protocol) = @_;
 print $data;
 my $stdout = select(STDOUT);
 flush($stdout);
}
---------------------------------------------------------------------

MfG, Sören

  1. Hallo Sören,

    Ich versuche seit einer Ewigkeit einen Webchat auf die Beine zu
    stellen, doch es will nicht gelingen.

    Kleiner Tip: lass es bleiben. Es gibt Java-Applets für IRC-Chats, das
    ist viel sinnvoller.

    Wie auch immer. Der Code, den du gepostet hast, ist nicht im geringsten
    verständlich. Du wirst schon ausführlicher und genauer werden müssen.

    Grüße,
     CK

    --
    "Ich muss auflegen, mein Essen ist gleich fertig."
    "Oh, was gibt 's denn?"
    "Hmm. Die Packung liegt schon im Muell, keine Ahnung.
    1. Hallo...

      klar, ich hätte dabei schreiben können, dass
      "$req = $ua->get($chatout, ':content_cb' => &callback, ':read_size_hint' => 4096);"
      das Auslesen des Chatouts ist. Aber darauf könnte man eigentlich auch von alleine kommen, wenn man Perl und LWP kennt. Nunja, die Ausgabe wird zumindest in 4096-Byte Blöcken an die Prozedur "Callback" geschickt. Und beim zweiten Ausführen von Callback, wird die Verbindung getrennt.
      Was Callback macht muss ich ja nicht unbedingt noch erläutern, oder??

      MfG

      1. Hallo Sören,

        [...]

        Du musst mir nicht deinen komischen Code erklären, sondern lieber
        mal, was deine Konstruktion ist.

        Grüße,
         CK

        --
        Sein oder nicht sein, das ist hier die Frage!
      2. Halihallo Sören

        klar, ich hätte dabei schreiben können, dass
        "$req = $ua->get($chatout, ':content_cb' => &callback, ':read_size_hint' => 4096);"
        das Auslesen des Chatouts ist.

        Hast du ja, zumindest in verworrener Art und Weise. Wo hier eine
        Schleife stehen soll ist mir gänzlich unklar...

        Aber darauf könnte man eigentlich auch von alleine kommen, wenn man Perl und LWP kennt.

        Nicht wirklich. Aus Deinem Quelltext und dem Subject kann man zwar
        entnehmen, dass du irgendwas mit Perl programmierst, aber die
        Verwendung von LWP lässt sich daraus keineswegs ableiten.
        Ich sehe nirgens ein 'use LWP', nirgens ein 'use LWP::UserAgent',
        und schon gar nicht, weiss ich was sich hinter $chatout versteckt.
        Schreibe _vollständigen_ Code. Vollständig heisst in diesem
        Zusammenhang aber auch nicht 'ganzer Code', sondern eben nur
        vollständig.

        Nunja, die Ausgabe wird zumindest in 4096-Byte Blöcken an die Prozedur "Callback" geschickt. Und beim zweiten Ausführen von Callback, wird die Verbindung getrennt.

        Wird sie nicht. Sie wird vom Server getrennt.

        Was Callback macht muss ich ja nicht unbedingt noch erläutern, oder??

        Musst du nicht, besonders nicht zu Christian :-)

        Du musst dich klarer ausdrücken und nicht auf Glaskugeln hoffen, denn
        diese stehen hier nicht zur Verfügung.

        Viele Grüsse

        Philipp

        1. Tach...

          Ich entschuldige mich vielmals euch mit meinem Problem belästigt zu haben. Ich danke euch beiden für den tollen Tipp bezüglich IRC, aber wenn IRC für mich in Frage käme, würde ich mir kaum so eine Mühe machen.
          Was das scheitern des Projektes angeht... Naja, es gibt Webchats. Und oh Wunder, die funktionieren sogar. Da müssen die wohl gezaubert haben, um das zu realisieren.

          Im Grunde kann man das gesamte Geplänkel vergessen. Es geht lediglich um eine Prozedur, die kontinuierlich ausgeführt wird und dir ihr übermittelten Daten (und es ist scheissegal woher die Daten kommen) an den Browser schicken soll. Leider funzt flush() nur beim ersten Ausführen der Prozedur und keiner weiss warum. Ihr ja leider auch nicht, sonst hättet ihr euch euer Gefasel sparen können.

          In diesem Sinne... danke für nichts.

  2. Halihallo Sören

    Ich versuche seit einer Ewigkeit einen Webchat auf die Beine zu stellen, doch es will nicht gelingen.

    Der Code unten lässt anderes vermuten. Du saugst ihn irgendwo ab...

    Es scheitert daran, dass der Browser die Chatausgabe erst beim Beenden der Verbindung (also nach komplettem Laden der Seite) anzeigt.

    Tja, das Problem ist nicht (korrekt) lösbar. flush() flushed nur
    die Verbindung zwischen CGI-Script und Webserver. Das Puffern der
    Ausgabe zwischen Webserver und HTTP-Client oder Proxi, oder was
    auch immer noch dazuwischen steht, kannst du nicht beeinflussen.
    Genausowenig wie das rendering eines HTML-fähiger Browser am anderen
    Ende der Leitung.

    Verwende, wie schon vorgeschlagen, das IRC-Protokoll, denn dieses ist
    für Chats ausgelegt, nicht HTTP (was ich jetzt mal glaskuglerisch
    annehme).

    Ich habe mittlerweile schon herausgefunden, dass man sich hierbei mit "flush()" Abhilfe schaffen kann. Das funktioniert bei mir aber leider auch nicht ohne weiteres. Ich bekomme zwar nun den Anfang des Chatouts mit Channelangabe und Anwesenden Usern, aber danach werden keine neuen Daten mehr angezeigt. Statt dessen wird beim Empfang weiterer Daten die Verbindung beendet.

    Tja...

    Es scheint, als würde der zweite "flush()" Befehl das ganze zum Kippen bringen. Wenn einer ne Idee hat, wäre ich sehr dankbar.

    Nicht wirklich. Das ganze Konzept ist zum Kippen verdammt.

    sub callback
    {
     my($data, $response, $protocol) = @_;
     print $data;
     my $stdout = select(STDOUT);
     flush($stdout);
    }

    Warum in jedem Callback-Zykel die Standardausgabe selektieren und
    flushen? - Verwende dies einmal ganz am Anfang und setze den
    autoflush auf den Handle.

    Viele Grüsse

    Philipp