mod_perl - client stopped connection before rflush completed

Alles, was Perl betrifft, kann hier besprochen werden.

mod_perl - client stopped connection before rflush completed

Postby subhuman » 01. August 2003 13:22

hi ihrz,

schön, mal ne deutsch sprachige liste gefunden zu haben, da muss ich mir keinen abbrechen mit der formulierung. ;)

so, es geht um folgendes, vielleicht ist jemandem von euch das prob schon mal begegnet und kann mir einen tipp geben.

umgebung: debian-linux, kernel 2.4.18, apache 1.3 27, mod_perl 1.27, intel-celeron 500, 384MB RAM

aufgabe: ich schreibe an einem html-chat, der eigentlich ganz gut funktioniert bisher, jedenfalls soweit er bisher besteht und in opera 7.11b2, aber als ich ihn mit mozilla 1.3 ausprobieren wollte, gab's folgendes problem:

ääh, by the way: wenn ihr es antesten wollt: es gibt einen testuser namens testuser mit dem passwort testuser. der offene chat befindet sich in der kategorie "subway", das passwort zum chat heißt "achnichdoch"...

also: der chat wird dargestellt in einem frameset im frameset, bestehend aus 3 frames: chat_main, chat_users und chat_input - quite easy so far. wohl, weil mein rechner so lahm ist, kriegt mozilla den chat_users frame nicht geladen. ein klick mit der rechten maustaste und "frame reload" bringt zwar dann (mitunter) alle frames auf den monitor, aber _exakt_ 3 sekunden später gibt's im error-log die message: "client stopped connection before rwrite completed". auch deren entstehung ist einleuchtend: ein "reload" ist nix anderes als "stop - load", ist ja klar. anschließend aber sind alle daten, die ich im ChatHandler vorrätig halte, perdu. and there's the prob.

zur erklärung (don't worry about the .plsp extension - it's just a name):

httpd.conf enthält die zeilen:

<FilesMatch "chat_main\.plsp$">
SetHandler perl-script
PerlHandler Forum::ChatHandler
</FilesMatch>

der ChatHandler arbeitet selbstverstüändlich mit einer prinzipiell endlosen while() schleife, denn er muss den client zeilenweise füttern:

package Forum::ChatHandler;
use strict;

sub handler {
my $r = shift;
$| = 1;

[... snip... ]

my $session = # egal, es gibt eine session, die session enthält einen user
my $chat = # auch egal, es gibt einen chat.

[ ... snip ...]

my @msgs = $chat->get_filtered_messages($session->user->usr_id); # should be clear
my @nmsgs;
while () {
# reload the session, it may have been modified
[ ... snip ... ]

if (ref($session) ne 'Forum::Core::Session' || $session->user->anonymus
|| !$session->user->online
|| $r->connection->aborted) {
[ ... snip ... ]
Apache::exit(DONE);
}

@nmsgs = $chat->get_filtered_messages($session->user->usr_id);
if (@nmsgs > @msgs) {
for (my $i = @msgs; $i < @nmsgs; $i++) {
$msg = $nmsgs[$i];
next if $msg->time < $b->{'chat'}->get_user($usr_id)->{'uch_msgtime'}; # ***
}
else {
sleep 1
[ ... snip ... ]
}
}
OK;
}

und im error_log steht, und zwar ausgelöst durch die mit *** markierte zeile: can't use string ("0") as hash reference while strict refs in use. !!!!

das liest sich ein bisschen wirr vielleicht, drum vielleicht zur ergänzung einer zeile aus Forum::Content::Leaf::Chat.pm:
sub get_user { shift->{USERS}->{shift()} || 0 }

d.h.; der client bricht die connection ab. $r->connection->aborted ist dennoch (seltsamerweise) nicht wahr. wir geraten in die "for"-schleife, und in der gibt das chat-objekt, dass kurz zuvor noch alle daten (also auch den user präsent hatte, eine "0" zurück, wenn es nach dem user sucht.

ain't that strange?

hat irgend jemand eine idee, ob das an apache liegt? oder wo zur hölle ich den fehler gemacht haben _könnte_? ich würd mich über jede antwort freuen.

so long
sub
subhuman
 
Posts: 2
Joined: 01. August 2003 12:43
Location: berlin

p.s.

Postby subhuman » 01. August 2003 13:24

vielleicht sollte ich's noch erwähnen: http://dsl-217-9-56-246.berlikomm.net
subhuman
 
Posts: 2
Joined: 01. August 2003 12:43
Location: berlin

Postby Oswald » 04. August 2003 10:40

Huhu subhuman!

Wow, endlich mal ein wirklich richtiges Problem. Leider kenn ich mich überhaupt nicht mit Perl aus und kann da nicht wirklich helfen.

Allerdings erinnere ich mich an ein ähnliches Problem, dass ich mal hatte. IE (also Windows) greift auf Linux-Webserver zu. Reload sorgt nicht dafür das eine TCP-Verbindung wirklich abgebrochen wird, sondern unbenutzt weiterbesteht und dann irgendwann vom Timeout beendet wird.

Der Windows-Recher hat nicht zum Beenden der Verbindung ein FIN geschickt, sondern ein RST. Das ist eine sehr, sehr freie (und eigentlich auch falsche) Interpretation von TCP und so versteht Linux nicht, dass die Verbindung nun beendet sein soll. Die Verbindung liegt da und erst nach dem Timeout kriegt die Linux-Seite das "Signal", dass die Verbindung nun geschlossen wurde.

Vielleicht ist es bei Dir was ähnliches. Da Du auch so eine kleine Verzögerung drin hast. Allerdings sollte der TCP-Timeout höher 3 Sekunden sein. Aber das kann schliesslich auch an so vielen Stellen eingestellt werden. Wer weiß, vielleicht ist der Wert bei Dir halt so.

Vielleicht ist es aber auch ganz was anderes...

Ich sagte ja: Endlich mal ein wirklich richtiges Problem. :)

Viel Erfolg und liebe Grüße,
Oswald
User avatar
Oswald
Apache Friends
 
Posts: 2718
Joined: 26. December 2002 19:51
Location: Berlin, Germany
Operating System: Linux


Return to Perl

Who is online

Users browsing this forum: No registered users and 2 guests