fork/non blocking HTTP::Daemon



Hallo Newsgroup


Ich probiere im Moment einen eigenen kleinen HTTP-Daemon zu
prgrammieren.
Als Grundlage habe ich mir die Klasse HTTP::Daemon ausgesucht. Er soll
später unter Linux und Windows laufen. Im Moment wird er unter Windows
programmiert. Er soll später unter fest definierten URLs bestimmt
Aktionen ausführen (Mail, Image, FTP, Datnsicherung, etc).

Alle einzelnen Anfragen funktionieren einwandfrei. Da dieser Server
jedoch auch länger an manchen Requests zu rechnen haben wird, ist es
notwendig das er den Socket(!?) nicht blockiert. Er soll in der
Rechenzeit weiterhin ansprechbar sein.

Ist aber gestartet. Ich muss zugeben das mit fork auch noch nicht ganz
verstanden zu haben.
fork erzeugt doch ein 100% gleiches Abbild vom Perl-Interpreter. Aber
wie läuft das dann mit den offenen Sockets und so weiter.
Vielleicht kann mir da jemand noch ein paar Hintergrundinformationen
geben.

Ich habe hier ein lauffähiges Testskript welches als
Single-Request-Server einwandfrei funktioniert.
Wenn ich jedoch die fork-Anweisunge auskommentiere, nimmt er keine
Requests mehr an. Er reagiert gar nicht mehr.
Ich habe gelesen das die threads unter perl und windows noch nicht
ausgereift sind. Ist die fork Lösung gut für diesen Einsatz? Gibt es
bessere Lösungen?
Über code-Beispiele wäre ich sehr dankbar.

Aber/Und...


Ich bin für jede Hilfe dankbar.



Gruß Robert


Anbei die Listings.

###############################################################################
service.pl
###############################################################################
use strict;
use warnings;

use FindBin;
use CGI;
use CGI::Log;
use HTTP::Daemon;
use HTTP::Status;
use HTTP::Response;


use lib $FindBin::Bin.'/objects';

use Server;



my $init = {
port => "90",
localaddr => "127.0.0.1",
serverprotocol => "tcp",
htdocs => $FindBin::Bin."/htdocs/",
logdir => $FindBin::Bin."/logs/",
};



my $service = Server->new($init);
if($service){
### Bind the standart callbacks
$service->bind();

$service->start();
}


print "finish process\n";





###############################################################################
Server.pm
###############################################################################
package Server;
use strict;
use warnings;


sub new {

my $class = shift;
my $init = shift;
my $self = {};

bless($self,$class);



$self->{"RUNNING_INSTANCE"} = undef;
$self->configure($init);



my @keys = keys(%{$self->{"PUBLIC_CONFIG"}});

if($self->{"PUBLIC_CONFIG"}->{"LocalPort"}){
my $serverinstanz = HTTP::Daemon->new(
LocalPort => 90, LocalAddr => "127.0.0.1", Proto => "tcp"
);

if($serverinstanz){
$self->{"RUNNING_INSTANCE"} = $serverinstanz;
return $self;
}

}
}



sub bind {
my $self = shift;
print "testbind\n";
}


sub start {
my $self = shift;


$SIG{PIPE} = 'IGNORE';
# Reaper für terminierte Kindprozesse
#$SIG{CHLD} = sub { wait(); };


print $self->{"RUNNING_INSTANCE"}->url."\n";

if($self->{"RUNNING_INSTANCE"}){

while(my $client = $self->{"RUNNING_INSTANCE"}->accept){

# next if $pid;
# fork();

# # Kind bearbeitet Requests der Verbindung
while(my $request = $client->get_request){
### Process Request

#sleep(50);



my $response = HTTP::Response->new();
$response->code(200);
$response->message("OK");
$response->header("Content-Type" => "text/html");
$response->header("Pragma" => "no-cache");
$response->content("test\n<br><b>".$request->url->path."</b>");
$client->send_response($response);




$client->close();
print "connection closed\n";
}
}
}else{
print "server not started\n";
}

}


sub shutdown {

}



sub restart {

}



sub configure {

my $self = shift;
my $init = shift;


my $public = {
localaddr => "LocalAddr",
port => "LocalPort",
serverprotocol => "Proto",
};


my $privat = {};


if(ref($init) eq "HASH"){

my @configParam = keys(%{$init});
for(my $c=0;$c<scalar(@configParam);$c++){

if($public->{$configParam[$c]}){
$self->{"PUBLIC_CONFIG"}->{ $public->{$configParam[$c]}} =
$init->{$configParam[$c]};
}else{
$self->{"PRIVAT_CONFIG"}->{$configParam[$c]} =
$init->{$configParam[$c]};
}
}
return 1;
}else{
return undef;
}

}




1;

.